IPFW NO DNS ACCESS - IPFW ??

Hello!

I'm having a problem getting dns connectivity for my windows computer on the LAN.I have tried with linux from the LAN and it works, but not if I use a windows machine(tried with two different windows machines).
Below are my /etc/ipfw.rules and /etc/rc.conf.
Any ideas on what could be wrong?

Code:
#!/bin/sh

# Flush existing rules
ipfw -f flush

wan=igc0
lan=ue0

# Block all IPv6 traffic
ipfw add 5 drop ip6 from any to any

# Allow all traffic on the LAN
ipfw add 10 allow all from any to any via $lan

# NAT rule for LAN to WAN traffic
ipfw add 15 divert natd ip4 from any to any via $wan

# Allow outbound DNS traffic on WAN
ipfw add 20 allow tcp from any to any 53 out via $wan setup keep-state
ipfw add 25 allow udp from any to any 53 out via $wan keep-state

# Allow outbound web traffic on WAN(ports 80 and 443)
ipfw add 30 allow tcp from any to any 80 out via $wan keep-state
ipfw add 35 allow tcp from any to any 443 out via $wan keep-state

# Allow outbound ping
ipfw add 40 allow icmp from any to any out via $wan keep-state

# Allow established connections
ipfw add 45 allow tcp from any to any established



rc.conf:
Code:
ifconfig_igc0="DHCP"
ifconfig_ue0="inet 192.168.100.1 netmask 255.255.255.0"
gatway_enable="YES"                 # Enable ip-routing between interfaces
firewall_enable="YES"               # Enable ipfw firewall
firewall_script="/etc/ipfw.rules"   # Path to ipfw rules script
firewall_logging="YES"              # Enable logging
natd_enable="YES"                   # Enable the natd daemon
natd_interface="igc0"               # NAT on WAN(igc0)
natd_program="/sbin/natd"           # Path to nat deamon
 
Last edited by a moderator:
Not very good with ipfw(8) but the best tool to debug situations like this is tcpdump(1). That allows you to look at the packets on the wire, instead of trying to guess what's going on.
 
Ok thx.
I used a rule like :
ipfw add 60000 deny log all from any to any

And read the /var/log/security and It showed:
deny UDP 8.8.8.8:53 192.168.100.100:56002 in via igc0 <---- igc0 = WAN

This means that the statefulleness of the outbound rules on port 53 for udp does not work?Or do I have the wrong rule order?
 
You keep-state after NAT. So on the outgoing request, what gets stateful is the IP addresses after NAT has translated them.
With the reply coming in, you again keepstate (that is, now, check the stateful rules) after NAT, which now already has translated the addresses back into the internal lan representation.
So, the addresses are not necessarily the same and the statefulness may not work.

Statefulness and NAT together is a pain. You may need to separate incoming and outgoing handling with branches (skipto). You should not use "via", but instead use explicit "recv" and "xmit", because "via" can be both, and that can have weird effects.
Then, if you do keepstate outgoing after NAT, you need to checkstate incoming before NAT, to have the same addresses. Or the other way round. That means you cannot use allow on the keepstate, because the checkstate will always do the very same action as the keepstate did,
and that doesn't make sense if the other one happens before the NAT. Also, a successful checkstate (that is not "allow") will then jump to the rule right after the originating keepstate and resume execution there. You may try to use record-state (which is a keep-state without implied check-state) to unmangle things a bit.

Over all, putting this together to something working is about as much fun as solving a magic-cube. ;)

That is why I built a machine that does it automated (https://flowm.daemon.contact)
If I put your interfaces and only the DNS-UDP flow into the machine, it creates these - that would be a working example how it can be done (but only a quick draft, there is still a lot of refinery to add - and this needs net.inet.ip.fw.one_pass=0 ).


Code:
/sbin/ipfw add 10 set 1 reass proto all in
/sbin/ipfw add 20 set 1 unreach6 admin-prohib log proto ip6 ext6hdr frag in
/sbin/ipfw add 30 set 1 count untag 65534 proto all
/sbin/ipfw add 40 set 1 skipto 360 proto all out
/sbin/ipfw add 50 set 1 skipto 130 proto all not recv ue0
/sbin/ipfw add 60 set 1 count proto all
/sbin/ipfw add 70 set 1 count proto all  // 'Interface ue0 IN'
/sbin/ipfw add 80 set 1 count proto all
/sbin/ipfw add 90 set 1 call 65524 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 100 set 1 allow proto all src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 110 set 1 unreach filter-prohib log proto ip4  // 'init END ue0'
/sbin/ipfw add 120 set 1 unreach6 admin-prohib log proto ip6  // 'init END ue0'
/sbin/ipfw add 130 set 1 skipto 340 proto all not recv igc0
/sbin/ipfw add 140 set 1 count proto all
/sbin/ipfw add 150 set 1 count proto all  // 'Interface igc0 IN'
/sbin/ipfw add 160 set 1 count proto all
/sbin/ipfw add 170 set 1 call 200 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 180 set 1 skipto 240 proto all not src-ip me not src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 190 set 1 skipto 220 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 200 set 1 check-state :f1r  // 'DNS-UDP[1]'
/sbin/ipfw add 210 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 220 set 1 unreach filter-prohib log proto ip4  // 'init END igc0'
/sbin/ipfw add 230 set 1 unreach6 admin-prohib log proto ip6  // 'init END igc0'
/sbin/ipfw add 240 set 1 count untag 65534 proto all tagged 65534  // 'wan[FILTER]'
/sbin/ipfw add 250 set 1 divert 8668 proto all  // 'wan[FILTER][NAT]'
/sbin/ipfw add 260 set 1 skipto 270 proto all  // 'wan[FILTER]'
/sbin/ipfw add 270 set 1 call 300 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 280 set 1 allow proto all not src-ip me not src-ip 192.168.100.0/24 dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 290 set 1 skipto 320 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 300 set 1 check-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 310 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 320 set 1 unreach filter-prohib log proto ip4  // 'post END igc0'
/sbin/ipfw add 330 set 1 unreach6 admin-prohib log proto ip6  // 'post END igc0'
/sbin/ipfw add 340 set 1 unreach filter-prohib log proto ip4
/sbin/ipfw add 350 set 1 unreach6 admin-prohib log proto ip6
/sbin/ipfw add 360 set 1 skipto 590 proto all not xmit igc0
/sbin/ipfw add 370 set 1 count proto all
/sbin/ipfw add 380 set 1 count proto all  // 'Interface igc0 OUT'
/sbin/ipfw add 390 set 1 count proto all
/sbin/ipfw add 400 set 1 call 460 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 410 set 1 skipto 430 proto all src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 420 set 1 skipto 520 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 430 set 1 count untag 65534 proto all tagged 65534  // '[FILTER] DNS-UDP[1]'
/sbin/ipfw add 440 set 1 divert 8668 proto all  // '[FILTER][NAT] DNS-UDP[1]'
/sbin/ipfw add 450 set 1 skipto 480 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 460 set 1 check-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 470 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 480 set 1 call 65494 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 490 set 1 allow proto all not src-ip me not src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 500 set 1 unreach filter-prohib log proto ip4  // 'DNS-UDP[1]'
/sbin/ipfw add 510 set 1 unreach6 admin-prohib log proto ip6  // 'DNS-UDP[1]'
/sbin/ipfw add 520 set 1 unreach filter-prohib log proto ip4  // 'init END igc0'
/sbin/ipfw add 530 set 1 unreach6 admin-prohib log proto ip6  // 'init END igc0'
/sbin/ipfw add 540 set 1 count untag 65534 proto all tagged 65534  // 'wan[FILTER]'
/sbin/ipfw add 550 set 1 divert 8668 proto all  // 'wan[FILTER][NAT]'
/sbin/ipfw add 560 set 1 skipto 570 proto all  // 'wan[FILTER]'
/sbin/ipfw add 570 set 1 unreach filter-prohib log proto ip4  // 'post END igc0'
/sbin/ipfw add 580 set 1 unreach6 admin-prohib log proto ip6  // 'post END igc0'
/sbin/ipfw add 590 set 1 skipto 700 proto all not xmit ue0
/sbin/ipfw add 600 set 1 count proto all
/sbin/ipfw add 610 set 1 count proto all  // 'Interface ue0 OUT'
/sbin/ipfw add 620 set 1 count proto all
/sbin/ipfw add 630 set 1 call 660 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 640 set 1 allow proto all not src-ip me not src-ip 192.168.100.0/24 dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 650 set 1 skipto 680 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 660 set 1 check-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 670 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 680 set 1 unreach filter-prohib log proto ip4  // 'init END ue0'
/sbin/ipfw add 690 set 1 unreach6 admin-prohib log proto ip6  // 'init END ue0'
/sbin/ipfw add 700 set 1 unreach filter-prohib log proto ip4
/sbin/ipfw add 710 set 1 unreach6 admin-prohib log proto ip6
/sbin/ipfw add 65484 set 1 return proto all
/sbin/ipfw add 65494 set 1 count tag 65534 proto udp dst-port 53 not src-ip me not src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 keep-state :f1r  // 'DNS-UDP[1]'
/sbin/ipfw add 65504 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 65514 set 1 return proto all
/sbin/ipfw add 65524 set 1 count tag 65534 proto udp dst-port 53 src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 keep-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 65534 set 1 return proto all  // 'DNS-UDP[1]'
 
You keep-state after NAT. So on the outgoing request, what gets stateful is the IP addresses after NAT has translated them.
With the reply coming in, you again keepstate (that is, now, check the stateful rules) after NAT, which now already has translated the addresses back into the internal lan representation.
So, the addresses are not necessarily the same and the statefulness may not work.

Statefulness and NAT together is a pain. You may need to separate incoming and outgoing handling with branches (skipto). You should not use "via", but instead use explicit "recv" and "xmit", because "via" can be both, and that can have weird effects.
Then, if you do keepstate outgoing after NAT, you need to checkstate incoming before NAT, to have the same addresses. Or the other way round. That means you cannot use allow on the keepstate, because the checkstate will always do the very same action as the keepstate did,
and that doesn't make sense if the other one happens before the NAT. Also, a successful checkstate (that is not "allow") will then jump to the rule right after the originating keepstate and resume execution there. You may try to use record-state (which is a keep-state without implied check-state) to unmangle things a bit.

Over all, putting this together to something working is about as much fun as solving a magic-cube. ;)

That is why I built a machine that does it automated (https://flowm.daemon.contact)
If I put your interfaces and only the DNS-UDP flow into the machine, it creates these - that would be a working example how it can be done (but only a quick draft, there is still a lot of refinery to add - and this needs net.inet.ip.fw.one_pass=0 ).


Code:
/sbin/ipfw add 10 set 1 reass proto all in
/sbin/ipfw add 20 set 1 unreach6 admin-prohib log proto ip6 ext6hdr frag in
/sbin/ipfw add 30 set 1 count untag 65534 proto all
/sbin/ipfw add 40 set 1 skipto 360 proto all out
/sbin/ipfw add 50 set 1 skipto 130 proto all not recv ue0
/sbin/ipfw add 60 set 1 count proto all
/sbin/ipfw add 70 set 1 count proto all  // 'Interface ue0 IN'
/sbin/ipfw add 80 set 1 count proto all
/sbin/ipfw add 90 set 1 call 65524 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 100 set 1 allow proto all src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 110 set 1 unreach filter-prohib log proto ip4  // 'init END ue0'
/sbin/ipfw add 120 set 1 unreach6 admin-prohib log proto ip6  // 'init END ue0'
/sbin/ipfw add 130 set 1 skipto 340 proto all not recv igc0
/sbin/ipfw add 140 set 1 count proto all
/sbin/ipfw add 150 set 1 count proto all  // 'Interface igc0 IN'
/sbin/ipfw add 160 set 1 count proto all
/sbin/ipfw add 170 set 1 call 200 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 180 set 1 skipto 240 proto all not src-ip me not src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 190 set 1 skipto 220 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 200 set 1 check-state :f1r  // 'DNS-UDP[1]'
/sbin/ipfw add 210 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 220 set 1 unreach filter-prohib log proto ip4  // 'init END igc0'
/sbin/ipfw add 230 set 1 unreach6 admin-prohib log proto ip6  // 'init END igc0'
/sbin/ipfw add 240 set 1 count untag 65534 proto all tagged 65534  // 'wan[FILTER]'
/sbin/ipfw add 250 set 1 divert 8668 proto all  // 'wan[FILTER][NAT]'
/sbin/ipfw add 260 set 1 skipto 270 proto all  // 'wan[FILTER]'
/sbin/ipfw add 270 set 1 call 300 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 280 set 1 allow proto all not src-ip me not src-ip 192.168.100.0/24 dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 290 set 1 skipto 320 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 300 set 1 check-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 310 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 320 set 1 unreach filter-prohib log proto ip4  // 'post END igc0'
/sbin/ipfw add 330 set 1 unreach6 admin-prohib log proto ip6  // 'post END igc0'
/sbin/ipfw add 340 set 1 unreach filter-prohib log proto ip4
/sbin/ipfw add 350 set 1 unreach6 admin-prohib log proto ip6
/sbin/ipfw add 360 set 1 skipto 590 proto all not xmit igc0
/sbin/ipfw add 370 set 1 count proto all
/sbin/ipfw add 380 set 1 count proto all  // 'Interface igc0 OUT'
/sbin/ipfw add 390 set 1 count proto all
/sbin/ipfw add 400 set 1 call 460 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 410 set 1 skipto 430 proto all src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 420 set 1 skipto 520 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 430 set 1 count untag 65534 proto all tagged 65534  // '[FILTER] DNS-UDP[1]'
/sbin/ipfw add 440 set 1 divert 8668 proto all  // '[FILTER][NAT] DNS-UDP[1]'
/sbin/ipfw add 450 set 1 skipto 480 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 460 set 1 check-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 470 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 480 set 1 call 65494 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 490 set 1 allow proto all not src-ip me not src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 500 set 1 unreach filter-prohib log proto ip4  // 'DNS-UDP[1]'
/sbin/ipfw add 510 set 1 unreach6 admin-prohib log proto ip6  // 'DNS-UDP[1]'
/sbin/ipfw add 520 set 1 unreach filter-prohib log proto ip4  // 'init END igc0'
/sbin/ipfw add 530 set 1 unreach6 admin-prohib log proto ip6  // 'init END igc0'
/sbin/ipfw add 540 set 1 count untag 65534 proto all tagged 65534  // 'wan[FILTER]'
/sbin/ipfw add 550 set 1 divert 8668 proto all  // 'wan[FILTER][NAT]'
/sbin/ipfw add 560 set 1 skipto 570 proto all  // 'wan[FILTER]'
/sbin/ipfw add 570 set 1 unreach filter-prohib log proto ip4  // 'post END igc0'
/sbin/ipfw add 580 set 1 unreach6 admin-prohib log proto ip6  // 'post END igc0'
/sbin/ipfw add 590 set 1 skipto 700 proto all not xmit ue0
/sbin/ipfw add 600 set 1 count proto all
/sbin/ipfw add 610 set 1 count proto all  // 'Interface ue0 OUT'
/sbin/ipfw add 620 set 1 count proto all
/sbin/ipfw add 630 set 1 call 660 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 640 set 1 allow proto all not src-ip me not src-ip 192.168.100.0/24 dst-ip 192.168.100.0/24 tagged 65534  // 'DNS-UDP[1]'
/sbin/ipfw add 650 set 1 skipto 680 proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 660 set 1 check-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 670 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 680 set 1 unreach filter-prohib log proto ip4  // 'init END ue0'
/sbin/ipfw add 690 set 1 unreach6 admin-prohib log proto ip6  // 'init END ue0'
/sbin/ipfw add 700 set 1 unreach filter-prohib log proto ip4
/sbin/ipfw add 710 set 1 unreach6 admin-prohib log proto ip6
/sbin/ipfw add 65484 set 1 return proto all
/sbin/ipfw add 65494 set 1 count tag 65534 proto udp dst-port 53 not src-ip me not src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 keep-state :f1r  // 'DNS-UDP[1]'
/sbin/ipfw add 65504 set 1 return proto all  // 'DNS-UDP[1]'
/sbin/ipfw add 65514 set 1 return proto all
/sbin/ipfw add 65524 set 1 count tag 65534 proto udp dst-port 53 src-ip 192.168.100.0/24 not dst-ip me not dst-ip 192.168.100.0/24 keep-state :f1  // 'DNS-UDP[1]'
/sbin/ipfw add 65534 set 1 return proto all  // 'DNS-UDP[1]'

Thanks for the answer.
I think I need to keep my script as simple as possible.It's getting a little complicated :)

I tried adding "check-state" right before the nat rule which got rid of the "deny UDP 8.8.8.8:53 192.168.100.100:56002", but the dns still does not function.

I managed to get full connectivity for windows computer on LAN with the following rule script:


#!/bin/sh

# Flush existing rules
ipfw -f flush

wan=igc0
lan=ue0

# Block all IPv6 traffic
ipfw add 5 drop ip6 from any to any

# Allow all traffic on the LAN
ipfw add 10 allow all from any to any via $lan

# NAT rule for LAN to WAN traffic
ipfw add 15 divert natd ip4 from any to any via $wan

# Allow outbound traffic on WAN
ipfw add 20 allow tcp from any to any out via $wan setup keep-state
ipfw add 25 allow udp from any to any out via $wan keep-state
ipfw add 26 allow udp from 8.8.8.8 53 to 192.168.100.0/24 in via $wan keep-state
ipfw add 27 allow udp from 8.8.4.4 53 to 192.168.100.0/24 in via $wan keep-state

# Allow established connections
ipfw add 30 allow tcp from any to any established

Is this a secure way of letting dns traffic in this way?
Is there a better way to instead adding a statefull outbound rule/s on LAN ??
I tried the "xmit" and "recv" instead of "via" but it did not work strangely.
 
You keep-state after NAT. So on the outgoing request, what gets stateful is the IP addresses after NAT has translated them.
With the reply coming in, you again keepstate (that is, now, check the stateful rules) after NAT, which now already has translated the addresses back into the internal lan representation.

Thanks for this. I've not seen it as well described anywhere; certainly not in ipfw(8) or maybe more importantly, the Handbook.

So, the addresses are not necessarily the same and the statefulness may not work.

Further, unlikely the same and probably would not work?

Statefulness and NAT together is a pain. You may need to separate incoming and outgoing handling with branches (skipto).

Which some handbook examples have used, but without clear explanation. The manpage has good coverage under /PACKET FLOW but you rarely see it used in examples.

You should not use "via", but instead use explicit "recv" and "xmit", because "via" can be both, and that can have weird effects.

Yes, again rarely stressed. The manpage covers that, but in general assumes a high level of TCP/IP comprehension by readers.

For me, ipfw was a natural for an old assembler hacker; it's raw and close to the metal, whereas I perceive - rightly or wrongly - pf() to be more of a higher-level language, where what goes on under the hood, so to speak, is less detailed.

For most people, that's likely a blessing, avoiding issues like these. I wasted too much time suggesting RTFM with ipfw back when freebsd-ipfw@ was still a useful discussion area.

Then, if you do keepstate outgoing after NAT, you need to checkstate incoming before NAT, to have the same addresses. Or the other way round. That means you cannot use allow on the keepstate, because the checkstate will always do the very same action as the keepstate did,
and that doesn't make sense if the other one happens before the NAT. Also, a successful checkstate (that is not "allow") will then jump to the rule right after the originating keepstate and resume execution there.

Again, well described thanks. I've never grokked the 'skipto keep-state' usage until now, when it makes sense.

You may try to use record-state (which is a keep-state without implied check-state) to unmangle things a bit.

I'm too old a dog, and the folks who added that and other refinements failed to clearly document the rationale, IMO, at least for non-wizard users.

I may or not get time to suss out your generated script.

cheers
 
Again, well described thanks. I've never grokked the 'skipto keep-state' usage until now, when it makes sense.
Yepp. That gives a defined behaviour, and it's a more efficient way than my call/return. But for skipto you need a fixed line number as address, and besides having to compute that (which gets complicated with a bunch of uplinks and multiple nat instances), this line number will likely change when modifying the ruleset. So you cannot do inflight reloading without breaking some dynamic sessions.

My approach can reload at any time, and preserve the dynamic state, because these rules only expect a "return", and that is always there.
It's not built for performance, there could be a lot optimizing still done. I just wanted to get it complete and correct (and more or less readable still), so that I can use it for any given configuration without bothering about the individual rules any longer.
 
Is the following IPFW rules script a secure way of enabling dns connectivity for LAN?
Is the rule order correct?

#!/bin/sh

# Flush existing rules
ipfw -f flush

wan=igc0
lan=ue0

# Block all IPv6 traffic
ipfw add 5 drop ip6 from any to any

# Allow all traffic on the LAN
ipfw add 10 allow all from any to any via $lan

# NAT rule for LAN to WAN traffic
ipfw add 15 divert natd ip4 from any to any via $wan

# Allow outbound traffic on WAN
ipfw add 20 allow tcp from any to any out via $wan setup keep-state
ipfw add 25 allow udp from any to any out via $wan keep-state
ipfw add 26 allow udp from 8.8.8.8 53 to 192.168.100.0/24 in via $wan keep-state

# Allow established connections
ipfw add 30 allow tcp from any to any established
 
I have also tried using "skipto" according to the gateway setup at https://www.zenarmor.com/docs/network-security-tutorials/freebsd-firewall-configuration-with-ipfw
without success.

Can anyone see whats wrong in the script below?? Is it something with the natd rule?



#!/bin/sh

# Flush existing rules
ipfw -f flush

wan=igc0
lan=ue0

# Block all IPv6 traffic
ipfw add 5 drop ip6 from any to any

# Allow all traffic on the LAN
ipfw add 10 allow all from any to any via $lan

ipfw add skipto 15 tcp from any to any out xmit $wanif setup keep-state
ipfw add skipto 15 udp from any to any out xmit $wanif keep-state

# NAT rule for LAN to WAN traffic
ipfw add 15 divert natd ip4 from any to any via $wan

# Allow established connections
ipfw add 45 allow tcp from any to any established
 
Can anyone see whats wrong in the script below?? Is it something with the natd rule?

Rather than showing just your scripts, show us the result of running them, with output of:

# ipfw -t show

posted inside a [code] block, where at least 2 issues should become apparent.
 
Rather than showing just your scripts, show us the result of running them, with output of:

# ipfw -t show

posted inside a [code] block, where at least 2 issues should become apparent.
Ok.Here is the output from ipfw -t show :

Code:
00005       0          0    denylog ip6 from any to any
00010       727    46771    allow ip from any to any via ue0
00015       739    46331    divert 8668 ip4 from any to any via igc0
00020        57     4433    allow tcp from any to any established
00110        0         0    skipto 15 tcp any to any out xmit igc0 setup keep-state
00210        0         0    skipto 15 udp any to any out xmit keep-state
65535      686     43922    deny ip from any to any
 
Ok.Here is the output from ipfw -t show :

Code:
00005       0          0    denylog ip6 from any to any
00010       727    46771    allow ip from any to any via ue0
00015       739    46331    divert 8668 ip4 from any to any via igc0
00020        57     4433    allow tcp from any to any established
00110        0         0    skipto 15 tcp any to any out xmit igc0 setup keep-state
00210        0         0    skipto 15 udp any to any out xmit keep-state
65535      686     43922    deny ip from any to any

If you'd used the -t switch, that would have included last-used timestamps. But anyway ...

Rules 110 and 210 were added without rule numbers, so they are numbered 100 (default) after the then highest rule, in this case 10.

Which puts them after rule 15, your skipto target. ipfw will not skip backwards. When using skipto you must ensure the target is higher. Try adding 1000 or so per skipto target.

Also the interface is missing (variable $wanif undefined?) on now rule 210.

ipfw(8) is the only authoritative source for ipfw usage, and /etc/rc.firewall was written by the ipfw developers.

The handbook section still has outright errors and some poor ideas. Most other tutorials (including the one you reference) have blindly copied and perpetuated these historical errors; this goes back over more than a decade.

Refer to PMc's post #4. I don't think I can help further. You may get more help with pf(8).
 
If you'd used the -t switch, that would have included last-used timestamps. But anyway ...

Rules 110 and 210 were added without rule numbers, so they are numbered 100 (default) after the then highest rule, in this case 10.

Which puts them after rule 15, your skipto target. ipfw will not skip backwards. When using skipto you must ensure the target is higher. Try adding 1000 or so per skipto target.

Also the interface is missing (variable $wanif undefined?) on now rule 210.

ipfw(8) is the only authoritative source for ipfw usage, and /etc/rc.firewall was written by the ipfw developers.

The handbook section still has outright errors and some poor ideas. Most other tutorials (including the one you reference) have blindly copied and perpetuated these historical errors; this goes back over more than a decade.

Refer to PMc's post #4. I don't think I can help further. You may get more help with pf(8).

I dont have ssh to the computer so I could not copy and paste.
I have tried specifying skipto rules with high numbers aswell, but doesn't work.
It was just a typo with missing $wan on rule 210.
Difficult firewall :) allright thx anyways
 
For a few years I had an ipfw firewall doing function similar to what you want.

The most helpful advice I can give without spoiling your fun, is this -

You have your ipfw wall setup to let all packets into the lan interface (ue0) and are filtering the nat'd packets on the way out of the wan interface (igc0) I might suggest that is a mistake: It works in an unpredictable manner at best.

Instead, a more workable approach is to filter wan-destined packets at input to your lan interface, then let all the (filtered) nat'd resulting packets out of the wan interface.

And at the lan interface section of your ipfw, remember to send a reject back to your lan hosts for every packet that did not make it through the filter. So those lan hosts find out they could not send that packet, and do not sit and hang forever waiting for replies.
 
Back
Top