Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Sep 2006 21:50:31 +0300
From:      KES <kes-kes@yandex.ru>
To:        freebsd-pf@freebsd.org
Subject:   Re[2]: pf fails to start
Message-ID:  <1211713334.20060907215031@yandex.ru>
In-Reply-To: <fd564f30609070633o663499eel853f29a7f54b12a7@mail.gmail.com>
References:  <922498059.20060907160002@yandex.ru> <fd564f30609070633o663499eel853f29a7f54b12a7@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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@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@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@yandex.ru




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1211713334.20060907215031>