Hacking Linux Exposed





previous article
next article
Egress filtering for a healthier Internet.
By Bri Hatch.

Summary: Security is not just protecting yourself from others, you must protect others from yourself. Egress filtering is an important part of any firewall setup.

The Slammer/Sapphire/etc worm really ruined my Internet experience for a few days. Yes, patches were available. Yes, people should have blocked inbound access to their windows boxes when not needed. These and many other explanations about what could have been done were discussed all over. However one thing that seems to have been overlooked in many sources is that it was the outbound packets that were killing us, and we shouldn't have been subject to them at all.

We are used to thinking of security as a defensive battle: keep the bad guys out of our systems. We set up our firewalls to block known attacks, block any inbound packets that don't go to permitted ports, restrict inbound packets from untrusted sources, keep spam out by blocking connections from machines on DNSBLs[1]. These are all defensive barriers we erect in front of our servers to keep the bad guys out.

The problem is that sooner or later there will be a breach of those barriers. Perhaps a bug exists in one of the services that you do need to permit. Perhaps your firewall rules were too weak. The problem is that once you are cracked, the cracker is on the inside of the firewall, and is uninhibited by your inbound rulesets.

Blocking inappropriate inbound access is a very good and necessary thing. However people need to start blocking inappropriate outbound access too. If your machine is just a mail server, then it needs to be able to send out packets from and to port 25, but it doesn't need to be able to make an HTTP connection. If you run a DNS server, it doesn't need to be able to support outbound FTP. And for goodness sake, if your network is w.x.y.z, packets from other addresses should never leave your boarders.

When your computer is compromised, you are no longer the innocent party trying to defend yourself, to other machines you have become the attacker. You owe it to others to make outbound attacks more difficult to the cracker or worms that have managed to get onto your machine.

Outbound packet security is called egress filtering. It's no harder to implement than the ingress filtering rules you should already have. Had the Slammer hosts been behind firewalls with proper egress filters, the outbound attacks would never have passed through their firewall/router.

As always, the best rule when creating firewalls/access lists is to list those packets which should be allowed and deny the rest. Be very restrictive! Better to break a few applications during testing than to leave holes open. If you have a completely new network, it is easy to block everything and open ports as needed. if you have an existing network, you should run a sniffer, logging the type of network activity you experience currently, and then create your rules to match them.[2]

So, let's take an example of the following server. We'll create both ingress and egress filters such that it does exactly what it needs, and no more.

Our sample machine runs Apache, Postfix, and allows inbound SSH access from the local network only. It needs to be able to look up DNS entries for it's Apache logfiles and to support a few DNSBL lists for preventing inbound spam. Here are the iptables rules you'd create on this host to support this configuration:


  # Define a few variables for ease of use


  # This machine makes all DNS requests to a single
  # DNS server, rather than asking the roots directly.

  # Set the policy to be DROP.  In other words, should a packet
  # not match any rule, it will be dropped by default.  We'll
  # put this before the flush to make sure that while this script
  # runs, we are secure by default.
  iptables -P INPUT DROP
  iptables -P OUTPUT DROP
  # Flush all tables.
  iptables -F
  iptables -F INPUT
  iptables -F OUTPUT
  # Let's allow all packets on the local (127.1) network interface.
  iptables -A INPUT -i lo -j ACCEPT
  iptables -A OUTPUT -o lo -j ACCEPT
  # Drop all inbound packets that claim to be from us..
  iptables -A INPUT -i $ETHERNET -s $MYIP -j DROP
  # Drop all outbound packets that claim not to be from us.
  iptables -A OUTPUT -o $ETHERNET -s ! $MYIP -j DROP
  # Block inbound from RFC1918 networks
  iptables -A INPUT -i $ETHERNET -s -j DROP
  # Add other such rules here to block 172.16/12, 192.168./16
  # and other networks, multicast, and flag settings that you
  # should not expect from legitimate traffic.
  # Remember, this example is to show egress filtering, not a
  # full firewall implementation.

  # Allow inbound HTTP from everywhere
  iptables -A INPUT  -i $ETHERNET -p tcp -d $MYIP --dport 80 -j ACCEPT
  iptables -A OUTPUT -o $ETHERNET -p tcp -s $MYIP --sport 80 ! --syn -j ACCEPT
  # Allow inbound SSH from local network
  iptables -A INPUT  -i $ETHERNET -p tcp -d $MYIP --dport 22 -s $MYNET -j ACCEPT
  iptables -A OUTPUT -o $ETHERNET -p tcp -s $MYIP --sport 22 -d $MYNET ! --syn -j ACCEPT

  # Allow outbound DNS to our nameserver[3]

  iptables -A OUTPUT -o $ETHERNET -p udp -s $MYIP --dport 53 -d $DNSSERVER -j ACCEPT
  iptables -A INPUT  -i $ETHERNET -p udp -d $MYIP --sport 53 -s $DNSSERVER -j ACCEPT
  # Log any rejects to syslog so we can debug
  iptables -A INPUT -j LOG
  iptables -A OUTPUT -j LOG

Many firewalls simply create rules on the INPUT chain. The OUTPUT rules above comprise our egress filters. As you can see, an egress filter will usually look pretty close to an ingress filter, so generating them is pretty simple, just reverse the -d / --dport (destination address / destination port) and -s / --sport (source address / source port) arguments. I like to include ! --syn where appropriate to prevent the initial packet of the TCP three way handshake, just to be verbose.

The above code is by no means a complete firewall. You'll want to include changes to some /proc entries[4], drop source routed packets and packets from the non-routable RFC-1918 networks, include some NAT or connection tracking modules, etc. I heartily recommend "Linux Firewalls, Second Edition" by Bob Ziegler - it has excellent iptables and ipchains info and sample configurations.

You can implement egress filtering on both the host itself, and on your firewalls. To protect those Windows boxes on your network, the firewall may be the only appropriate place. If a cracker gets onto your machine, rather than an automated worm, he/she would be able to undo your iptables rules quite easily, so it's always a good idea to include rules on the firewall as well.

The one thing I'd like you to take away from this article is that egress filtering is a good thing. Here are just a few reasons:

  • You won't be a source of attacks, and will thus be less likely to be blackholed as a bad netizen, or break the AUP of your ISP.

  • You're less likely to need to admit you were broken into. (Image is important for big companies.)

  • Most attacks use TCP, and if you drop the outgoing SYN packet, you'll never establish the session, and the drain on your network will be minimal.

  • You're more likely to find when an attacker is calling out to get his/her tools, or prevent them altogether.

  • You're more likely to see when an upgrade of your software changes it's network requirements in a way you don't like.

  • You'll find when internal users are acting differently than you expect.

  • You'll keep spyware and other software from 'calling home'
Many of the firewall-creation scripts you find on the Internet do include egress filtering as well. If you are using one that does not, you can modify it to do so fairly easily. Or you can look for one that was designed with more paranoia from the beginning.


[1] A DNSBL is a DNS-based black hole list. Many of these exist, listing machines that list open relays, known spam sources, etc.

[2] Be sure to validate the existing activity -- if there is unnecessary or unaccounted for traffic, see what's causing it at the source.

[3] Yes, this does not handle TCP responses. Some days I subscribe to the DJB school of DNS.

[4] You may want to see a previous article about /proc at http://www.hackinglinuxexposed.com/articles/20021015.html for example.

Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He loves to watch as unscrupulous software on his fiance's laptop tries to do things we wouldn't like. He should really limit the hours of the day when the log monitoring software pages him about it though. Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2003

This is the February 13, 2003 issue of the Linux Security: Tips, Tricks, and Hackery newsletter. If you wish to subscribe, visit http://lists.onsight.com/ or send email to Linux_Security-request@lists.onsight.com.

previous article
next article