pf: rule expands to no valid combination

dvl@

Developer
When my FreeBSD 8.2-STABLE firewall reboots, the PF ruleset is not loaded. After booting, if I invoke the ruleset manually, it loads just fine: # pfctl -f /etc/pf.rules

Watching the boot process, I see these two messages:
Code:
/etc/pf.rules:136: rule expands to no valid combination
/etc/pf.rules:147: rule expands to no valid combination
pfctl: Syntax error in config file: pf rules not loaded
Looking at those lines:
Code:
1: ext_if="fxp0"
2: int_if="fxp1"
...
127: pass out quick on $ext_if proto tcp all modulate state flags S/SA
...
133: pass out quick on $int_if proto ipv6-icmp all synproxy state
134: pass in  quick on $int_if proto ipv6-icmp all synproxy state
135:
136: pass in  on $int_if inet6 proto tcp from $int_if:network flags S/SA keep state
...
147: pass in quick on $ext_if inet proto {tcp, udp} from any to $ext_if port domain keep state
I included 127 and 133-134 to demonstrate that other rules refer to $int_if and $ext_if without problem.

Ideas? Suggestions?
 
I'd guess the interfaces are taking too long to initialize fully before PF tries to load the rules and the interfaces do not yet have addresses assigned to them. Maybe /etc/rc.d/netwait can remedy the problem?
 
kpa said:
I'd guess the interfaces are taking too long to initialize fully before PF tries to load the rules and the interfaces do not yet have addresses assigned to them. Maybe /etc/rc.d/netwait can remedy the problem?

That's not found in this 8.4 system, but I see in it a 9.1 system. I see this in there:

Code:
# The netwait script is intended to be used by systems which have
# statically-configured IP addresses in rc.conf(5).  If your system
# uses DHCP, you should use synchronous_dhclient="YES" in your
# /etc/rc.conf instead of using netwait.

Is that what you meant?
 
Thanks. It appears to be unavailable on 8.4. But what great incentive to upgrade to 9.1.
 
Re synproxy

From http://openbsd.org/faq/pf/filter.html#synproxy

Normally when a client initiates a TCP connection to a server, PF will pass the handshake packets between the two endpoints as they arrive. PF has the ability, however, to proxy the handshake. With the handshake proxied, PF itself will complete the handshake with the client, initiate a handshake with the server, and then pass packets between the two. In the case of a TCP SYN flood attack, the attacker never completes the three-way handshake, so the attacker's packets never reach the protected server, but legitimate clients will complete the handshake and get passed. This minimizes the impact of spoofed TCP SYN floods on the protected service, handling it in PF instead. Routine use of this option is not recommended, however, as it breaks expected TCP protocol behavior when the server can't process the request and when load balancers are involved.
 
Oh yes good catch @J65nko. The synproxy is meant to be turned on only when you're under an attack.
 
Last edited by a moderator:
I've changed all my 'synproxy state' instances to 'keep state'.

The problem persists, but I don't think that was meant to fix it.

FYI, I think the 'and' in the final sentence of the quote should be an 'or'. i.e. I'm not using a load balancer, thus this should never affect me.
 
dvl@ said:
Thanks. It appears to be unavailable on 8.4. But what great incentive to upgrade to 9.1.

Well, yes, but it is in 8.4. Look in /etc/defaults/rc.conf. Here's an example:

Code:
netwait_enable="YES"
netwait_ip="333.333.333.333"  # IP address to ping
netwait_timeout="60"
netwait_if="re0"
netwait_if_timeout="60"
 
Indeed, my remark about synproxy was not meant to solve your problem ;)

I don't have an 8.4 system but on a 9.1 system without an internal NIC I can reproduce your error with a lo5 device:

Code:
[cmd=#] cat -n dvl.pf[/cmd]
     1  int_if = 'lo5'
     2  ext_if = 're0'
     3
     4  pass out quick on $ext_if proto tcp all 
     5  pass out quick on $int_if proto ipv6-icmp all 
     6  pass in  quick on $int_if proto ipv6-icmp all
     7
     8  pass in  on $int_if inet6 proto tcp from [color=blue]$int_if:network[/color]
     9
    10  pass in quick on $ext_if inet proto {tcp, udp} from any to $ext_if port domain

[cmd=#] ifconfig lo5 create 10.1.2.3/24[/cmd]

[cmd=#] ifconfig lo5[/cmd]
lo5: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 10.1.2.3 netmask 0xffffff00 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

[cmd=#] pfctl -vvnf dvl.pf[/cmd]
int_if = "lo5"
ext_if = "re0"
dvl.pf:8: rule expands to no valid combination

If I assign an IPv6 address it works:

Code:
[cmd=#]ifconfig lo5 inet6 3:: ; ifconfig lo5[/cmd]
lo5: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 10.1.2.3 netmask 0xffffff00 
        inet6 3:: prefixlen 64 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

[cmd=#] pfctl -vvnf dvl.pf[/cmd]
int_if = "lo5"
ext_if = "re0"
@0 pass out quick on lo5 proto ipv6-icmp all keep state
@1 pass in quick on lo5 proto ipv6-icmp all keep state
@2 pass out quick on re0 proto tcp all flags S/SA keep state
[color=blue]@3 pass in on lo5 inet6 proto tcp from 3::/64 to any flags S/SA keep state[/color]
@4 pass in quick on re0 inet proto tcp from any to 88.198.14.41 port = domain flags S/SA keep state
@5 pass in quick on re0 inet proto udp from any to 88.198.14.41 port = domain keep state

I think the first error, about being unable to expand the $int_if:network construct is the real error. Because the internal interface does not yet have an IPv6 address it is not possible to derive the IPv6 network/subnet.
 
wblock@ said:
Well, yes, but it is in 8.4. Look in /etc/defaults/rc.conf. Here's an example:

Code:
netwait_enable="YES"
netwait_ip="333.333.333.333"  # IP address to ping
netwait_timeout="60"
netwait_if="re0"
netwait_if_timeout="60"

Ahh, my error was locate... I was using locate on 9.1, but on 8.4, the locate database was out of date...

Thank you.
 
J65nko said:
I think the first error, about unable to expand the $int_if:network construct when the internal interface does not yet have an IPv6 address is the culprit.

Interesting... And the second error?
 
wblock@ said:
Well, yes, but it is in 8.4. Look in /etc/defaults/rc.conf. Here's an example:

Code:
netwait_enable="YES"
netwait_ip="333.333.333.333"  # IP address to ping
netwait_timeout="60"
netwait_if="re0"
netwait_if_timeout="60"

I tried this:

Code:
netwait_enable="YES"
netwait_ip="2001:470:1f07:b80:21b:21ff:fe51:ab2d" # internal host
netwait_if="fxp1"

and this

Code:
netwait_enable="YES"
netwait_ip="10.0.0.1" # external host, not the real IP
netwait_if="fxp0"

In both cases, the error messages for pf appeared before the netwait was performed. FYI, this was on FreeBSD 8.4-RELEASE-p1. Now trying a freebsd-update -r 9.1-RELEASE fetch.
 
Does fxp0 have a static or dynamic IP address? If it's dynamic, use ifconfig_fxp0="SYNCDHCP". Also, there was an errataum about fxp(4) interfaces having problems bouncing, but I don't recall which release that was on.
 
Yes, fxp0 has a dynamic address. I will try that option after this freebsd-update finishes.

Fetching 9107 patches.....10....20

Two hours later: 1580....1590....1600…

Might be a while.
 
That's it, then.
Code:
ifconfig_fxp0="DHCP"
continues with the startup scripts before dhclient(8) finishes, and other startup scripts like /etc/rc.d/pf can run before fxp0 has an address.
 
dvl@ said:
I tried this:

Code:
netwait_enable="YES"
netwait_ip="2001:470:1f07:b80:21b:21ff:fe51:ab2d" # internal host
netwait_if="fxp1"

and this

Code:
netwait_enable="YES"
netwait_ip="10.0.0.1" # external host, not the real IP
netwait_if="fxp0"

In both cases, the error messages for pf appeared before the netwait was performed. FYI, this was on FreeBSD 8.4-RELEASE-p1. Now trying a freebsd-update -r 9.1-RELEASE fetch.

FYI, on FreeBSD 9.1-RELEASE-p4, netwait worked. After boot, my rules were correctly loaded.
 
wblock@ said:
Does fxp0 have a static or dynamic IP address? If it's dynamic, use ifconfig_fxp0="SYNCDHCP". Also, there was an errataum about fxp(4) interfaces having problems bouncing, but I don't recall which release that was on.

This worked too. Thank you. I think I'll be using this.
 
Back
Top