Просмотр исходного кода

add support dns names in filters

rajven 3 лет назад
Родитель
Сommit
b547d92626
3 измененных файлов с 73 добавлено и 13 удалено
  1. 18 5
      scripts/Rstat/net_utils.pm
  2. 54 8
      scripts/sync_mikrotik.pl
  3. 1 0
      updates/20230429/mysql-migrate-path.sql

+ 18 - 5
scripts/Rstat/net_utils.pm

@@ -32,6 +32,7 @@ GetDhcpRange
 GetIpRange
 GetIP
 GetSubNet
+is_ip
 is_ipip_valid
 is_ip_valid
 print_net
@@ -60,13 +61,11 @@ sub ResolveNames {
 my $hostname = shift;
 my @result=();
 my $res = Net::DNS::Resolver->new;
-$res->nameservers($dns_server);
-my $query = $res->search($hostname);
+$res->nameservers($dns_server) if (!$dns_server);
+my $query = $res->search($hostname,"A");
 my $result;
 if ($query) {
-    foreach my $rr ($query->answer) {
-        if ($rr->type eq "A") { push(@result,$result = $rr->address); }
-	}
+    foreach my $rr ($query->answer) { push(@result,$result = $rr->address);	}
     }
 return (@result);
 }
@@ -231,6 +230,20 @@ return $ok;
 
 #---------------------------------------------------------------------------------------------------------
 
+sub is_ip {
+my $ip_str = trim($_[0]);
+if ($ip_str =~ /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})(\/[0-9]{1,2}){0,1}/) {
+        my $mask = $5;
+        return 0 if($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255);
+        $mask =~s/\/// if ($mask);
+        $mask = 32 if (!$mask);
+        return 0 if ($mask > 32);
+        return 1;
+        }
+return 0;
+}
+#---------------------------------------------------------------------------------------------------------
+
 sub is_ip_valid {
 my $ip_str = trim($_[0]);
 if ($ip_str =~ /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})(\/[0-9]{1,2}){0,1}/) {

+ 54 - 8
scripts/sync_mikrotik.pl

@@ -23,6 +23,7 @@ use Rstat::mysql;
 use DBI;
 use Fcntl qw(:flock);
 use Parallel::ForkManager;
+use Net::DNS;
 
 #$debug = 1;
 
@@ -363,24 +364,69 @@ log_debug("Queues status:".Dumper(\%queues));
 my @filterlist_ref = get_records_sql($dbh,"SELECT * FROM Filter_list where type=0");
 
 my %filters;
+my %dyn_filters;
+
+my $max_filter_rec = get_record_sql($dbh,"SELECT MAX(id) FROM Filter_list");
+my $max_filter_id = $max_filter_rec->{id};
+
+my $dyn_filters_base = $max_filter_id+1000;
+my $dyn_filters_index = $dyn_filters_base;
+
 foreach my $row (@filterlist_ref) {
-$filters{$row->{id}}->{id}=$row->{id};
-$filters{$row->{id}}->{proto}=$row->{proto};
-$filters{$row->{id}}->{dst}=$row->{dst};
-$filters{$row->{id}}->{dstport}=$row->{dstport};
-$filters{$row->{id}}->{srcport}=$row->{srcport};
-$filters{$row->{id}}->{action}=$row->{action};
+    #if dst - ip address
+    if (is_ip($row->{dst})) {
+        $filters{$row->{id}}->{id}=$row->{id};
+        $filters{$row->{id}}->{proto}=$row->{proto};
+        $filters{$row->{id}}->{dst}=$row->{dst};
+        $filters{$row->{id}}->{dstport}=$row->{dstport};
+        $filters{$row->{id}}->{srcport}=$row->{srcport};
+        $filters{$row->{id}}->{action}=$row->{action};
+        #set false for dns dst flag
+        $filters{$row->{id}}->{dns_dst}=0;
+        } else {
+        #if dst not ip - check dns record
+        my @dns_record=ResolveNames($row->{dst});
+        $resolved_ips = (scalar @dns_record>0);
+        next if (!$resolved_ips);
+        foreach my $resolved_ip (@dns_record) {
+                #enable dns dst filters
+                $filters{$row->{id}}->{dns_dst}=1;
+                #add dynamic dns filter
+                $filters{$dyn_filters_index}->{id}=$row->{id};
+                $filters{$dyn_filters_index}->{proto}=$row->{proto};
+                $filters{$dyn_filters_index}->{dst}=$resolved_ip;
+                $filters{$dyn_filters_index}->{dstport}=$row->{dstport};
+                $filters{$dyn_filters_index}->{srcport}=$row->{srcport};
+                $filters{$dyn_filters_index}->{action}=$row->{action};
+                $filters{$dyn_filters_index}->{dns_dst}=0;
+                #save new filter dns id for original filter id
+                push(@{$dyn_filter->{$row->{id}}},$dyn_filters_index);
+                $dyn_filters_index++;
+            }
+        }
 }
 
 log_debug("Filters status:". Dumper(\%filters));
+log_debug("DNS-filters status:". Dumper(\%dyn_filters));
 
 my @grouplist_ref = get_records_sql($dbh,"SELECT group_id,filter_id,Group_filters.order FROM Group_filters order by Group_filters.group_id,Group_filters.order");
 
 my %group_filters;
 my $index=1;
 foreach my $row (@grouplist_ref) {
-$group_filters{'group_'.$row->{group_id}}->{$index}=$row->{filter_id};
-$index++;
+    #if dst dns filter not found
+    if (!$filters{$row->{filter_id}}->{dns_dst}) {
+        $group_filters{'group_'.$row->{group_id}}->{$index}=$row->{filter_id};
+        $index++;
+    } else {
+        #if found dns dst filters - add
+        if (exists $dyn_filter->{$row->{filter_id}} and scalar @{$dyn_filter->{$row->{filter_id}}}>0) {
+            foreach my $dyn_filter (@{$dyn_filter->{$row->{filter_id}}}) {
+                $group_filters{'group_'.$row->{group_id}}->{$index}=$dyn_filter;
+                $index++; 
+            }
+        }
+    }
 }
 
 log_debug("Group filters: ".Dumper(\%group_filters));

+ 1 - 0
updates/20230429/mysql-migrate-path.sql

@@ -1,2 +1,3 @@
 UPDATE `config_options` SET `default_value` = REPLACE(`default_value`, '/usr/local/scripts/', '/opt/Eye/scripts/') WHERE `default_value` LIKE '%/usr/local/scripts/%';
 UPDATE `config` SET `value` = REPLACE(`value`, '/usr/local/scripts/', '/opt/Eye/scripts/') WHERE `value` LIKE '%/usr/local/scripts/%';
+ALTER TABLE `Filter_list` CHANGE `dst` `dst` VARCHAR(253) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL;