Before you read anything else, make sure you have read and understood HowFirewallingWorks. This tells you about iptables(8) and gives some examples.

If you need a decent iptables FireWall for your Linux box, you probably want to give PerrysFirewallingScript a try.

There are LinuxDistributions that exist only to provide firewalling; PerryLorier is working on a FireWall-on-a-disc system. You can technically speaking shut a Linux machine down into Kernel-only mode and still be running a FireWall.

Adding a rule

To create a rule that will send back an ICMP message, use

iptables -A chain [...] --jump REJECT --reject-with icmp-port-unreachable

The type corresponds to an ICMP error and can be one of:

  • icmp-net-unreachable
  • icmp-host-unreachable
  • icmp-port-unreachable (default)
  • icmp-proto-unreachable
  • icmp-net-prohibited
  • icmp-host-prohibited

Deleting a rule

iptables -D chain [rule number]
iptables -D chain [rule description]

Hint: if you want to delete a rule and you don't want to have to mess around with specifying ports etc, try iptables -L --line-numbers. Then you can just use iptables -D FORWARD 1 to remove it.

Deleting all rules

iptables [-t <table>] -F [chain]

This removes all rules from the specified table and chain, or all the chains in the table if none is specified.

Hint: It won't delete any user-defined chains, although it will remove the rules within them, nor will it set the default policy for the table. This, though, should:

iptables -t filter -F
iptables -t filter -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t filter -P INPUT ACCEPT
iptables -t filter -P FORWARD ACCEPT
iptables -t filter -P OUTPUT ACCEPT
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P INPUT ACCEPT
iptables -t mangle -P FORWARD ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
iptables -t mangle -P POSTROUTING ACCEPT

Hints, tips and traps

  • Having a default DENY or REJECT policy is a good idea. Don't start with that rule if you're working remotely, though...
  • DENY might sound nice, but it means people can spoof packets from your computer, and your computer won't abort the connection. A rate limited REJECT (using -m limit) is much much safer.
  • You probably want to rate limit log messages too. Otherwise a good portscan can flood syslogd(8) for ages.
  • If you are having problems using -m owner with iptables 1.2.6a and Kernel 2.4.x see IptablesNotes
  • For those stupid places that don't support packet fragmentation (like some online banking sites a while back):

    iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

    Make sure it's the first thing in the FORWARD chain on your router, or in the OUTPUT chain if you use one of those hardware DSL router boxes.


If you have a FireWall running iptables, chances are you'll want to forward a port at some point (to run a P2P app, a game server etc).

Experiment with this command line, substituting the emphasized bits according to your needs:

iptables -t nat -A PREROUTING -i ppp0 -j DNAT -p tcp --to= --dport 4661

Can't access the NZ Herald or other sites?

Make sure you have ECN (Explicit Congestion Notification) disabled and don't have any TypeOfService settings in your FireWall script. If you know what you're doing, try iptables -t mangle -F PREROUTING which should clean up any of them.

Alternatively, you can go with the Don't fix good science to work with a bad implementation, or manually add rules allowing access to the NZ Herald IPs.

Also, it should be noted that some home routers don't seem to like ECNs either. If you're having problems accessing the InterNet with a home ADSL router, and tcpdump(8) output is mentioning packets with SWE?, try turning ECNs off as seen in the ECN page.

Multiple people behind a firewall can't make PPTP connections simultaneously

Have a NAT FireWall that only allows one person behind it to make a VPN connection at once? See PPTPConnectionTracking

Run non-root processes on ports below 1024

If you want to be able to run a process that responds to requests on a Port below 1024 without running it as the SuperUser, a simple approach is to have it bind to some port above 1024, then configure a lower layer in the NetworkStack to do the legwork. On Linux, a convenient way to achieve this is by using iptables(8):

iptables --table nat -A PREROUTING -p tcp --dport $external_port -i eth0 -j REDIRECT --to-ports $local_port

This way, you could have a process bind to port 8080 locally, but have it appear to outsiders as though it was listening on port 80.

Part of CategoryNetworking and CategorySecurity