pf fails to start
KES
kes-kes at yandex.ru
Thu Sep 7 11:51:37 PDT 2006
some experements:
I)
>kes# ps ax|grep ppp
> 357 ?? Ss 0:18.88 /usr/sbin/ppp -ddial -unit1 adsl
> 373 ?? Rs 46:53.56 /usr/sbin/ppp -dedicated -quiet -unit0 leased
>47226 p2 DL+ 0:00.00 grep ppp
>#KILL pppoe connection
>kes# kill -9 373
>kes# kill -9 373
>373: No such process
>#Reload pf.conf
>kes# pfctl -f /etc/pf.conf
>no IP address found for tun0
>/etc/pf.conf:48: could not parse host specification
>no IP address found for tun0
>/etc/pf.conf:66: could not parse host specification
>no IP address found for tun0
>/etc/pf.conf:100: could not parse host specification
>no IP address found for tun0
>/etc/pf.conf:101: could not parse host specification
>pfctl: Syntax error in config file: pf rules not loaded
>#start pppoe
>kes# /usr/sbin/ppp -dedicated -quiet -unit0 leased
>kes# pfctl -f /etc/pf.conf
>#no errors here.
>kes#
>So I have no "Syntax error in config file"
>TO authur of pf:
>You must change behavior of pf like ipfw does.
>ipfw only do warning messages in situations like this.
to my mind this is a bug, pf must work fine
without any scripts. Look at next situation:
pf starts OK and tun0 rules loaded.
I have delete tun0 interface but pf don't fail and continue working
aroud normally. when I return tun0 pf works as anything had not happend
So it must start without existing interface NORMALLY!! like ipfw does.
>This can easily be solved by using "(tun0)" in these rules
I have such rule:
adslIf = "tun1"
denIf = "rl2"
nat on $denIf from { <natAdsl> } to !<lans> -> ($adslIf)
#pfctl -sn
.....
nat on rl2 from <natAdsl> to ! <lans> -> (tun1) round-robin
ROUND-ROBIN???!!! or no!!!! If I have many IP's and I don't want round-robin....
Any ideas?
>2) "altq on tun0 ..."
>This one can't be worked around directly due to the way ALTQ is
>implemented, but see below.
I have posted next message to NETGRAPH team. I think this will be
better to shape with netgraph against pf + ALTQ
Archie Cobbs <archie at dellroad.org> wrote:
>>KES wrote:
>> Hello, archie.
>>
>> How about 'ALTQ' node? or may be 'queue' node
>> for packets scheduling
>
>> in--->|policy|--->out
>
>> policy may be CBQ, PRIO, HFSC or HTB....
>
>> I want this:
>
>> in-->HTB-->out - - - in-->PRIO-->out
>Sounds neat.. ask around on freebsd-net at freebsd.org as there may
>be others interested, etc.
-----------------------------------
pf.conf
--------------------------------
table <rfc1918> const { 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 }
table <loopback> const { 127.0.0.0/8 }
table <lans> const { 10.10.0.0/16 10.11.0.0/16 10.0.0.0/16 }
table <spoofRfc> const { 192.168.0.0/16 172.16.0.0/12 }
table <natDialup> persist { 192.168.0.0/24 }
table <natDen> persist { 192.168.1.0/24 172.16.82.1 192.168.2.0/24 }
table <natAdsl> persist { 172.16.82.2 }
table <natSirius> persist { 192.168.3.0/24 172.16.82.3 10.10.16.6 10.10.16.1 10.10.16.5 }
table <natArtsv> persist { 192.168.4.0/24 172.16.82.4 }
loopIf = "lo0"
artsvIf = "rl0"
kesIf = "rl2"
denIf = "rl2"
siriusIf = "tun0"
adslIf = "tun1"
vpnIf = "ng"
dialIf = "ppp"
allIntIf = "{" $artsvIf $kesIf "}"
allExtIf = "{" $artsvIf $kesIf $adslIf $siriusIf "}"
realIf = "{" $artsvIf $kesIf $adslIf $siriusIf "}"
localNat= "10.10.16.1 10.10.16.5 10.10.16.6"
clientsNat = "192.168.0.0/24"
denNat = "192.168.1.0/24"
adslNat = "192.168.2.0/24"
siriusNat = "192.168.3.0/24"
artsvNat = "192.168.4.0/24"
artsvIP = "MySomeRealIP"
denIP = "10.0.0.250"
#################################################
############ QUEUEING ################
#################################################
altq on tun0 cbq bandwidth 20Kb queue { tun0_std }
queue tun0_std on tun0 cbq ( default )
# queue tun0_std on tun0 cbq { tun0_out tun0_in }
# queue tun0_in bandwidth 30% cbq (default)
# queue tun0_out bandwidth 30% cbq
#################################################
############ NAT ###################
#################################################
nat on $siriusIf from { <natSirius> <natDialup> } to !<lans> -> $siriusIf
nat on $siriusIf from { <natDen> } to !<lans> -> $denIP
nat on $siriusIf from { <natArtsv> } to !<lans> -> $artsvIP
nat on $siriusIf from { <natAdsl> } to !<lans> -> ($adslIf)
nat on $denIf from { <natDen> } to !<lans> -> $denIP
nat on $denIf from { <natArtsv> <natDialup> } to !<lans>-> $artsvIP
nat on $denIf from { <natAdsl> } to !<lans> -> ($adslIf)
nat on $adslIf from { <natDen> <natAdsl> } to !<lans> -> ($adslIf)
nat on $adslIf from { <natArtsv> <natDialup> } to !<lans> -> $artsvIP
nat on $artsvIf from { <natArtsv> <natDen> <natAdsl> <natDialup> } to !<lans> -> $artsvIP
#rdr LAN irc to world IRC server.
rdr proto tcp from any to 10.0.16.1 port 6667 -> some_Real_IP port 6667
rdr proto tcp from any to any port 8888 -> 192.168.18.50 port 80
rdr proto tcp from any to $siriusIf port { 1313 8080 8085 8086 3724 37240 8087 } -> 10.10.16.6
#################################################
############ FILTER ################
#################################################
#################################################
#Put packets to queues
#################################################
#pass in on tun0 from any to My_REAL_IP queue tun0_in
#pass out on tun0 from My_REAL_IP to any queue tun0_out
block log all
#block on $vpnIf all
block in log quick on $realIf from <spoofRfc> to any
block quick on { ng } from any to <lans>
block quick on { ng } from <lans> to any
pass quick from <lans> to <lans>
#################################################
pass quick on lo0 from any to any
block from 127.0.0.0/8 to any
block from any to 127.0.0.0/8
#************************************************
#Allow outgoing traffic from ME(real IPs) to LANs. We mustnt route it
pass quick on {!ppp !ng} from { 193.239.133.66 10.0.0.250 tun0 (tun1) } to <lans>
pass quick on {ppp ng} from { 193.239.133.66 10.0.0.250 tun0 (tun1) } to 192.168.0.0/16
#Allow outgoing traffic with guaranty next hop
#WARNING: to ANY but !<lans> and !192.168.0.0/16
pass out quick route-to (rl2 10.0.0.30) from 10.0.0.250 to any
pass out quick route-to (rl0 GW_Real_IP_HERE_1 ) from My_Real_IP_HERE_1 to any
pass out quick route-to (tun0 GW_Real_IP_HERE_2 ) from My_Real_IP_HERE_2 to any
#I get dynIP from provider. so I dont know real IP, so I use (tun1)
#but If I get many IP and don'want round-robin. Any Ideas?
pass out quick route-to (tun1 GW_Real_IP_HERE_3 ) from (tun1) to any
#Allow incoming traffic
pass in on rl0 from !<lans> to any
pass in on rl2 from !<lans> to any
pass in on tun1 from any to any
pass in on tun0 from any to any
#Allow IN traffic to internet from LOCAL trusted mashines
pass quick from { $localNat } to !<lans>
pass quick from !<lans> to { $localNat }
pass quick on $dialIf from { 192.168.0.0/16 } to any
pass quick on $dialIf from any to { 192.168.0.0/16 }
pass quick on $vpnIf from { 192.168.0.0/16 } to !<lans>
pass quick on $vpnIf from !<lans> to { 192.168.0.0/16 }
-----------------------------------------------------------------
#################################################################
II)
It's handy if pf have static rule numeration, but pf have not :`-(
If I have changed pf.conf (For example I have two firewall's rules
one if tun0 exists, two if tun0 dont :-\ ) I must change rules for
gathering a statistic. It's very inconvenient!!!
If I have more than one iface to the world. I cant count
incoming trafic, because of when packet goes through rules
it look like this:
world_IP to local_IP
--------------------
213.180.193.123:80 to 192.168.0.1:34212
and I dont know It have come via rl0, rl2, tun0 ro tun1 ???
------------------------
My Program to get statistic
------------------------
#!/usr/bin/perl -w
while( -x '/auto/pfStat/dbDir/lock' ) {
$date= `date`;
`echo -n $date>> /auto/pfStat/dbDir/locked`;
}
`echo > /auto/pfStat/dbDir/lock`;
$periods= {
'hour'=> 'periodic',
'day'=> 'hour',
'month'=> 'day'
};
$saveToRule= {
'29' => 'den_out',
'30' => 'artsv_out',
'31' => 'sirius_out',
'32' => 'adsl_out'
};
$saveToNat= {
'0' => 'sirius_in',
'1' => 'sirius2_in',
'2' => 'den_in',
'3' => 'artsv_in',
'4' => 'adsl_in'
};
while( $saveTo= (each %$saveToRule)[1] ){
push @saveToAll, $saveTo;
}
while( $saveTo= (each %$saveToNat)[1] ){
push @saveToAll, $saveTo;
}
if( defined $ARGV[0] ) {
$period= $ARGV[0];
foreach $saveName ( @saveToAll) {
$sumPkts= 0; $sumBytes= 0;
if( open( FH, "</auto/pfStat/dbDir/$saveName.$periods->{$period}") ) {
$sumPkts= 0; $sumBytes= 0;
while( <FH> =~ /.*?> (\d+) (\d+)/go) {
$sumPkts= $sumPkts + $1;
$sumBytes= $sumBytes + $2;
}
close FH;
}
# print "$sumPkts $sumBytes\n";
#Move old Statistics to DB
$_= $period;
SWITCH:{
/hour/ && do {
($hour)= (localtime())[2];
`mv /auto/pfStat/dbDir/$saveName.$periods->{$period} /auto/pfStat/dbDir/$saveName.$period.$hour`;
last SWITCH;};
/day/ && do {
($day)= (localtime())[3];
`mkdir /auto/pfStat/dbDir/$day` if ! -e "/auto/pfStat/dbDir/$day";
`mv /auto/pfStat/dbDir/$saveName.$periods->{$period} /auto/pfStat/dbDir/$day`;
`mv /auto/pfStat/dbDir/$saveName.$periods->{$period}.* /auto/pfStat/dbDir/$day`;
last SWITCH;};
/month/ && do {
($month,$year)= (localtime())[4,5];
$month+= 1; $year+= 1900;
`mkdir /auto/pfStat/dbDir/$year-$month` if ! -e "/auto/pfStat/dbDir/$year-$month";
`mv /auto/pfStat/dbDir/$saveName.$periods->{$period} /auto/pfStat/dbDir/$year-$month` if -e
"/auto/pfStat/dbDir/$saveName.$periods->{$period}";
$files= `ls -m -p /auto/pfStat/dbDir`;
# print $files;
while ( $files =~ /(.*?),/og ) {
$file= $1;
($dir)= $file =~ /^ ?(\d+)\/$/;
next if !$dir;
`mv /auto/pfStat/dbDir/$dir /auto/pfStat/dbDir/$year-$month` if -e "/auto/pfStat/dbDir/$dir";
}
last SWITCH;};
}
($date)= `date` =~ /(.*?)\n/;
`echo "$date> $sumPkts $sumBytes" >> /auto/pfStat/dbDir/$saveName.$period`;
}
`rm /auto/pfStat/dbDir/lock`;
exit;
}
else {$period= 'periodic';};
$saveTo= $saveToRule;
$pfstat= `pfctl -sr -v -v`;
$matchRule= '@(\d+).*?\n.*?Packets:.*?(\d+).*?Bytes:.*?(\d+).*?\n';
while ( $pfstat =~ /$matchRule/go ) {
if( defined $saveTo->{$1} ) {
$saveName= $saveTo->{$1};
$pktsNew= $2;
$bytesNew= $3;
($pkts, $bytes)= `cat /auto/pfStat/dbDir/$saveName` =~ /(\d+) (\d+)/;
# print "pkts: $pktsNew - $pkts; bytes: $bytesNew - $bytes\n";
if( $pktsNew < $pkts ) {$pkts= $pktsNew;}
else {$pkts= $pktsNew - $pkts;}
if( $bytesNew < $bytes ) {$bytes= $bytesNew;}
else {$bytes= $bytesNew - $bytes;}
($date)= `date` =~ /(.*?)\n/;
`echo "$date> $pkts $bytes" >> /auto/pfStat/dbDir/$saveName.$period`;
`echo -n "$pktsNew $bytesNew" > /auto/pfStat/dbDir/$saveName`;
}
# print "$1 $2 $3\n";
}
$saveTo= $saveToNat;
$pfstat= `pfctl -sn -v -v`;
$matchRule= '@(\d+) nat.*?\n.*?Packets:.*?(\d+).*?Bytes:.*?(\d+).*?\n';
while ( $pfstat =~ /$matchRule/go ) {
# print $1 ." ". $2 ." ". $3 ."\n";
if( defined $saveTo->{$1} ) {
$saveName= $saveTo->{$1};
$pktsNew= $2;
$bytesNew= $3;
($pkts, $bytes)= `cat /auto/pfStat/dbDir/$saveName` =~ /(\d+) (\d+)/;
# print "pkts: $pktsNew - $pkts; bytes: $bytesNew - $bytes\n";next;
if( $pktsNew < $pkts ) {$pkts= $pktsNew;}
else {$pkts= $pktsNew - $pkts;}
if( $bytesNew < $bytes ) {$bytes= $bytesNew;}
else {$bytes= $bytesNew - $bytes;}
($date)= `date` =~ /(.*?)\n/;
`echo "$date> $pkts $bytes" >> /auto/pfStat/dbDir/$saveName.$period`;
`echo -n "$pktsNew $bytesNew" > /auto/pfStat/dbDir/$saveName`;
}
# print "$1 $2 $3\n";
}
`rm /auto/pfStat/dbDir/lock`;
--------------------------------
PS. pf vs ipfw
ipfw -- better fro gather statistic, but elephantine with NATing
pf -- useless for gather statistic, VERY good for redirect, nat etc.
KES mailto:kes-kes at yandex.ru
More information about the freebsd-pf
mailing list