My firewall is set up and working for everything - almost. It's running NAT and altq, neither of which should be relevant to my problem (let me know if I'm wrong, and I'll post details)
It has 3 relevant interfaces: $ext_if - x.x.x.x (running NAT) $dmz_if - 10.0.1/24 $int_if - 10.0.0/24 I'll continue translating interface names into the above variables for consistency. I have a web server on the dmz at 10.0.1.3, which I can't reach from within the LAN (10.0.0.x). For troubleshooting, I inserted the following as my first filter rule: pass in log quick inet proto tcp from any to 10.0.1.3 \ port = www keep state Going to 10.0.1.3 from my computer (10.0.0.12) produce the following at the firewall: $ sudo tcpdump -netti $dmz_if host 10.0.1.3 tcpdump: listening on $dmz_if ##### ABBREVIATED ######### 10.0.0.12.2358 > 10.0.1.3.80: S 1460,nop,nop,sackOK> 10.0.1.3.80 > 10.0.0.12.2358: S 1460,nop,nop,sackOK> 10.0.0.12.2358 > 10.0.1.3.80: S 1460,nop,nop,sackOK> 10.0.1.3.80 > 10.0.0.12.2358: . ack 1 17520 10.0.1.3.80 > 10.0.0.12.2358: S 1460,nop,nop,sackOK> 10.0.1.3.80 > 10.0.0.12.2358: S 1460,nop,nop,sackOK> 10.0.0.12.2358 > 10.0.1.3.80: S 1460,nop,nop,sackOK> 10.0.1.3.80 > 10.0.0.12.2358: . ack 1 17520 ##### END ABBREVIATED ######### ##### UNABRIDGED ######### 1115153374.614518 0:90:27:88:b6:fe 0:0:86:42:a3:1c 0800 62: 10.0.0.12.2358 > 10.0.1.3.80: S 1296914794:1296914794(0) win 65535 <mss 1460,nop,nop,sackOK> (DF) 1115153374.614730 0:0:86:42:a3:1c 0:90:27:88:b6:fe 0800 62: 10.0.1.3.80 > 10.0.0.12.2358: S 1556928070:1556928070(0) ack 1296914795 win 17520 <mss 1460,nop,nop,sackOK> (DF) 1115153377.523739 0:90:27:88:b6:fe 0:0:86:42:a3:1c 0800 62: 10.0.0.12.2358 > 10.0.1.3.80: S 1296914794:1296914794(0) win 65535 <mss 1460,nop,nop,sackOK> (DF) 1115153377.523918 0:0:86:42:a3:1c 0:90:27:88:b6:fe 0800 60: 10.0.1.3.80 > 10.0.0.12.2358: . ack 1 win 17520 (DF) 1115153377.524631 0:0:86:42:a3:1c 0:90:27:88:b6:fe 0800 62: 10.0.1.3.80 > 10.0.0.12.2358: S 1556928070:1556928070(0) ack 1296914795 win 17520 <mss 1460,nop,nop,sackOK> (DF) 1115153383.533238 0:0:86:42:a3:1c 0:90:27:88:b6:fe 0800 62: 10.0.1.3.80 > 10.0.0.12.2358: S 1556928070:1556928070(0) ack 1296914795 win 17520 <mss 1460,nop,nop,sackOK> (DF) 1115153383.542747 0:90:27:88:b6:fe 0:0:86:42:a3:1c 0800 62: 10.0.0.12.2358 > 10.0.1.3.80: S 1296914794:1296914794(0) win 65535 <mss 1460,nop,nop,sackOK> (DF) 1115153383.542924 0:0:86:42:a3:1c 0:90:27:88:b6:fe 0800 60: 10.0.1.3.80 > 10.0.0.12.2358: . ack 1 win 17520 (DF) 1115153397.774040 0:0:86:42:a3:1c ff:ff:ff:ff:ff:ff 0800 243: 10.0.1.3.138 > 10.0.1.255.138: udp 201 ##### END UNABRIDGED ######### Obviously, the request for the web page is getting to the web server, and the ack packet is getting back to the firewall, but never through the firewall back to my computer. So, I try listening to pflog0: $ sudo tcpdump -netti pflog0 host 10.0.1.3 tcpdump: listening on pflog0 ##### ABBREVIATED ######### rule 0/0(match): pass in on $int_if: 10.0.0.12.2519 > 10.0.1.3.80: S ... rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: S ... ack... rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: . ack... rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: S ... ack... rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: . ack... rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: S ... ack... rule 127/0(match): block in on $dmz_if: 10.0.1.3.138 > 10.0.1.255.138: udp 208 ##### END ABBREVIATED ######### ##### UNABRIDGED ######### 1115156686.704844 rule 0/0(match): pass in on $int_if: 10.0.0.12.2519 > 10.0.1.3.80: S 453666105:453666105(0) win 65535 <mss 1460,nop,nop,sackOK> (DF) 1115156686.705489 rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: S 309612598:309612598(0) ack 453666106 win 17520 <mss 1460,nop,nop,sackOK> (DF) 1115156689.686885 rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: . ack 1 win 17520 (DF) 1115156689.698320 rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: S 309612598:309612598(0) ack 453666106 win 17520 <mss 1460,nop,nop,sackOK> (DF) 1115156695.705812 rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: . ack 1 win 17520 (DF) 1115156695.706915 rule 127/0(match): block in on $dmz_if: 10.0.1.3.80 > 10.0.0.12.2519: S 309612598:309612598(0) ack 453666106 win 17520 <mss 1460,nop,nop,sackOK> (DF) 1115156705.732135 rule 127/0(match): block in on $dmz_if: 10.0.1.3.138 > 10.0.1.255.138: udp 208 ##### END UNABRIDGED ######### Now, what's up with that!? The packet entering $int_if matched the first rule - but only once. Subsequant packets going that direction must have matched the state table, since they didn't show up (right?). But returning packets entering on $dmz_if got blocked. Why would they even be filtered? They should be found in the state table. Or am I missing something? I'm feeling pretty stumped. I hope someone has more insight on this than I. Thanks in advance.