PF and DHCP on FreeBSD10

Hello,

I recently upgraded my 8.3 box to 10.0 and was hoping to leverage DHCP this time around. In my /etc/rc.conf when setting DHCP I notice that my/etc/pf.conf rules do not get loaded on boot. The console messages scroll by rather quickly but it seems like it is because it does not have an IP address loaded in time for when it wants to start up PF. I can verify they are not loaded by pinging the server from a remote host and receiving replies (when PF is loaded ping probes are blocked). Furthermore when I statically set the IP for my network interface in /etc/rc.conf there appears to be no route outside of my network. I pasted the ping output below when using DHCP and also my relative config files which I hope to be of assistance. I also include output from jls since I have a few jails. Not sure if those need to be added into my/etc/rc.conf file but they seem to work without issue. Another thing that is odd, and perhaps related to the lack of IP address (or so it seems) on boot via DHCP is that the /etc/pf.conf rules never get loaded, however when dropping the kern.securelevel I have no problem running them via the command line (rules parse fine).

Code:
[brad@mercury ~]$ cat /etc/pf.conf
set skip on lo0
interface="re0"
apacheJail="192.168.0.102"
ircJail="192.168.0.103"
plexJail="192.168.0.104"
scrub in all
rdr pass on $interface proto tcp from any to $interface port 80 -> $apacheJail 
rdr pass on $interface proto tcp from any to $interface port 6667 -> $ircJail 
rdr pass on $interface proto tcp from any to $interface port 32400 -> $plexJail 
antispoof for lo0
antispoof for $interface
block in on $interface
pass in on $interface proto tcp from any to any port 2662 
pass out on $interface proto {tcp,udp,icmp} all


[brad@mercury ~]$ cat /etc/rc.conf
hostname="mercury.milkyway"
keyrate="fast"
ifconfig_re0="192.168.0.101 netmask 255.255.255.0"
#ifconfig_re0="DHCP"
pf_enable="YES"
pf_rules="/etc/pf.conf"
dumpdev="NO"
zfs_enable="YES"
sshd_enable="YES"
ntpd_enable="YES"
ezjail_enable="YES"
nfs_client_enable="YES"
kern_securelevel_enable="YES"
kern_securelevel="3"


[brad@mercury ~]$ cat /etc/resolv.conf 
search milkyway
nameserver 192.168.0.1



[brad@mercury ~]$ ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
        ether 74:d4:35:3f:2c:df
        inet 192.168.0.101 netmask 0xffffff00 broadcast 192.168.0.255 
        inet 192.168.0.104 netmask 0xffffffff broadcast 192.168.0.104 
        inet 192.168.0.103 netmask 0xffffffff broadcast 192.168.0.103 
        inet 192.168.0.102 netmask 0xffffffff broadcast 192.168.0.102 
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128 
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
        inet 127.0.0.1 netmask 0xff000000 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>


[brad@mercury ~]$ jls
   JID  IP Address      Hostname                      Path
     1  192.168.0.104   plexJail                      /usr/jails/plexJail
     2  192.168.0.103   ircJail                       /usr/jails/ircJail
     3  192.168.0.102   apacheJail                    /usr/jails/apacheJail

[brad@mercury ~]$ ping google.com
PING google.com (74.125.228.6): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host
ping: sendto: No route to host
ping: sendto: No route to host
^C
 
Try with the interface configured with DHCP but in such a way that the start up scripts wait until the DHCP negotiation has finished. It's called SYNCDHCP:

Code:
ifconfig_re0="SYNCDHCP"
 
Awesome! Worked like a charm! Thank you for that info, I was not aware of that option.
 
It should also work if you change your rules a little, instead of this:
Code:
rdr pass on $interface proto tcp from any to $interface port 80 -> $apacheJail
You would use this:
Code:
rdr pass on $interface proto tcp from any to ($interface) port 80 -> $apacheJail
The ($interface) will make sure the rule is automatically adjusted when the IP address of $interface changes.

Another way is to remove the destination address completely:
Code:
rdr pass on $interface proto tcp to port 80 -> $apacheJail
 
Thanks I will adjust that too just in case I change it down the road...might save a few headaches.
 
Back
Top