Dumb IPFW Question

Ian Smith smithi at nimnet.asn.au
Wed Sep 26 23:08:22 PDT 2007


On Wed, 26 Sep 2007 20:46:29 +0100 Chris Yocum <cyocum at gmail.com> wrote:

 >      Just to explain a bit, I have installed a FreeBSD 6.2 system on a
 > machine to act as a natd router.  I turned on the firewall and set the
 > firewall rule script to the one from the handbook
 > (http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/firewalls-ipfw.html)
 > (Example Ruleset #2 at the bottom).

Despite lots of useful tips, especially regarding stateful rules, there
are a number of problems with some of the information on that page, and
I wouldn't rely on it as a substitute for a thorough study of ipfw(8). 
At the risk of being called on to submit a PR and diff, be particularly
wary of the sections in which the word 'mandatory' appears, and perhaps
compare those rulesets with those in /etc/rc.firewall.  But anyway ..

 >      After some investigation when I could not get www, I discovered
 > that somehow port 53 is blocked even when I explicitly open it.  This
 > happens when I uncomment the rule "# Reject & Log all unauthorized out
 > going connections to the public Internet
 > $cmd 450 deny log all from any to any out via $pif".  So essentially,
 > when I use that line, I loose my DNS and my www will not work anymore.

I see Chuck already caught your use of 'setup' with udp, which was the
immediate problem.  In fact, the ruleset #2 you used as basis has a rule
for TCP port 53 (needed if you need to transfer zone/s with an outside
DNS server) but had entirely omitted UDP 53 (though the earlier examples
included it), which it seems you must have already noticed.

 >      Otherwise, it all works great and I could not be happier.  Thank
 > you in advance for any help that you may be able to provide.  I am
 > sure that it is some small blunder on my part.

One thing lacking in that ruleset is stopping of _outbound_ spoofing of
RFC 1918 etc addresses; refer to the 'simple' section of rc.firewall,
particularly the placement of anti-spoofing rules wrt NATD diversion. 

 > # Dup these lines if your ISP has more than one DNS server

Or use an address list in one rule, like addr1,addr2,addr3

 > # Get the IP addresses from /etc/resolv.conf file
 > $cmd 023 $skip udp from any to <isp dns ip> 53 out via $pif setup keep-state
 > $cmd 024 $skip udp from any to <isp dns ip> 53 out via $pif setup keep-state
 > $cmd 025 $skip udp from any to <isp dns ip> 53 out via $pif setup keep-state

As you've found, dropping 'setup' will make these work.

 > # Allow out ping
 > $cmd 080 $skip icmp from any to any out via $pif keep-state

I'm not sure if this is sufficient to allow icmptypes needed by TCP for
MTU discovery? but I allow these types specifically and not statefully. 
  
 > # Deny all Netbios service. 137=name, 138=datagram, 139=session
 > # Netbios is MS/Windows sharing services.
 > # Block MS/Windows hosts2 name server requests 81
 > $cmd 320 deny tcp from any to any 137 in via $pif
 > $cmd 321 deny tcp from any to any 138 in via $pif
 > $cmd 322 deny tcp from any to any 139 in via $pif
 > $cmd 323 deny tcp from any to any 81  in via $pif

I've noticed other people just copying these rules from this example,
but 137 and 138 are on UDP, not TCP, while 139 is a TCP service.  Still,
unless you wanted to count these individually, the 'deny everything not
specifically allowed' rule will catch these anyhow.  And if you've got
windows boxes NAT'd on the inside you should block these going OUT too.

eg for TCP:
	#% first take out the VAST bulk of TCP bogons / background noise:
	crap="135,139,445,1433,2967,2968,4899,5900"
	crap="${crap},8000,8080,3128"
	${fwadd} deny log $afew tcp from any to any ${crap} in via ${ext_if} setup
	# Reject&Log all other setup of incoming connections from the outside
	${fwadd} deny log $lots tcp from any to any in via ${ext_if} setup
and for UDP:
	#% first cut out most of the heavy duty noise (incl broken insiders)
	junk="137,138,1433,1434"
	junk="${junk},3544"		# XP home calls home? MS ipV6 'Toredo'
	${fwadd} deny udp from any to any ${junk} via ${ext_if}

 > #allow in information from the ISP's DNS
 > $cmd 361 allow udp from <ip dns ip> 53 to any in via $pif keep-state
 > $cmd 362 allow udp from <ip dns ip> 53 to any in via $pif keep-state

These are not useful, since you're using outbound UDP keep-state on 53.
If you're running a public DNS server, you'd need to allow inbound DNS
in from anyone, not (just) your ISP.

HTH, Ian



More information about the freebsd-questions mailing list