Hacking Linux Exposed





previous article
next article
Using iptables chains to simplify kernel ACL management.
By Bri Hatch.

Summary: By creating new chains that are called by the INPUT chain, you can easily tweak kernel ACLs without recreating the entire ruleset each time.

When last we left our heroes...

Over the last two newsletters, we've created a simple firewall that prevents any inbound access. We'd like to make it possible to easily allow certain hosts to connect inbound with SSH, eventually making it an automated/dynamic process. This will mean we'll be adding and removing rules a lot, and this can be a pain when all your rules are in one big INPUT chain.

What we'll do is add a new iptables chain called allow_in. In this chain we'll add rules that allow all TCP packets for hosts that should be allowed to connect. To create this chain, you use

  # iptables --new-chain allow_in

We now add this chain to our INPUT chain processing before the SYN packets would normally be dropped. In the firewall ruleset we created, we only had ACCEPT rules with a default DROP at the end, so we should add the following rule just before the end of the rules:

  # iptables -A INPUT -j allow_in

This tells the INPUT chain to process the entries in the new allow_in chain. When this chain in finished processing the rules in INPUT will continue where they left off. Since we don't have any rules in this chain right now, it's not doing much, so let's add a few:

  # iptables -A allow_in -p tcp --source --dport 22 -j ACCEPT
  # iptables -A allow_in -p tcp --source --dport 22 -j ACCEPT

Let's look at the full iptables rules

  # iptables -nL
  Chain INPUT (policy DROP)
  target     prot opt source          destination
  ACCEPT     tcp  --          tcp flags:!0x16/0x02
  ACCEPT     udp  --          udp spt:53
  ACCEPT     udp  --          udp dpt:68
  ACCEPT     icmp --          icmp type 3
  ACCEPT     icmp --          icmp type 4
  ACCEPT     icmp --          icmp type 11
  ACCEPT     icmp --          icmp type 12
  ACCEPT     icmp --          icmp type 5
  ACCEPT     icmp --          icmp type 9
  ACCEPT     icmp --          icmp type 8
  ACCEPT     icmp --          icmp type 0
  allow_in   all  --
  DROP       all  --

Chain FORWARD (policy ACCEPT)
target     prot opt source            destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source            destination

Chain allow_in (1 references)
target     prot opt source            destination
ACCEPT     tcp  --          tcp dpt:22
ACCEPT     tcp  --          tcp dpt:22

So inbound packet processing looks like this:

  • Allow inbound TCP packets that are in response to outbound connections.
  • Allow inbound UDP DNS replies
  • Allow useful ICMP packets.
  • Process the allow_in chain which will
    • Allow SSH from
    • Allow SSH from
  • Log any other packets
  • Drop all packets

Now the nice thing about this setup is that we can manage the allow_in chain separate from the others. The nicest feature is that we can flush this chain without affecting the other rules:

  # iptables -F allow_in

So, the trick now is how exactly do we manage this chain easily? We'd like him to be able to sit down on any random machine that wasn't already in the list and somehow let his computer know that it's him and to allow the machine to SSH in.

Next week I'll show you a DNS sniffing hack that will let us manage this allow_in chain dynamically. It'll be fun, trust me.

Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He always prefers to build a firewall on his own than use a commercial product. He has this expensive Cisco PIX lying around with six tempting Ethernet ports - anyone know how to install Linux on it? Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2003

This is the July 22, 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