PF pf ignoring rules - unable to do zone transfers

I am unable to get pf to allow zone transfer traffic to happen. Here is my setup:

172.16.100.122 = dns slave
172.16.10.177 = dns master

The slave can do queries using drill example.com @172.16.10.177 but zone transfers totally fail. The traffic is being dropped by PF.

Code:
drill -t axfr example.com @172.16.10.177

Code:
block in on vlan10: 172.16.10.177.53 > 172.16.100.122.23383: Flags [S.], seq 636995862, ack 2691157684, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 870150398 ecr 339277532], length 0

I tried to make rules to explicitly pass in traffic coming from port 53 as well but it is still being dropped.


Code:
pass in quick on vlan10 inet proto tcp from 172.16.10.177 to any flags S/SA keep state label "DNS testing"
pass in quick on vlan10 inet proto udp from 172.16.10.177 to any keep state label "DNS testing"


This code is at the top of all pass rules and pf seems to be ignoring it.

Any ideas?
 
Use -e on your tcpdump of pflog to see what rule (see pfctl -vvs rules) is blocking it and work from there. Do you have any block quick rules above it?
 
Use -e on your tcpdump of pflog to see what rule (see pfctl -vvs rules) is blocking it and work from there. Do you have any block quick rules above it?

It says rule 0 is matching.

Here are the rules according to pfctl -vvs rules
Code:
@0 block drop in log all
  [ Evaluations: 9092870   Packets: 8663308   Bytes: 520420890   States: 0     ]
  [ Inserted: uid 0 pid 41510 State Creations: 0     ]
@1 pass out all flags S/SA keep state
  [ Evaluations: 9091319   Packets: 1909472   Bytes: 481940675   States: 29    ]
  [ Inserted: uid 0 pid 41510 State Creations: 225922]
@2 pass in quick on vlan10 inet proto tcp from 172.16.10.177 to any flags S/SA keep state label "DNS testing"
  [ Evaluations: 8864857   Packets: 11623     Bytes: 11359570    States: 0     ]
  [ Inserted: uid 0 pid 41510 State Creations: 44    ]
@3 pass in quick on vlan10 inet proto udp from 172.16.10.177 to any keep state label "DNS testing"
  [ Evaluations: 319032    Packets: 3312      Bytes: 777330      States: 0     ]
  [ Inserted: uid 0 pid 41510 State Creations: 1705  ]
When I try a zone transfer here is the tcpdump

Code:
15:57:00.719683 rule 0..16777216/0(match): block in on vlan10: 172.16.10.177.53 > 172.16.100.122.63487: Flags [S.], seq 2553593698, ack 1432322508, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1202143376 ecr 671270510], length 0
 
It's not being blocked. Rule 0 always matches even if a rule later on allows the traffic. Rule 0 also always logs matching packets, i.e. everything, including traffic that's allowed in subsequent rules. Use tcpdump(1) to look at the actual traffic, not the data from pflog0.

I would suggest removing the log from block in all and add a log statement to the rules allowing the DNS traffic.
 
I think you're reloading rules and catching packets that are part of an established connection, but not in pf's state table. "Flags [S.]" = Syn+Ack == part of a connection already created.

Try setting up your ruleset and then rebooting, if possible. See also the paragraph starting with "Because flags S/SA is applied by default" in pf.conf(5).
 
I think you're reloading rules and catching packets that are part of an established connection, but not in pf's state table. "Flags [S.]" = Syn+Ack == part of a connection already created.

Try setting up your ruleset and then rebooting, if possible. See also the paragraph starting with "Because flags S/SA is applied by default" in pf.conf(5).

I rebooted and I get the same result.

It's not being blocked. Rule 0 always matches even if a rule later on allows the traffic. Rule 0 also always logs matching packets, i.e. everything, including traffic that's allowed in subsequent rules. Use tcpdump(1) to look at the actual traffic, not the data from pflog0.

If I analyze the traffic on vlan10 and do a zone transfer I get this

tcpdump -e -ni vlan10 port 53
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vlan10, link-type EN10MB (Ethernet), capture size 65535 bytes
18:58:25.537745 0c:c4:7a:12:46:04 > 00:00:5e:00:01:01, ethertype IPv4 (0x0800), length 74: 172.16.10.177.53 > 172.16.100.122.53186: Flags [S.], seq 497690022, ack 1411747825, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1213028195 ecr 682155329], length 0
18:58:28.579266 0c:c4:7a:12:46:04 > 00:00:5e:00:01:01, ethertype IPv4 (0x0800), length 74: 172.16.10.177.53 > 172.16.100.122.53186: Flags [S.], seq 3539731897, ack 1411747825, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1213031236 ecr 682158371], length 0

What is the step needed for allowing the traffic to pass? I'm confused here.
 
Something is missing here; these is the second transfer in a tcp 3-way handshake. Where is the first should be just an "S"? Can you make a diagram of where you're running commands, where you're capturing traffic, and where the pf rules are? Everything works when you disable pf?

Please provide the full pf.conf, too. (On each machine running pf)
 
Something is missing here; these is the second transfer in a tcp 3-way handshake. Where is the first should be just an "S"? Can you make a diagram of where you're running commands, where you're capturing traffic, and where the pf rules are? Everything works when you disable pf?

Please provide the full pf.conf, too. (On each machine running pf)

Zone transfers work immediately if I disable pf.

tsJhwzz.png


pf.conf
Code:
block in log all
pass out all keep state


# 172.16.10.177 = DNS Master
# zone transfers
pass in quick on $vlan10_if proto {tcp, udp} from 172.16.10.177 to any label "DNS testing"

# DNS lookups
pass in on $vlan10_if proto {tcp, udp} from $vlan10_if:network to any port 53
pass in on $vlan100_if proto {tcp, udp} from $vlan100_if:network to any port 53

Commands being run

On the the DNS slave - 172.16.100.122

Code:
drill -t axfr example.com @172.16.10.177
Error: Error starting axfr: Could not send or receive, because of network error


On the firewall

Code:
tcpdump -e -ni vlan10 port 53 and host 172.16.10.177
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vlan10, link-type EN10MB (Ethernet), capture size 65535 bytes
19:36:36.178979 0c:c4:7a:12:46:04 > 00:00:5e:00:01:01, ethertype IPv4 (0x0800), length 74: 172.16.10.177.53 > 172.16.10.177.100.122.15501: Flags [S.], seq 885461597, ack 1806053195, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1215318837 ecr 684445971], length 0
19:36:39.206879 0c:c4:7a:12:46:04 > 00:00:5e:00:01:01, ethertype IPv4 (0x0800), length 74: 172.16.10.177.53 > 172.16.10.177.100.122.15501: Flags [S.], seq 885461597, ack 1806053195, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1215318837 ecr 684448999], length 0

Code:
tcpdump -e -ni pflog0 port 53
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 65535 bytes
19:40:23.478332 rule 0..16777216/0(match): block in on vlan10: 172.16.10.177.53 > 172.16.100.122.64526: Flags [S.], seq 2209413258, ack 2146696585, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1215546136 ecr 684673270], length 0
19:40:26.497835 rule 0..16777216/0(match): block in on vlan10: 172.16.10.177.53 > 172.16.100.122.64526: Flags [S.], seq 2209413258, ack 2146696585, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 1215546136 ecr 684676290], length 0
 
I have to assume that's not the whole pf.conf as your $*_if macros aren't defined. I'll assume they're what you would expect.

Can your try adding 'flags any' to your pass ... port 53 lines?
 
I have to assume that's not the whole pf.conf as your $*_if macros aren't defined. I'll assume they're what you would expect.

Can your try adding 'flags any' to your pass ... port 53 lines?

Do you mean like this?

Code:
# 172.16.10.177 = DNS Master
# zone transfers
pass in quick on $vlan10_if proto {tcp, udp} from any port 53 to any

# DNS lookups
pass in on $vlan10_if proto {tcp, udp} from any  to any port 53
pass in on $vlan100_if proto {tcp, udp} from any to any port 53
 
It's not being blocked.

Seems like it was definitely being blocked.


No, like this:

Code:
pass in quick on $vlan10_if proto {tcp, udp} from any port 53 to any flags any

This works!

Code:
pass in quick on $vlan10_if proto {tcp, udp} from any port 53 to any flags any


I did some testing and read the man page section on flags.

I noticed that this rule works

Code:
pass in quick on $vlan10_if proto {tcp, udp} from any port 53 to any flags S/S

But it does not work with (the default rule basically)

Code:
pass in quick on $vlan10_if proto {tcp, udp} from any port 53 to any flags S/SA

Does this mean that the DNS master is starting off the transfer with a SYNACK packet instead of a SYN packet? I would really like to understand why this is happening but I am happy that it is working now!

Thanks again Eric.
 
Something is odd. You might try making sure the pf rules (without flags any) are loaded, and then reboot either the master or slave system to make sure all TCP connections are completely torn down, and then test, but it’s quite odd.
 
It's not being blocked. Rule 0 always matches even if a rule later on allows the traffic. Rule 0 also always logs matching packets, i.e. everything, including traffic that's allowed in subsequent rules. Use tcpdump(1) to look at the actual traffic, not the data from pflog0

I don’t believe this is true. You can have a block log all as rule 0, and as long as a packet matches some other (non-logging) rule later (or existing state), it will not be output to pflog0. I can go test, but that’s my recollection
 
Back
Top