PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [iptables] DHCP-Requests blockieren



fork
30.03.06, 11:56
Hallo,

ich habe mir hier folgende kleine Aufgabe für mich: Ich möchte meine DHCP-Server im Netz betreiben und moechte nur Clients mit einer bestimmten MAC zulassen. Dazu hab' ich ein kleines iptables script das erst mal alle Anfragen via udp an port 67(bootps) blockiert. Doch das will nicht, zumindest nicht auf der Debian Kiste. Auf der susi laeuft das einwandfrei, auf dem Debian greifen die Regeln nicht.

Konfig SuSE:
Kernel 2.6.8-24.18-default / iptables 1.2.11

Konfig Debian:
Kernel 2.6.16-1-686 / iptables 1.3.3


Chain INPUT (policy ACCEPT 15090 packets, 10M bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT udp -- any any anywhere anywhere udp dpt:bootps reject-with icmp-port-unreachable
0 0 REJECT tcp -- any any anywhere anywhere tcp dpt:bootps reject-with icmp-port-unreachable
7 460 ACCEPT all -- any any anywhere anywhere

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 289K packets, 447M bytes)
pkts bytes target prot opt in out source destination

Irgendeine Idee woran das liegen koennte?

-----

Hintergrund:
Ich betreibe einen 2. DHCP-Server als Netzbootserver, der bei Bedarf Rettungs(Knoppix) und Installationssystem(FAI) bereitstellen soll. Über eine Web-oberflaeche sollen dann Nutzer MAC-Adressen eingeben sollen, die dann adhoc via iptables freigeschaltet werden.

Hier das cgi:

#!/usr/bin/perl

use CGI qw/:fatals_to_browser :standard :form *table/;
use strict;
use constant MAC_FILE => '/etc/dhcp3/mac-access/macs.txt';

print header;
print start_html('DHCP-Zugriffssteuerung fuer den Netzbootserver');
print start_form();
my $cgi=CGI->new();
my $self=$cgi->url();
my $error;
my $message;
my $action=0;

print "<h1>DHCP-Zugriffssteuerung fuer den Netzbootserver</h1>\n";
if (param()) {

if(param("mac")) {
my $mac=param("mac");
chomp($mac);
&convertmac(\$mac) or &error("$mac ist keine gueltige MAC-Adresse");
unless($error) {
if(&macneu($mac)) {
&info("MAC Adresse $mac hinzugefuegt");
&writemac($mac);
$action=1;
} else {
&error("MAC Adresse schon vorhanden");
}
}
}
if(param("DELETE_MAC")) {
my $mac=param("DELETE_MAC");
chomp($mac);
if(&macneu($mac)) {
&error("MAC: $mac existiert nicht in der Datei");
} else {
if(&deletemac($mac) ) {
&info("MAC: $mac wurde geloescht");
$action=1;
}
}
}

&showmacs();

&printmessage();

if($action) {
system("/usr/bin/sudo /usr/local/bin/fw-dhcp-blocker");
&info("Systemkonfiguration wurde geandert");
&printmessage();
}

} else {

&showmacs()
}
print end_form();
print end_html();
exit(0);

sub showmacs {
# MAC-Adressen aus Datei lesen
my @MACS=&getmacs();
$cgi->delete_all();

# MAC-Adressen anzeigen

print "<P>Neue MAC-Adresse: ".$cgi->textfield(-name=>"mac",-size=>40,).$cgi->submit(-value=>"Hinzufuegen")."</P>\n";

print "<font size=4><b>Freigeschaltete MAC-Adressen</b></font>";

print "<TABLE>\n";
for my $ADDR (@MACS) {
print "<TR><TD>$ADDR</TD><TD><A HREF=\"$self?DELETE_MAC=$ADDR\">loeschen</A></TD></TR>\n";
}
print "</TABLE>\n";
}

sub getmacs {
open(MACS,"<".MAC_FILE) or &error("Kann macs.txt nicht lesen: $!");
my @list;
while(<MACS>) {
chomp();
push(@list,$_);
}
close(MACS);
return(@list);
}

sub writemac {
my $mac=shift;
open(MACS,">>".MAC_FILE) or &error("Kann macs.txt nicht zum schreiben oeffnen: $!");
print MACS "$mac\n";
close(MACS);
}

sub writemacs {
my $macs=shift;
open(MACS,">".MAC_FILE) or &error("Kann macs.txt nicht zum schreiben oeffnen: $!");
for my $ADDR (@$macs) {
print MACS "$ADDR\n";
}
close(MACS);
}


sub macneu {
my $newmac=shift;
my @MACS=&getmacs();
for my $ADDR (@MACS) {
return(0) if($ADDR eq $newmac);
}
return(1);
}

sub deletemac {
my $mac=shift;
my @MACS=&getmacs();
my @NEWMACS;
my $ADDR;
for $ADDR ( @MACS ) {
if($ADDR ne $mac) {
push(@NEWMACS,$ADDR);
}
}
&writemacs(\@NEWMACS);
}

sub convertmac {
my $mac=shift;
if( $$mac =~ /^([0-9a-fA-F]{2}[:-]?){5}[0-9a-fA-F]{2}$/ ) {
$$mac =~ s/-/:/g;
$$mac =~ s/([a-f])/\U$1/g;
return(1);
}
return(0);
}

sub printmessage {
print "<p> </p>";
print $message;
}

#sub writemac {

sub error {
my $msg=shift;
$message="<font size=5 color=red>Fehler: $msg</font>\n";
$error=1;
# die($msg);
}

sub info {
my $msg=shift;
$message="<font size=5 color=green>$msg</font>\n";
$error=0;
# die($msg);
}

sub debug {
my $msg=shift;
print "<font size=5 color=orange>$msg</font>\n";
# die($msg);
}
#!/usr/bin/perl

use CGI qw/:fatals_to_browser :standard :form *table/;
use strict;
use constant MAC_FILE => '/etc/dhcp3/mac-access/macs.txt';

print header;
print start_html('DHCP-Zugriffssteuerung fuer den Netzbootserver');
print start_form();
my $cgi=CGI->new();
my $self=$cgi->url();
my $error;
my $message;
my $action=0;

print "<h1>DHCP-Zugriffssteuerung fuer den Netzbootserver</h1>\n";
if (param()) {

if(param("mac")) {
my $mac=param("mac");
chomp($mac);
&convertmac(\$mac) or &error("$mac ist keine gueltige MAC-Adresse");
unless($error) {
if(&macneu($mac)) {
&info("MAC Adresse $mac hinzugefuegt");
&writemac($mac);
$action=1;
} else {
&error("MAC Adresse schon vorhanden");
}
}
}
if(param("DELETE_MAC")) {
my $mac=param("DELETE_MAC");
chomp($mac);
if(&macneu($mac)) {
&error("MAC: $mac existiert nicht in der Datei");
} else {
if(&deletemac($mac) ) {
&info("MAC: $mac wurde geloescht");
$action=1;
}
}
}

&showmacs();

&printmessage();

if($action) {
system("/usr/bin/sudo /usr/local/bin/fw-dhcp-blocker");
&info("Systemkonfiguration wurde geandert");
&printmessage();
}

} else {

&showmacs()
}
print end_form();
print end_html();
exit(0);

sub showmacs {
# MAC-Adressen aus Datei lesen
my @MACS=&getmacs();
$cgi->delete_all();

# MAC-Adressen anzeigen

print "<P>Neue MAC-Adresse: ".$cgi->textfield(-name=>"mac",-size=>40,).$cgi->submit(-value=>"Hinzufuegen")."</P>\n";

print "<font size=4><b>Freigeschaltete MAC-Adressen</b></font>";

print "<TABLE>\n";
for my $ADDR (@MACS) {
print "<TR><TD>$ADDR</TD><TD><A HREF=\"$self?DELETE_MAC=$ADDR\">loeschen</A></TD></TR>\n";
}
print "</TABLE>\n";
}

sub getmacs {
open(MACS,"<".MAC_FILE) or &error("Kann macs.txt nicht lesen: $!");
my @list;
while(<MACS>) {
chomp();
push(@list,$_);
}
close(MACS);
return(@list);
}

sub writemac {
my $mac=shift;
open(MACS,">>".MAC_FILE) or &error("Kann macs.txt nicht zum schreiben oeffnen: $!");
print MACS "$mac\n";
close(MACS);
}

sub writemacs {
my $macs=shift;
open(MACS,">".MAC_FILE) or &error("Kann macs.txt nicht zum schreiben oeffnen: $!");
for my $ADDR (@$macs) {
print MACS "$ADDR\n";
}
close(MACS);
}


sub macneu {
my $newmac=shift;
my @MACS=&getmacs();
for my $ADDR (@MACS) {
return(0) if($ADDR eq $newmac);
}
return(1);
}

sub deletemac {
my $mac=shift;
my @MACS=&getmacs();
my @NEWMACS;
my $ADDR;
for $ADDR ( @MACS ) {
if($ADDR ne $mac) {
push(@NEWMACS,$ADDR);
}
}
&writemacs(\@NEWMACS);
}

sub convertmac {
my $mac=shift;
if( $$mac =~ /^([0-9a-fA-F]{2}[:-]?){5}[0-9a-fA-F]{2}$/ ) {
$$mac =~ s/-/:/g;
$$mac =~ s/([a-f])/\U$1/g;
return(1);
}
return(0);
}

sub printmessage {
print "<p> </p>";
print $message;
}

#sub writemac {

sub error {
my $msg=shift;
$message="<font size=5 color=red>Fehler: $msg</font>\n";
$error=1;
# die($msg);
}

sub info {
my $msg=shift;
$message="<font size=5 color=green>$msg</font>\n";
$error=0;
# die($msg);
}

sub debug {
my $msg=shift;
print "<font size=5 color=orange>$msg</font>\n";
# die($msg);
}

Hier das zugehoerige iptables-script:

#!/bin/bash

ipt=/sbin/iptables

$ipt -Z
$ipt -X
$ipt -F INPUT
$ipt -F

$ipt -A INPUT -p udp --dport 67 -j REJECT
$ipt -A INPUT -p tcp --dport 67 -j REJECT

for mac in $(cat /etc/dhcp3/mac-access/macs.txt)
do
$ipt -I INPUT -p tcp -m mac,tcp --mac-source $mac --dport 67 -j ACCEPT
$ipt -I INPUT -p udp -m mac,udp --mac-source $mac --dport 67 -j ACCEPT
done

$ipt -A INPUT -j ACCEPT

fork
30.03.06, 18:08
...im README bei ISC steht das das so ist... :(

fork
30.03.06, 19:05
OK. Aufgabe geloest. Ueber die Anweisung deny unknown-clients werden unbekannte Hosts, also hosts die nicht über eine host-Anweisung mit MAC-Adresse bekannt gemacht wurden, abgewiesen. Die host-deklarationen werden dann jeweils neu erzeugt und der DHCP-Server neu gestartet.

dhcpaccess.cgi

#!/usr/bin/perl

use CGI qw/:fatals_to_browser :standard :form *table/;
use strict;
use constant MAC_FILE => '/etc/dhcp3/mac-access/macs.txt';

print header;
print start_html('DHCP-Zugriffssteuerung fuer den Netzbootserver');
print start_form();
my $cgi=CGI->new();
my $self=$cgi->url();
my $error;
my $message;
my $action=0;

print "<h1>DHCP-Zugriffssteuerung fuer den Netzbootserver</h1>\n";
if (param()) {

if(param("mac")) {
my $mac=param("mac");
chomp($mac);
&convertmac(\$mac) or &error("$mac ist keine gueltige MAC-Adresse");
unless($error) {
if(&macneu($mac)) {
&info("MAC Adresse $mac hinzugefuegt");
&writemac($mac);
$action=1;
} else {
&error("MAC Adresse schon vorhanden");
}
}
}
if(param("DELETE_MAC")) {
my $mac=param("DELETE_MAC");
chomp($mac);
if(&macneu($mac)) {
&error("MAC: $mac existiert nicht in der Datei");
} else {
if(&deletemac($mac) ) {
&info("MAC: $mac wurde geloescht");
$action=1;
}
}
}

&showmacs();

&printmessage();

if($action) {
open(RECONFIG,"/usr/bin/sudo /usr/local/bin/dhcp-host-config 2>&1 |");
my $line;
while($line=<RECONFIG>) {
&out($line);
}
&info("Systemkonfiguration wurde geandert");
&printmessage();
}

} else {

&showmacs()
}
print end_form();
print end_html();
exit(0);

sub showmacs {
# MAC-Adressen aus Datei lesen
my @MACS=&getmacs();
$cgi->delete_all();

# MAC-Adressen anzeigen

print "<P>Neue MAC-Adresse: ".$cgi->textfield(-name=>"mac",-size=>40,).$cgi->submit(-value=>"Hinzufuegen")."</P>\n";

print "<font size=4><b>Freigeschaltete MAC-Adressen</b></font>";

print "<TABLE>\n";
for my $ADDR (@MACS) {
print "<TR><TD>$ADDR</TD><TD><A HREF=\"$self?DELETE_MAC=$ADDR\">loeschen</A></TD></TR>\n";
}
print "</TABLE>\n";
}

sub getmacs {
open(MACS,"<".MAC_FILE) or &error("Kann macs.txt nicht lesen: $!");
my @list;
while(<MACS>) {
chomp();
push(@list,$_);
}
close(MACS);
return(@list);
}

sub writemac {
my $mac=shift;
open(MACS,">>".MAC_FILE) or &error("Kann macs.txt nicht zum schreiben oeffnen: $!");
print MACS "$mac\n";
close(MACS);
}

sub writemacs {
my $macs=shift;
open(MACS,">".MAC_FILE) or &error("Kann macs.txt nicht zum schreiben oeffnen: $!");
for my $ADDR (@$macs) {
print MACS "$ADDR\n";
}
close(MACS);
}


sub macneu {
my $newmac=shift;
my @MACS=&getmacs();
for my $ADDR (@MACS) {
return(0) if($ADDR eq $newmac);
}
return(1);
}

sub deletemac {
my $mac=shift;
my @MACS=&getmacs();
my @NEWMACS;
my $ADDR;
for $ADDR ( @MACS ) {
if($ADDR ne $mac) {
push(@NEWMACS,$ADDR);
}
}
&writemacs(\@NEWMACS);
}

sub convertmac {
my $mac=shift;
if( $$mac =~ /^([0-9a-fA-F]{2}[:-]?){5}[0-9a-fA-F]{2}$/ ) {
$$mac =~ s/-/:/g;
$$mac =~ s/([a-f])/\U$1/g;
return(1);
}
return(0);
}

sub printmessage {
print "<p> </p>";
print $message;
}

#sub writemac {

sub error {
my $msg=shift;
$message="<font size=5 color=red>Fehler: $msg</font>\n";
$error=1;
# die($msg);
}

sub info {
my $msg=shift;
$message="<font size=5 color=green>$msg</font>\n";
$error=0;
# die($msg);
}

sub debug {
my $msg=shift;
print "<font size=5 color=orange>$msg</font>\n";
# die($msg);
}

sub out {
my $msg=shift;
print "<p><font size=3>$msg</font><p>\n";
}


dhcp-host-config

#!/bin/bash

reghosts=/etc/dhcp3/mac-access/registered_hosts.txt
>$reghosts

for mac in $(cat /etc/dhcp3/mac-access/macs.txt)
do
echo "host $(echo $mac| /bin/sed -e s/://g) { hardware ethernet $mac; }">>$reghosts
done

/etc/init.d/dhcp3-server restart