Solved Using IPFW to control traffic between two LANs

kumba

New Member

Reaction score: 1
Messages: 15

So the firewall I've put together seems to work well. What I want to do now is be more restrictive on traffic between two LAN subnets, specifically wireless LAN (WLAN) and wired LAN. I would also like to do this based on interface, not by subnet address, that way I hit both IPv4 and IPv6 traffic at the same time instead of having proto-specific rules. I've figured out a good blocking rule (I think):

Code:
${ipfw} add 0014 set 1 deny ip from any to any out xmit ${wifi} recv ${lan}

Doing a DNS query from a WLAN client to a DNS server on the LAN is denied this way. But if I want to allow DNS traffic to/from WLAN and LAN, I can't figure out how to do that statefully. I was messing around with these two rules and not really getting anywhere:
Code:
#${ipfw} add 0012 set 1 check-state :wlan

${ipfw} add 0013 set 1 allow udp from any to any 53 out xmit ${wifi} recv ${lan} record-state :wlan

I thought that would work. Rule 0013 should allow DNS outbound from WLAN interface dst-port 53 to inbound on LAN interface and record-state (to avoid implicit check-state, since the main :default checkstate is further down in my ruleset). The 0012 check-state rule should allow an answer to return back to WLAN from the LAN, and the 0014 deny rule above catches anything not DNS-based. The flow label I thought prevents the early check-state from causing issues with the main check-state later on (since that one deals more with NAT stuff).

However, this doesn't work. I can tell by logging the packets to the ipfw0 interface that the DNS query packet gets to the LAN, and my LAN's DNS server responds, but the response packet is getting denied by the 0014 deny rule. It seems like check-state is having no effect. Looking at the dynamic rule table, I also don't see where a state association is even setup. I've tried keep-state as well as record-state, but no change in behavior. I haven't tried DNS over TCP in case this is a quirk of how IPFW "sessionizes" UDP (i.e., requiring two packets minimum or such).
 

VladiBG

Aspiring Daemon

Reaction score: 264
Messages: 641

Try this:
${ipfw} add 10 check-state
${ipfw} add 20 allow tcp from any to any 53 out via ${wifi} setup keep-state
${ipfw} add 30 allow udp from any to any 53 out via ${wifi} keep-state
${ipfw} add 40 deny ip from any to any out xmit ${wifi} recv ${lan}
 
OP
OP
K

kumba

New Member

Reaction score: 1
Messages: 15

Try this:
${ipfw} add 10 check-state
${ipfw} add 20 allow tcp from any to any 53 out via ${wifi} setup keep-state
${ipfw} add 30 allow udp from any to any 53 out via ${wifi} keep-state
${ipfw} add 40 deny ip from any to any out xmit ${wifi} recv ${lan}
Just now got back to this. On this particular snippet, what if I already have a check-state rule further down for the WAN/NAT traffic? Aren't the flownames supposed to let you control to which flow a check-state applies to so that I can have a dedicated one for the WLAN to limit the services that WLAN clients on my wifi subnet can access?

In any event, I decided to just run unbound on the WLAN AP subnet in a caching-only mode and used "local-zone static" definitions to identify the small handful of WLAN systems I have. That way, I can go back to my old method of firewalling off the wired and wireless networks completely.
 
Top