parse_ulog.pl 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #!/usr/bin/perl
  2. #
  3. # Copyright (C) Roman Dmitiriev, rnd@rajven.ru
  4. #
  5. #-A FORWARD -j ULOG --ulog-prefix "FORWARD" --ulog-cprange 48 --ulog-qthreshold 50
  6. #-A FORWARD -j USERS
  7. use FindBin '$Bin';
  8. use lib "$Bin/";
  9. use strict;
  10. use DBI;
  11. use Time::Local;
  12. use Net::Patricia;
  13. use Data::Dumper;
  14. use Date::Parse;
  15. use Socket;
  16. use Rstat::config;
  17. use Rstat::main;
  18. use Rstat::net_utils;
  19. use Rstat::mysql;
  20. setpriority(0,0,19);
  21. my $router_id;
  22. my %fields=('device_name'=>'1', 'id'=>'1');
  23. my $gate = get_record($dbh,'devices',\%fields,"deleted=0 and internet_gateway=1 and vendor_id=19 and device_name='".$HOSTNAME."'");
  24. if (!$gate) { exit 0; }
  25. my $router_name=$gate->{device_name};
  26. $router_id = $gate->{id};
  27. db_log_debug($dbh,"Import traffic from router id: $router_id start") if ($debug);
  28. # net objects
  29. my $users = new Net::Patricia;
  30. InitSubnets();
  31. my $dbt = init_traf_db();
  32. #get userid list
  33. my $user_auth_list = $dbh->prepare( "SELECT id,ip,user_id,save_traf FROM User_auth where deleted=0 ORDER by user_id,ip" );
  34. if ( !defined $user_auth_list ) { die "Cannot prepare statement: $DBI::errstr\n"; }
  35. $user_auth_list->execute;
  36. # user auth list
  37. my $authlist_ref = $user_auth_list->fetchall_arrayref();
  38. $user_auth_list->finish();
  39. my %user_stats;
  40. print "\nUser auth ip:\n" if ($debug);
  41. foreach my $row (@$authlist_ref) {
  42. $users->add_string($row->[1],$row->[0]);
  43. print "ip: $row->[1] auth_id: $row->[0]\n" if ($debug);
  44. $user_stats{$row->[0]}{net}=$row->[1];
  45. $user_stats{$row->[0]}{id}=$row->[0];
  46. $user_stats{$row->[0]}{user_id}=$row->[2];
  47. $user_stats{$row->[0]}{save_traf}=$row->[3];
  48. $user_stats{$row->[0]}{in}=0;
  49. $user_stats{$row->[0]}{out}=0;
  50. }
  51. my $last_time = localtime();
  52. my $time_string;
  53. my $dbtime;
  54. my $hour_date;
  55. my $minute_date;
  56. my @batch_sql_traf=();
  57. open(FH,"-");
  58. while (my $line=<FH>) {
  59. #1555573194.980;17 ; 77.243.0.12; 172.20.178.71; 53; 43432; 1; 134; 2; 1
  60. $line=~s/\s+//g;
  61. my ($l_time,$l_proto,$l_src_ip,$l_src_port,$l_dst_ip,$l_dst_port,$l_packets,$l_bytes,$l_input,$l_output,$l_prefix) = split(/ /,$line);
  62. next if (!$l_time);
  63. next if ($l_src_ip eq '0.0.0.0');
  64. next if ($l_dst_ip eq '0.0.0.0');
  65. next if ($l_src_ip eq '255.255.255.255');
  66. next if ($l_dst_ip eq '255.255.255.255');
  67. next if ($l_prefix !~ /FORWARD/i);
  68. next if ($Special_Nets->match_string($l_src_ip) or $Special_Nets->match_string($l_dst_ip));
  69. #unknown networks
  70. if (!$office_networks->match_string($l_src_ip) and !$office_networks->match_string($l_dst_ip)) {
  71. print "Unknown packet! src: $l_src_ip dst: $l_dst_ip \n";
  72. next;
  73. }
  74. #local forward
  75. if ($office_networks->match_string($l_src_ip) and $office_networks->match_string($l_dst_ip)) { next; }
  76. #free forward
  77. if ($office_networks->match_string($l_src_ip) and $free_networks->match_string($l_dst_ip)) { next; }
  78. if ($free_networks->match_string($l_src_ip) and $office_networks->match_string($l_dst_ip)) { next; }
  79. print "Flow: $line\n" if ($debug);
  80. my $l_src_ip_aton=StrToIp($l_src_ip);
  81. my $l_dst_ip_aton=StrToIp($l_dst_ip);
  82. if ($l_time ne $l_time+0) { $l_time=time-600; }
  83. $last_time = $l_time;
  84. my ($sec,$min,$hour,$day,$month,$year,$zone) = (localtime($l_time))[0,1,2,3,4,5];
  85. $month++;
  86. $year += 1900;
  87. $time_string = sprintf "%04d-%02d-%02d %02d:%02d:%02d",$year,$month,$day,$hour,$min,$sec;
  88. $dbtime = $dbh->quote($time_string);
  89. $hour_date = $dbh->quote(sprintf "%04d-%02d-%02d %02d:00:00",$year,$month,$day,$hour);
  90. $minute_date = $dbh->quote(sprintf "%04d-%02d-%02d %02d:%02d:00",$year,$month,$day,$hour,$min);
  91. my $user_found = 0;
  92. # find user id
  93. if ($office_networks->match_string($l_src_ip)) {
  94. my $out_user = $users->match_string($l_src_ip);
  95. if ($out_user) {
  96. $user_stats{$out_user}{out} += $l_bytes;
  97. $user_stats{$out_user}{dbtime} = $minute_date;
  98. $user_stats{$out_user}{htime} = $hour_date;
  99. print "OUT: $out_user + $l_bytes sum: $user_stats{$out_user}{out}\n" if ($debug);
  100. $user_found = 1;
  101. if ($save_detail and $user_stats{$out_user}{save_traf}) {
  102. my $dSQL="INSERT INTO Traffic_detail (auth_id,router_id,timestamp,proto,src_ip,dst_ip,src_port,dst_port,bytes) VALUES($out_user,$router_id,$dbtime,'$l_proto',$l_src_ip_aton,$l_dst_ip_aton,'$l_src_port','$l_dst_port','$l_bytes')";
  103. push (@batch_sql_traf,$dSQL);
  104. }
  105. }
  106. }
  107. if ($office_networks->match_string($l_dst_ip)) {
  108. my $in_user = $users->match_string($l_dst_ip);
  109. if ($in_user) {
  110. $user_stats{$in_user}{in} += $l_bytes;
  111. $user_stats{$in_user}{dbtime} = $minute_date;
  112. $user_stats{$in_user}{htime} = $hour_date;
  113. print "IN: $in_user + $l_bytes sum: $user_stats{$in_user}{in}\n" if ($debug);
  114. $user_found = 1;
  115. if ($save_detail and $user_stats{$in_user}{save_traf}) {
  116. my $dSQL="INSERT INTO Traffic_detail (auth_id,router_id,timestamp,proto,src_ip,dst_ip,src_port,dst_port,bytes) VALUES($in_user,$router_id,$dbtime,'$l_proto',$l_src_ip_aton,$l_dst_ip_aton,'$l_src_port','$l_dst_port','$l_bytes')";
  117. push (@batch_sql_traf,$dSQL);
  118. }
  119. }
  120. }
  121. next if ($users->match_string($l_src_ip) or $users->match_string($l_dst_ip));
  122. next if (!$add_unknown_user);
  123. # find user ip
  124. my $user_ip;
  125. my $user_ip_aton;
  126. undef $user_ip;
  127. #add user by src ip only if dst not office network!!!!
  128. if (!$office_networks->match_string($l_dst_ip) and $office_networks->match_string($l_src_ip)) { $user_ip = $l_src_ip; }
  129. #skip unknown packet
  130. if (!$user_ip) { next; }
  131. $user_ip_aton=StrToIp($user_ip);
  132. db_log_warning($dbh,"New ip $user_ip added by netflow!");
  133. #default user
  134. my $new_user_id=get_new_user_id($dbh,$user_ip);
  135. my $insert_auth;
  136. $insert_auth->{ip}=$user_ip;
  137. $insert_auth->{ip_int}=$user_ip_aton;
  138. $insert_auth->{ip_int_end}=$user_ip_aton;
  139. $insert_auth->{user_id}=$new_user_id;
  140. $insert_auth->{enabled}="0";
  141. $insert_auth->{deleted}="0";
  142. $insert_auth->{save_traf}="$save_detail";
  143. insert_record($dbh,'User_auth',$insert_auth);
  144. my $sSQL="SELECT id,ip,user_id FROM User_auth where ip_int=\"$user_ip_aton\" and deleted=0";
  145. my $get_user_auth = $dbh->prepare($sSQL);
  146. if ( !defined $get_user_auth ) { die "Cannot prepare statement: $DBI::errstr\n"; }
  147. $get_user_auth->execute;
  148. # user auth list
  149. my $new_user = $get_user_auth->fetchall_arrayref();
  150. $get_user_auth->finish();
  151. my $auth_id;
  152. foreach my $row (@$new_user) {
  153. next if (!$row->[0]);
  154. $auth_id = $row->[0];
  155. $users->add_string($user_ip,$auth_id);
  156. $user_stats{$auth_id}{net}=$user_ip;
  157. $user_stats{$auth_id}{user_id}=$row->[2];
  158. $user_stats{$auth_id}{id}=$auth_id;
  159. $user_stats{$auth_id}{in}=0;
  160. $user_stats{$auth_id}{out}=0;
  161. db_log_info($dbh,"Added user_auth id: $auth_id ip: $user_ip user_id: $row->[2]");
  162. last;
  163. }
  164. print "ERROR add user_auth!\n" if (!$users->match_string($user_ip));
  165. if ($auth_id) {
  166. if ($save_detail) {
  167. my $dSQL="INSERT INTO Traffic_detail (auth_id,router_id,timestamp,proto,src_ip,dst_ip,src_port,dst_port,bytes) VALUES($auth_id,$router_id,$dbtime,'$l_proto',$l_src_ip_aton,$l_dst_ip_aton,'$l_src_port','$l_dst_port','$l_bytes')";
  168. push (@batch_sql_traf,$dSQL);
  169. }
  170. if ($l_src_ip eq $user_ip) {
  171. $user_stats{$auth_id}{out} += $l_bytes;
  172. }
  173. if ($l_dst_ip eq $user_ip) {
  174. $user_stats{$auth_id}{in} += $l_bytes;
  175. }
  176. $user_stats{$auth_id}{dbtime} = $minute_date;
  177. $user_stats{$auth_id}{htime} = $hour_date;
  178. } else {
  179. undef $user_ip;
  180. undef $user_ip_aton;
  181. }
  182. }
  183. my ($min,$hour,$day,$month,$year) = (localtime($last_time))[1,2,3,4,5];
  184. $month ++;
  185. $year += 1900;
  186. ######## user statistics
  187. print "Update traffic table...\n" if ($debug);
  188. # update database
  189. foreach my $row (keys %user_stats) {
  190. next if ($user_stats{$row}{in} + $user_stats{$row}{out} <= 0);
  191. # insert row
  192. my $statSQL="INSERT INTO User_traffic (timestamp,auth_id,router_id,byte_in,byte_out,byte_proxy) VALUES($user_stats{$row}{dbtime},$user_stats{$row}{id},$router_id,$user_stats{$row}{in},$user_stats{$row}{out},'0')";
  193. print "$statSQL\n" if ($debug);
  194. push (@batch_sql_traf,$statSQL);
  195. }
  196. ### hour stats
  197. print "Update hourly stats table...\n" if ($debug);
  198. # get current stats
  199. my $sql = "Select auth_id, SUM(byte_in),SUM(byte_out) from User_stats WHERE ((YEAR(timestamp)=$year) and (MONTH(timestamp)=$month) and (DAY(timestamp)=$day) and (HOUR(timestamp)=$hour) and router_id=$router_id) Group by auth_id order by auth_id";
  200. my $fth = $dbt->prepare($sql);
  201. $fth->execute;
  202. my $hour_stats=$fth->fetchall_arrayref();
  203. $fth->finish;
  204. # update database
  205. foreach my $row (keys %user_stats) {
  206. next if (!$user_stats{$row}{htime});
  207. my $found = 0;
  208. ### find current statistics
  209. foreach my $row2 (@$hour_stats) {
  210. my ($f_s,$f_id,$f_in,$f_out) = @$row2;
  211. if ($user_stats{$row}{id} eq $f_id) {
  212. $f_in += $user_stats{$row}{in};
  213. $f_out += $user_stats{$row}{out};
  214. $found = 1;
  215. my $ssql="UPDATE User_stats set byte_in='$f_in', byte_out='$f_out' WHERE (id=$f_s and router_id=$router_id)";
  216. my $res = $dbt->do($ssql);
  217. unless ($res) {
  218. my $dSQL="INSERT INTO User_stats (timestamp,auth_id,router_id,byte_in,byte_out) VALUES($user_stats{$row}{htime},'$user_stats{$row}{id}','$router_id','$f_in','$f_out')";
  219. push (@batch_sql_traf,$dSQL);
  220. }
  221. last;
  222. }
  223. }
  224. next if ($found);
  225. my $dSQL="INSERT INTO User_stats (timestamp,auth_id,router_id,byte_in,byte_out) VALUES($user_stats{$row}{htime},'$user_stats{$row}{id}','$router_id','$user_stats{$row}{in}','$user_stats{$row}{out}')";
  226. push (@batch_sql_traf,$dSQL);
  227. }
  228. $dbt->{AutoCommit} = 0;
  229. my $sth;
  230. foreach my $sSQL(@batch_sql_traf) {
  231. $sth = $dbt->prepare($sSQL);
  232. $sth->execute;
  233. }
  234. $sth->finish;
  235. $dbt->{AutoCommit} = 1;
  236. db_log_debug($dbh,"Import traffic from router id: $router_id stop") if ($debug);
  237. $dbt->disconnect;
  238. $dbh->disconnect;
  239. print "Done\n" if ($debug);
  240. exit 0;