Prechádzať zdrojové kódy

update isc dhcpd script for last version

root 2 rokov pred
rodič
commit
465081ddd4

+ 47 - 12
docs/addons/dhcpd.conf

@@ -24,27 +24,59 @@ use-host-decl-names off;
 
 ping-check false;
 
+log-facility local5;
+
 on commit {
     set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
     set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
     set ClientHostName = pick-first-value(option host-name,"undef");
-    execute("/opt/Eye/scripts/dhcp-hook.sh", "add", ClientIP, ClientMac, ClientHostName);
+    log (info, concat("add;", ClientIP,";", ClientMac, ";", ClientHostName,";",binary-to-ascii(10,8,"",suffix (option agent.circuit-id, 1)),";",binary-to-ascii(16,8,":",suffix(option agent.remote-id,6)),";;;"));
     }
 
 on release {
     set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
     set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
-    execute("/opt/Eye/scripts/dhcp-hook.sh", "del", ClientIP, ClientMac);
-    }
+    log (info, concat("del;", ClientIP,";", ClientMac, ";undef;;;;;;"));
+}
 
 on expiry {
     set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
     set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
-    execute("/opt/Eye/scripts/dhcp-hook.sh", "del", ClientIP, ClientMac);
-    }
+    log (info, concat("del;", ClientIP,";", ClientMac, ";undef;;;;;;"));
+}
 
 log (info, concat("DHCPDLOG - ",binary-to-ascii(10, 8, ".", leased-address)," - ",pick-first-value(option host-name,"undef")," - ",binary-to-ascii (16, 8, ":", substring(hardware, 1, 7))," - at switch - ",binary-to-ascii(16,8,":",suffix(option agent.remote-id,6))," - vlan - ",binary-to-ascii(10,16,"",substring(suffix(option agent.circuit-id,4),0,2))," - port - ",binary-to-ascii(10,8,"",suffix (option agent.circuit-id, 1))," - via - ",binary-to-ascii(10,8,".",packet (24,4))));
 
+if exists agent.remote-id and exists agent.circuit-id {
+  log(info,concat("DHCPCIRCUIT for lease of ",binary-to-ascii(10,8,".",leased-address),
+  " is connected to interface ",binary-to-ascii(10,8,"/",suffix(option agent.circuit-id,2)),
+  ", VLAN ",binary-to-ascii(10,16,"",substring(suffix(option agent.circuit-id,4),0,2)),
+  " on switch ",binary-to-ascii(16,8,":",suffix(option agent.remote-id,6))
+  ));
+  log(info,concat("DHCPOPT82 for lease of ",binary-to-ascii(10,8,".",leased-address),
+  " raw option-82 info is CID: ",binary-to-ascii(10,8,".",option agent.circuit-id),
+  " AID: ",binary-to-ascii(16,8,".",option agent.remote-id)
+  ));
+  } elsif exists agent.remote-id {
+      log(info,concat("DHCPAGENT for lease of ",binary-to-ascii(10,8,".",leased-address),
+      " on agent ",binary-to-ascii(16,8,":",substring(option agent.remote-id, 2, 6))
+    ));
+    } elsif exists agent.circuit-id {
+      log(info,concat("DHCPCIRCUITID on ",
+      suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,1,1))),2),":",
+      suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,2,1))),2),":",
+      suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,3,1))),2),":",
+      suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,4,1))),2),":",
+      suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,5,1))),2),":",
+      suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,6,1))),2),
+      " to ",binary-to-ascii(10,8,".",leased-address),
+      " via ",option agent.circuit-id
+    ));
+}
+
+option ms-classless-static-routes code 249 = array of unsigned integer 8;
+option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
+
 # WPAD definition
 option wpad code 252 = text;
 # Suppress WPAD activity - no cache, no DNS.
@@ -69,13 +101,16 @@ vendor-option-space MSFT;
 option MSFT.release-on-shutdown 1;
 }
 
-shared-network "company" {
+class "default" {
+    match if (binary-to-ascii (10, 16, "",   substring    ( option agent.circuit-id, 2, 2 ) ) = "99");
+}
 
-#office
-subnet 192.168.1.0 netmask 255.255.255.0 {
-    option routers 192.168.1.1;
-    authoritative;
-    include "/etc/dhcp/stat/192.168.1.0.conf";
-    }
+class "any" {
+    match if (not exists agent.circuit-id);
+}
 
+class "direct" {
+    match if (binary-to-ascii(10,8,".",packet (24,4)) = "0.0.0.0");
 }
+
+include "/etc/dhcp/eye.d/eye.conf";

+ 0 - 7
docs/dhcpd/dhcp-hook.sh

@@ -1,7 +0,0 @@
-#!/bin/bash
-
-time=$(date +%s)
-#TYPE;MAC;IP;HOSTNAME
-echo "$1;$3;$2;$4;${time}" >>/var/log/dhcp.log &
-
-exit

+ 52 - 27
docs/dhcpd/print-dhcpd.pl

@@ -18,6 +18,9 @@ use Rstat::mysql;
 use Rstat::net_utils;
 use File::Basename;
 use File::Path;
+use utf8;
+
+binmode(STDOUT,':utf8');
 
 setpriority(0,0,19);
 
@@ -41,7 +44,15 @@ my $subnet_name = $subnet->{subnet};
 $subnet_name=~s/\/\d+$//g;
 $dhcp_conf{$subnet_name}->{first_ip}=IpToStr($subnet->{dhcp_start});
 $dhcp_conf{$subnet_name}->{last_ip}=IpToStr($subnet->{dhcp_stop});
-if ($connected->match_string(IpToStr($subnet->{gateway}))) { $dhcp_conf{$subnet_name}->{relay_ip}='direct'; } else { $dhcp_conf{$subnet_name}->{relay_ip}=IpToStr($subnet->{gateway}); }
+$dhcp_conf{$subnet_name}->{relay_ip}=IpToStr($subnet->{gateway});
+my $dhcp=GetDhcpRange($subnet->{subnet});
+$dhcp_conf{$subnet_name}->{mask}=$dhcp->{mask};
+$dhcp_conf{$subnet_name}->{masklen}=$dhcp->{masklen};
+$dhcp_conf{$subnet_name}->{gateway}=IpToStr($subnet->{gateway});
+$dhcp_conf{$subnet_name}->{network}=$dhcp->{network};
+$dhcp_conf{$subnet_name}->{dhcp_lease_time}=$subnet->{dhcp_lease_time}*60;
+$dhcp_conf{$subnet_name}->{deny_unknown_clients} = $subnet->{static};
+if ($connected->match_string(IpToStr($subnet->{gateway}))) { $dhcp_conf{$subnet_name}->{relay_ip}='direct'; }
 }
 
 foreach my $zone (keys %dhcp_conf) {
@@ -52,55 +63,56 @@ for (my $i=$dhcp_conf{$zone}->{first_aton}; $i <= $dhcp_conf{$zone}->{last_aton}
     }
 }
 
-my $dir_name = "/etc/dhcp/stat";
+my $dir_name = "/etc/dhcp/eye.d";
 my $new_dir = $dir_name.".new";
 
 if (! -d "$dir_name" ) { mkpath($dir_name); }
 if (! -d "$new_dir" ) { mkpath($new_dir); }
 
 #get userid list
-my $sSQL="SELECT id,ip,ip_int,mac,comments FROM User_auth where dhcp=1 and deleted=0 and user_id<>$hotspot_user_id and user_id<>$default_user_id ORDER by ip_int";
+my $sSQL="SELECT id,ip,ip_int,mac,comments,dns_name FROM User_auth where dhcp=1 and deleted=0 and ou_id !=".$default_user_ou_id." and ou_id !=".$default_hotspot_ou_id." ORDER by ip_int";
 
 my @users = get_records_sql($dbh,$sSQL);
 
 foreach my $row (@users) {
+next if (!$row);
+
 next if (!$row);
 next if (!$dhcp_networks->match_string($row->{ip}));
+next if (!$row->{mac});
+next if (!$row->{ip});
 next if ($hotspot_networks->match_string($row->{ip}));
 my $info = $office_networks->match_string($row->{ip});
 next if (!$info);
-next if (!$row->{mac});
-next if (!$row->{ip});
-$info=~s/(\/\d+)$//;
-#push(@{$dhcp_conf{$info}},"host $row->{id} { hardware ethernet $row->{mac}; fixed-address $row->{ip}; }");
+my $zone_name = $info->{subnet};
+$zone_name=~s/(\/\d+)$//;
+#push(@{$dhcp_conf{$zone_name}},"host $row->{id} { hardware ethernet $row->{mac}; fixed-address $row->{ip}; }");
 
 my @u_mac_array;
 foreach my $octet (split(/:/,$row->{mac})){$octet=~s/0(\S:?)/$1/g;push(@u_mac_array,$octet);}
 my $u_mac=join(':',@u_mac_array);
 
-push(@{$dhcp_conf{$info}->{conf}},"# Data for $row->{id}");
-push(@{$dhcp_conf{$info}->{conf}},"class \"".$row->{id}."_fixed\" {");
-push(@{$dhcp_conf{$info}->{conf}},"match if (");
-push(@{$dhcp_conf{$info}->{conf}},"binary-to-ascii(16,8,\":\",substring(hardware,1,6))=\"".$u_mac.'"');
-if ($dhcp_conf{$info}->{relay_ip}!~/direct/i) {
-    push(@{$dhcp_conf{$info}->{conf}},"and binary-to-ascii(10,8,\".\",packet(24,4))=\"".$dhcp_conf{$info}->{relay_ip}.'"');
+push(@{$dhcp_conf{$zone_name}->{conf}},"# Data for $row->{id}");
+push(@{$dhcp_conf{$zone_name}->{conf}},"class \"".$row->{id}."_fixed\" {");
+push(@{$dhcp_conf{$zone_name}->{conf}},"match if (");
+push(@{$dhcp_conf{$zone_name}->{conf}},"binary-to-ascii(16,8,\":\",substring(hardware,1,6))=\"".$u_mac.'"');
+if ($dhcp_conf{$zone_name}->{relay_ip}!~/direct/i) {
+    push(@{$dhcp_conf{$zone_name}->{conf}},"and binary-to-ascii(10,8,\".\",packet(24,4))=\"".$dhcp_conf{$zone_name}->{relay_ip}.'"');
     }
-push(@{$dhcp_conf{$info}->{conf}},");");
-push(@{$dhcp_conf{$info}->{conf}},"}");
-push(@{$dhcp_conf{$info}->{conf}},"pool {");
-push(@{$dhcp_conf{$info}->{conf}},"range $row->{ip} $row->{ip};");
-push(@{$dhcp_conf{$info}->{conf}},"allow members of \"".$row->{id}."_fixed\";");
-push(@{$dhcp_conf{$info}->{conf}},"}");
-$dhcp_conf{$info}->{pool}->{$row->{ip_int}} = 1;
+push(@{$dhcp_conf{$zone_name}->{conf}},");");
+push(@{$dhcp_conf{$zone_name}->{conf}},"}");
+push(@{$dhcp_conf{$zone_name}->{conf}},"pool {");
+push(@{$dhcp_conf{$zone_name}->{conf}},"range $row->{ip} $row->{ip};");
+push(@{$dhcp_conf{$zone_name}->{conf}},"allow members of \"".$row->{id}."_fixed\";");
+push(@{$dhcp_conf{$zone_name}->{conf}},"}");
+$dhcp_conf{$zone_name}->{pool}->{$row->{ip_int}} = 1;
 }
 
 foreach my $zone (keys %dhcp_conf) {
-#    print "Analyze zone: $zone\n";
     my $start_pool = 0;
     for (my $i=$dhcp_conf{$zone}->{first_aton}; $i <= $dhcp_conf{$zone}->{last_aton}; $i++) {
 	if (($dhcp_conf{$zone}->{pool}->{$i} or $i==$dhcp_conf{$zone}->{last_aton}) and $start_pool) {
-		my $conf_str="range ".IpToStr($start_pool)." ".IpToStr($i-1).";";
-#		print "$conf_str\n";
+		my $conf_str="range dynamic-bootp ".IpToStr($start_pool)." ".IpToStr($i-1).";";
 		push(@{$dhcp_conf{$zone}->{conf}},$conf_str);
 		$start_pool = 0;
 		}
@@ -110,10 +122,23 @@ foreach my $zone (keys %dhcp_conf) {
 	}
 }
 
-foreach my $lease_file (keys %dhcp_conf) {
-my $full_zone_path=$new_dir."/".$lease_file.".conf";
-#my $full_zone_path=$dir_name."/".$lease_file.".conf";
-write_to_file($full_zone_path,$dhcp_conf{$lease_file}->{conf});
+write_to_file($new_dir."/eye.conf","#dynamic generated file");
+write_to_file($new_dir."/eye.conf",'shared-network "company" {',1);
+
+foreach my $zone (keys %dhcp_conf) {
+my $full_zone_path=$new_dir."/".$zone.".conf";
+write_to_file($full_zone_path,$dhcp_conf{$zone}->{conf});
+write_to_file($new_dir."/eye.conf",'subnet '.$dhcp_conf{$zone}->{network}.' netmask '.$dhcp_conf{$zone}->{mask}.' {',1);
+write_to_file($new_dir."/eye.conf","\toption routers ".$dhcp_conf{$zone}->{gateway}.';',1);
+write_to_file($new_dir."/eye.conf","\tmax-lease-time ".$dhcp_conf{$zone}->{dhcp_lease_time}.';',1);
+write_to_file($new_dir."/eye.conf","\tdefault-lease-time ".$dhcp_conf{$zone}->{dhcp_lease_time}.';',1);
+write_to_file($new_dir."/eye.conf","\tauthoritative;",1);
+write_to_file($new_dir."/eye.conf","\tallow duplicates;",1);
+write_to_file($new_dir."/eye.conf","\tuse-host-decl-names on;",1);
+write_to_file($new_dir."/eye.conf","\t".'include "'.$full_zone_path.'";',1);
+if ($dhcp_conf{$zone}->{deny_unknown_clients}) { write_to_file($new_dir."/eye.conf","\tdeny unknown-clients;",1); }
+write_to_file($new_dir."/eye.conf","\t}",1);
 }
+write_to_file($new_dir."/eye.conf",'}',1);
 
 exit 0;

+ 130 - 0
docs/dhcpd/print-dhcpd2.pl

@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+
+#
+# Copyright (C) Roman Dmitiriev, rnd@rajven.ru
+#
+
+use FindBin '$Bin';
+use lib "$Bin/";
+use strict;
+use DBI;
+use Time::Local;
+use Net::Patricia;
+use NetAddr::IP;
+use Data::Dumper;
+use Rstat::config;
+use Rstat::main;
+use Rstat::mysql;
+use Rstat::net_utils;
+use File::Basename;
+use File::Path;
+use utf8;
+
+binmode(STDOUT,':utf8');
+
+setpriority(0,0,19);
+
+my %dhcp_conf;
+
+my $connected = new Net::Patricia;
+my $dhcp_networks = new Net::Patricia;
+
+my $int_addr=do_exec('/sbin/ip addr show | grep "scope global"');
+foreach my $address (split(/\n/,$int_addr)) {
+if ($address=~/inet\s+(.*)\s+brd/i) {
+    if ($1) { $connected->add_string($1); }
+    }
+}
+
+my @subnets=get_records_sql($dbh,'SELECT * FROM subnets WHERE dhcp=1 and office=1 and vpn=0 and hotspot=0 ORDER BY ip_int_start');
+foreach my $subnet (@subnets) {
+next if (!$subnet->{gateway});
+$dhcp_networks->add_string($subnet->{subnet});
+my $subnet_name = $subnet->{subnet};
+$subnet_name=~s/\/\d+$//g;
+$dhcp_conf{$subnet_name}->{first_ip}=IpToStr($subnet->{dhcp_start});
+$dhcp_conf{$subnet_name}->{last_ip}=IpToStr($subnet->{dhcp_stop});
+$dhcp_conf{$subnet_name}->{relay_ip}=IpToStr($subnet->{gateway});
+my $dhcp=GetDhcpRange($subnet->{subnet});
+$dhcp_conf{$subnet_name}->{mask}=$dhcp->{mask};
+$dhcp_conf{$subnet_name}->{masklen}=$dhcp->{masklen};
+$dhcp_conf{$subnet_name}->{gateway}=IpToStr($subnet->{gateway});
+$dhcp_conf{$subnet_name}->{network}=$dhcp->{network};
+$dhcp_conf{$subnet_name}->{dhcp_lease_time}=$subnet->{dhcp_lease_time}*60;
+$dhcp_conf{$subnet_name}->{deny_unknown_clients} = $subnet->{static};
+if ($connected->match_string(IpToStr($subnet->{gateway}))) { $dhcp_conf{$subnet_name}->{relay_ip}='direct'; }
+}
+
+foreach my $zone (keys %dhcp_conf) {
+$dhcp_conf{$zone}->{first_aton} = StrToIp($dhcp_conf{$zone}->{first_ip});
+$dhcp_conf{$zone}->{last_aton} = StrToIp($dhcp_conf{$zone}->{last_ip});
+for (my $i=$dhcp_conf{$zone}->{first_aton}; $i <= $dhcp_conf{$zone}->{last_aton}; $i++) {
+    $dhcp_conf{$zone}->{pool}->{$i}=0;
+    }
+}
+
+my $dir_name = "/etc/dhcp/eye.d";
+my $new_dir = $dir_name.".new";
+
+if (! -d "$dir_name" ) { mkpath($dir_name); }
+if (! -d "$new_dir" ) { mkpath($new_dir); }
+
+#get userid list
+my $sSQL="SELECT id,ip,ip_int,mac,comments,dns_name FROM User_auth where dhcp=1 and deleted=0 and ou_id !=".$default_user_ou_id." and ou_id !=".$default_hotspot_ou_id." ORDER by ip_int";
+
+my @users = get_records_sql($dbh,$sSQL);
+
+foreach my $row (@users) {
+next if (!$row);
+
+next if (!$row);
+next if (!$dhcp_networks->match_string($row->{ip}));
+next if (!$row->{mac});
+next if (!$row->{ip});
+next if ($hotspot_networks->match_string($row->{ip}));
+my $info = $office_networks->match_string($row->{ip});
+next if (!$info);
+my $zone_name = $info->{subnet};
+$zone_name=~s/(\/\d+)$//;
+push(@{$dhcp_conf{$zone_name}->{conf}},"# Data for $row->{id} $row->{dns_name} $row->{comments}");
+if ($row->{dns_name}) {
+    push(@{$dhcp_conf{$zone_name}->{conf}},"host ".$row->{id}." { hardware ethernet ".$row->{mac}."; fixed-address ".$row->{ip}."; option host-name ".$row->{dns_name}."; }");
+    } else {
+    push(@{$dhcp_conf{$zone_name}->{conf}},"host ".$row->{id}." { hardware ethernet ".$row->{mac}."; fixed-address ".$row->{ip}."; }");
+    }
+$dhcp_conf{$zone_name}->{pool}->{$row->{ip_int}} = 1;
+}
+
+foreach my $zone (keys %dhcp_conf) {
+    my $start_pool = 0;
+    for (my $i=$dhcp_conf{$zone}->{first_aton}; $i <= $dhcp_conf{$zone}->{last_aton}; $i++) {
+	if (($dhcp_conf{$zone}->{pool}->{$i} or $i==$dhcp_conf{$zone}->{last_aton}) and $start_pool) {
+		my $conf_str="range dynamic-bootp ".IpToStr($start_pool)." ".IpToStr($i-1).";";
+		push(@{$dhcp_conf{$zone}->{conf}},$conf_str);
+		$start_pool = 0;
+		}
+	if (!$dhcp_conf{$zone}->{pool}->{$i} and !$start_pool) {
+		$start_pool = $i;
+		}
+	}
+}
+
+write_to_file($new_dir."/eye.conf","#dynamic generated file");
+write_to_file($new_dir."/eye.conf",'shared-network "company" {',1);
+
+foreach my $zone (keys %dhcp_conf) {
+my $full_zone_path=$new_dir."/".$zone.".conf";
+write_to_file($full_zone_path,$dhcp_conf{$zone}->{conf});
+write_to_file($new_dir."/eye.conf",'subnet '.$dhcp_conf{$zone}->{network}.' netmask '.$dhcp_conf{$zone}->{mask}.' {',1);
+write_to_file($new_dir."/eye.conf","\toption routers ".$dhcp_conf{$zone}->{gateway}.';',1);
+write_to_file($new_dir."/eye.conf","\tmax-lease-time ".$dhcp_conf{$zone}->{dhcp_lease_time}.';',1);
+write_to_file($new_dir."/eye.conf","\tdefault-lease-time ".$dhcp_conf{$zone}->{dhcp_lease_time}.';',1);
+write_to_file($new_dir."/eye.conf","\tauthoritative;",1);
+write_to_file($new_dir."/eye.conf","\tallow duplicates;",1);
+write_to_file($new_dir."/eye.conf","\t".'include "'.$full_zone_path.'";',1);
+if ($dhcp_conf{$zone}->{deny_unknown_clients}) { write_to_file($new_dir."/eye.conf","\tdeny unknown-clients;",1); }
+write_to_file($new_dir."/eye.conf","\t}",1);
+}
+write_to_file($new_dir."/eye.conf",'}',1);
+
+exit 0;

+ 8 - 4
docs/dhcpd/update-dhcpd

@@ -9,19 +9,23 @@ if [ ${ret} -ne 0 ]; then
     exit
     fi
 
-diff -aqbBfi /etc/dhcp/stat /etc/dhcp/stat.new >/dev/null
+diff -aqbBfi /etc/dhcp/eye.d /etc/dhcp/eye.d.new >/dev/null
 ret=$?
 
 if [ ${ret} -ne 0 ]; then
     logger -t dhcpd "Update dhcpd config"
-    rm -f /etc/dhcp/stat/*.conf >/dev/null 2>&1
-    cp -f /etc/dhcp/stat.new/*.conf /etc/dhcp/stat >/dev/null 2>&1
+    rm -f /etc/dhcp/eye.d/*.bak >/dev/null 2>&1
+    find /etc/dhcp/eye.d/ -iname "*.conf" -exec rename \.conf \.bak {} \;  >/dev/null 2>&1
+    cp -f /etc/dhcp/eye.d.new/*.conf /etc/dhcp/eye.d >/dev/null 2>&1
+    sed -i 's/\.new//' /etc/dhcp/eye.d/eye.conf >/dev/null 2>&1
     /sbin/dhcpd -t -cf /etc/dhcp/dhcpd.conf >/dev/null 2>&1
     ret=$?
     if [ ${ret} -eq 0 ]; then
-        systemctl restart dhcpd>/dev/null
+        systemctl restart isc-dhcp-server>/dev/null
 	else
         logger -t dhcpd "Config error! Skip restart dhcp."
+        rm -f /etc/dhcp/eye.d/*.conf >/dev/null 2>&1
+        find /etc/dhcp/eye.d/ -iname "*.bak" -exec rename .bak .conf {} \; >/dev/null 2>&1
 	fi
     else
     logger -t dhcpd "Config not changed. Skip restart"

+ 1 - 1
scripts/dhcp-log.pl

@@ -114,7 +114,7 @@ if (!$pid) {
             next if (!$type);
             next if ($type!~/(old|add|del)/i);
 
-            if (exists $leases{$ip} and $leases{$ip}{'type'} eq $type and time()-$leases{$ip}{last_time} <= $mute_time) { next; }
+            if (exists $leases{$ip} and $leases{$ip}{'type'} eq $type and time()-$leases{$ip}{'last_time'} <= $mute_time) { next; }
 
             if (time()-$last_refresh_config>=60) { init_option($hdb); }