Tip of the Trade: m0n0wall
Ed. Note: This article has been revised to correct information about M0n0wall's relation to OpenBSD PF. Packet filtering need not be complicated. For both power and ease of use, consider a BSD-based packet filer, like ipfilter. When coupled with m0n0wall, a specialized implementation of FreeBSD + ipfilter designed for routers and firewalls, it is even easier to use.
Iptables usually gloms all the glory, since it is the packet filter included in the Linux kernel. But there is an alternative worth considering that is at least equally powerful and easier to use: ipfilter. ipfilter runs on most Unix variants, and the easiest way to get acquainted with it is by running m0n0wall.
m0n0wall is a specialized implementation of FreeBSD designed for routers and firewalls. It weighs in at well under 10 megabytes, but you still get a complete operating system, firewall, Web administration, traffic shaping, DNS server, DHCP server, SNMP, support for DynDNS updates and a whole lot more. m0n0wall offers a nice pointy-clicky interface for setting up a stout ipfilter firewall. For ultimate power, however, you really want to know how to write rules from scratch.
ipfilter rule syntax is not like iptables rules, which look like they came from the mind of a demented programmer. Instead, they are closer to natural language. This example is the unrestricted rules for the localhost (lo) interface:
pass in quick on lo0 all pass out quick on lo0 all
block in all
block in quick all
pass in inet proto icmp all icmp-type $icmp_types keep state
block in quick from 18.104.22.168/28 to any pass in all
pass in on $ext_if inet proto tcp from any to $webserver port = 80 keep state