Because I had to learn ipfwadm and then ipchains I've procrastinated learning iptables because it pissed me off that I had to relearn the Linux firewalling tool every other year. So now as I have to deal with CaptivePortal's and NoCatAuth it's about time I finally came to terms with it. Here are some notes to help me not have to read the damn howto's or man pages.
See also: CommandLine
Basics
Iptables is basically an extension of ipchains, in the sense that a single table may contain multiple chains.
- All table, chain and policy names are case sensitive so "ACCEPT" isn't the same as "accept".
There are three default tables called filter, nat and mangle (if you don't specify a table on the CommandLine it uses the filter table by default).
- Each chain has a default policy of ACCEPT (let packets flow), DROP (deny packets), QUEUE (hand over to userspace) or RETURN (stop and jump to the next chain).
Viewing Data
- iptables -t (filter|nat|mangle) ...
- Specify that you want your changes to apply to a specific table.
- iptables -t nat -L -n -v
- View any rules inside of the nat table ("-n" means don't resolve IP's to host names and speeds it up significantly).
- iptables -t nat -P OUTPUT ACCEPT
- Set the default policy of the OUTPUT chain in the nat table to ACCEPT.
- watch iptables -t nat -L -n -v
- View a constantly refresing view of the nat table (poor mans firewall monitor).
- iptables -t nat -Z
- Reset any counters in the nat table to zero.
Adding and Removing Rules
- iptables -A INPUT --protocol tcp --dport 22 -s "192.168.0.0/16" -j LOG
- Log all SSH connections (port 22) from the 192.168.*.* subnet.
- iptables -A INPUT --protocol tcp --dport 22 -s "192.168.0.0/16" -j DROP
- Drop all packets from 192.168.*.* which arrive on port 22 (ssh).
NAT and Masquerading
Assuming eth0 is the interface facing the world and eth1 is the interface on the inside.
- sysctl -w net.ipv4.ip_forward=1
This enables forwarding in the kernel, and is required for NAT to work. On old Linux systems without sysctl you can achieve the same effect using echo "1" > /proc/sys/net/ipv4/ip_forward. To make this setting persistant between reboots you need to edit /etc/sysctl.conf.
- iptables -F -t nat; iptables -F -t filter
- Clears any rules that might already exist in the nat or filter tables. It's a good idea to make sure you start with a fresh slate when trying new rules.
- iptables -t nat -A POSTROUTING -s eth1 -j MASQUERADE
- This configures masqerading for internal machines to the world.
- iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source w.x.y.z
- Where w.x.y.z is the IP address of eth0. This rewrites packets going to the world to have a source IP of w.x.y.z. Source NAT is an alternative to masquerading, I'm not sure what the pro's and con's are but it seems to do much the same thing.
Port Forwarding
If you have the above NAT setup, you can forward connections to a port on your gateway box to an internal box. This could be useful if you wanted your web server to be inside your gateway but be reachable externally.
- iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.10:80
- This forwards TCP connections on port 80 from your gateway/firewall box to port 80 of your web server (192.168.1.10).
- iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT
- If you have a default policy in the filter table of DROP then you need to add a manual filter rule to allow the port forwarding (if you default policy is ACCEPT you do not need this rule).
Making Rules Persistant
Once you have your desired firewall configuration you want to make sure that any changes you make are saved and that they become effective again on a reboot.
- iptables-save -c > /root/rc.iptables
- This saves the current state of your firewall rules to a file. The -c tells it to also save the packet counters associated with any rules (very useful if you use iptables for traffic monitoring).
- iptables-restore -c < /root/rc.iptables
- This flushes any existing rules and restores the saved rules making them active, -c tells it to start any counters at the saved values.
Note that RedhatLinux automates this process with the /etc/init.d/iptables by writing your firewall rules to /etc/sysconfig/iptables on shutdown and restoring on reboot. On other systems you will need to write your own script.