Solved PF + IPv6

HI,
I'm having hard time with configuring PF firewall to firewalling IPv6 traffic.
IPv4 works well. But IPv6 has some strange behavior.
For example I have a rule like this:
Code:
pass in on $ext_if inet proto { tcp } from any to <www_servers> port { 80 443 } keep state
pass in on $ext_if inet6 proto { tcp } from any to <www6_servers> port { 80 443 } keep state

Telnet over IPv4 works as expected but over IPv6 it's blocked.

Both ping and ping6 works.

Thanks for some hints in advance.
 
The rules seems pretty straight forward. Standard recommendations I would think would apply. Do you have any rules below it that are more specific that could be matching it? Remember PF is last match wins unless you use the 'quick' keyword. Try checking counters of pfctl -vsr and look for what rules are making state matches and rules don't make a match. Try adding 'log' statements and examining in real time using the tcpdump(1) command in pflog(4).
 
Thanks. I made some research as you recommended. There might be problem in the "pass out" rule while on IPv6 if I read logs correctly.
Here is some log output:

IPv4 port 80 (works):

telnet:
telnet 10.26.18.4 80
Code:
Trying 10.26.18.4...
Connected to 10.26.18.4.
Escape character is '^]'.

pflog:
Code:
00:00:00.211245 rule 12..16777216/0(match): pass in on igb0: 192.168.117.71.37160 > 10.26.18.4.80: Flags , seq 3904808337, win 14600, options [mss 1460,sackOK,TS val 24265303 ecr 0,nop,wscale 4], length 0

tcpdump:
Code:
17:47:31.236630 IP 192.168.117.71.37160 > 10.26.18.4.80: Flags , seq 3904808337, win 14600, options [mss 1460,sackOK,TS val 24265303 ecr 0,nop,wscale 4], length 0
17:47:31.251832 IP 10.26.18.4.80 > 192.168.117.71.37160: Flags [S.], seq 1845064795, ack 3904808338, win 65535, options [mss 1460,nop,wscale 6,sackOK,TS val 1722364036 ecr 24265303], length 0
17:47:31.251849 IP 192.168.117.71.37160 > 10.26.18.4.80: Flags [.], ack 1, win 913, options [nop,nop,TS val 24265307 ecr 1722364036], length 0
17:47:39.510952 IP 192.168.117.71.37160 > 10.26.18.4.80: Flags [F.], seq 1, ack 1, win 913, options [nop,nop,TS val 24267372 ecr 1722364036], length 0
17:47:39.526014 IP 10.26.18.4.80 > 192.168.117.71.37160: Flags [.], ack 2, win 1040, options [nop,nop,TS val 1722372310 ecr 24267372], length 0
17:47:39.526116 IP 10.26.18.4.80 > 192.168.117.71.37160: Flags [F.], seq 1, ack 2, win 1040, options [nop,nop,TS val 1722372310 ecr 24267372], length 0
17:47:39.526126 IP 192.168.117.71.37160 > 10.26.18.4.80: Flags [.], ack 2, win 913, options [nop,nop,TS val 24267376 ecr 1722372310], length 0


IPv6 port 80 (not working):

server with firewall: 2001:20:10::214:84
client: 2a02:125:1006::2:b


telnet:
telnet 2001:20:10::214:84 80
Code:
Trying 2001:20:10::214:84...
telnet: Unable to connect to remote host: Connection timed out

pflog:
Code:
00:00:00.000000 rule 14..16777216/0(match): pass in on igb0: 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22261606 ecr 0,nop,wscale 4], length 0

tcpdump:
Code:
15:33:56.447848 IP6 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22261606 ecr 0,nop,wscale 4], length 0
15:33:57.446045 IP6 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22261856 ecr 0,nop,wscale 4], length 0
15:33:59.450035 IP6 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22262357 ecr 0,nop,wscale 4], length 0
15:34:03.462030 IP6 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22263360 ecr 0,nop,wscale 4], length 0
15:34:11.478040 IP6 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22265364 ecr 0,nop,wscale 4], length 0
15:34:27.526043 IP6 2a02:125:1006::2:b.50303 > 2001:20:10::214:84.80: Flags , seq 1879235569, win 14400, options [mss 1440,sackOK,TS val 22269376 ecr 0,nop,wscale 4], length 0

There is a difference in tcpdump output. While testing IPv6 I can only see packets from client but no packets from server. IPv4 is fine as shown in tcpdump.

I tried to put "pass out inet6 all keep state" in pf.conf but no success.
Is there any other rule which is necessary to pass IPv6 traffic?
 
Have you tested if 2001:20:10::214:84 is listening on port 80? (you can always use telnet from inside your host)
 
Yes, it listens. When I'm trying to telnet service on IPv6 directly from the machine, it works:
sockstat
Code:
www      httpd      68843 3  tcp6   2001:20:10::214:84:80 *:*
 
I ran pfctl -vvsr as junovitch recommended and it seems (if I read it correctly) that there is really something wrong:
Code:
@8 pass out log on igb0 inet6 proto tcp from (igb0:5) to ! (igb0:5) flags S/SA modulate state (max 90000, source-track rule, max-src-conn 1000, max-src-nodes 256, adaptive.start 54000, adaptive.end 108000)
  [ Evaluations: 290       Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 72674 State Creations: 0     ]

Shouldn't be Packets: >0 if I try to telnet IPv6 ports?

This is for pings:
Code:
@10 pass out log on igb0 inet6 proto ipv6-icmp from (igb0:5) to ! (igb0:5) keep state (max 90000, source-track rule, max-src-conn 1000, max-src-nodes 256, adaptive.start 54000, adaptive.end 108000)
  [ Evaluations: 260       Packets: 572       Bytes: 39232       States: 1     ]
  [ Inserted: uid 0 pid 72674 State Creations: 252   ]

When I'm pinging server Packets: are increasing (as I wrote - ping6 works)
 
Alright, I have found a problem:
Code:
scrub on $ext_if all reassemble tcp fragment reassemble

Is there any way how to normalize IPv6 packets? It seems there is no support for it.
 
The @8 rule in your rules is really strange if this is a firewall between a LAN and WAN, it is passing only traffic originating from the firewall itself and nothing from the LAN network if there is one. Can you post the full rules?
 
The @8 rule in your rules is really strange if this is a firewall between a LAN and WAN, it is passing only traffic originating from the firewall itself and nothing from the LAN network if there is one. Can you post the full rules?

There was a problem with scrubbing. It works well with IPv4 but it drops IPv6 packets:
The rule is:
Code:
scrub on $ext_if all reassemble tcp fragment reassemble

Now I'm trying to find how to solve it.
 
Code:
### all incoming traffic on external interface is normalized and fragmented
### packets are reassembled.
scrub in on $ext_if all fragment reassemble

This is from a 9.3 PF fully dual stacked working without any problems.
 
I did not read all that stuff that was written here, but I would look if router and neighbor advertisements and solicitations are working right.
Sometimes providers are filtering on their switches, doing something like IGMP Snooping that causes advertisements to fail.
 
Thanks guys,
Code:
scrub in on $ext_if all fragment reassemble

works. I did not have a chance to try it sooner, sorry for the delay.
I set this thread as solved.
Thanks again.
 
Back
Top