It's been a LONG time since I messed with ipfw (OS X) and I've never gotten to play with iptables, so this is me thinking aloud in order to understand these (so I can maybe start writing my own) and hopefully as a baseline for others. Let me know if anything needs fixed.
First off there are 3 main tables.
filter:
This is the default table (if no -t option is passed). It contains the built-in chains INPUT (for packets destined to local sockets), FORWARD (for packets being routed through the box), and OUTPUT (for locally-generated packets).
nat:
This table is consulted when a packet that creates a new connection is encountered. It consists of three built-ins: PREROUTING (for altering packets as soon as they come in), OUTPUT (for altering locally-generated packets before routing), and POSTROUTING (for altering packets as they are about to go out).
mangle:
This table is used for specialized packet alteration. Until kernel 2.4.17 it had two built-in chains: PREROUTING (for altering incoming packets before routing) and OUTPUT (for altering locally-generated packets before routing). Since kernel 2.4.18, three other built-in chains are also supported: INPUT (for packets coming into the box itself), FORWARD (for altering packets being routed through the box), and POSTROUTING (for altering packets as they are about to go out).
On to the code:
Code:
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables -t nat -F
iptables -t mangle -F
Flush the tables.
Flush the table 'nat'.
Delete all chains.
Delete all chains on table 'nat'.
Flush the table 'nat'
-
I think all of these are redundent, wouldn't 1 flush do the same?
-
Code:
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE -o $gateway_interface
On the table (-t) 'nat' append (-A) the rule to the chain 'POSTROUTING' (as in do this stuff after stuff is routed). Only onn the source (-s) 10.0.0.0/24. The jump (-j) to the target 'MASQUERADE' on out bound interface (-o) $gateway_interface.

Originally Posted by
MASQUERADE
This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target. Masquerading is equivalent to specifying a mapping to the IP address of the interface the packet is going out, but also has the effect that connections are forgotten when the interface goes down. This is the correct behavior when the next dialup is unlikely to have the same interface address (and hence any established connections are lost anyway).
.
Code:
iptables -t nat -A PREROUTING -p udp -j DNAT --to $router
On the table 'nat', append the rule to the chain PREROUTING. Only on protocol (-p) udp, jump to the target DNAT and forward to the $router

Originally Posted by
DNAT
This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It specifies that the destination address of the packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined. It takes one type of option:
--to-destination ipaddr[-ipaddr][

ort-port]
which can specify a single new destination IP address, an inclusive range of IP addresses, and optionally, a port range (which is only valid if the rule also specifies -p tcp or -p udp). If no port range is specified, then the destination port will never be modified.
.
So if I'm reading this right. ALL udp requests will get routed properly. Not that it really matters much, but if you were to use a UDP->TCP bridge, you could get through without any problem?
Code:
iptables -t nat -A PREROUTING -m mark --mark 0x42 -j ACCEPT
On the table 'nat', append to the 'PREROUTING' chain. Match (-m) only packets that have the mark (--mark) 0x42. Jump to the target 'ACCEPT' (let the packet through).
iptables -t filter -I FORWARD 1 -m mark --mark 0x42 -j ACCEPT
On the table 'filter', insert the chain "FORWARD". Add the rules at the head of the chain (1). Only on packets that match (-m) the mark (--mark) 0x42. Jump to the target 'ACCEPT'.
Code:
iptables -t nat -A PREROUTING -i at0 -p udp --dport 53 -j ACCEPT
On the table 'nat', append to the chain "Pre Routing" on interface (-i) at0 (Adapter created by airbase) on protocol udp and destination port 53 (DHCP) jump to the target 'accept'. (Let all DHCP requests).
Code:
iptables -t nat -A PREROUTING -i at0 -p tcp --dport 80 -j REDIRECT --to-port 80
Finally... on the table 'nat' and the chain 'prerouting'. On interface at0, protocol tcp port 80. Jump to the target Redirect, redirect to localhost port 80.
And in the code to add a user...
iptables -t mangle -I PREROUTING -m mac --mac-source $MAC -j MARK --set-mark 0x42
To the table 'mangle'. Insert to the chain prerouting (Default is 1, so -I PREROUTING 1 is identical). Match (-m) mac address, with the mac source (--mac-source) $MAC (from the shell script). Jump to the 'MARK' target and set the mark to 0x42.
--
So. How does this all Tie together? IPtables has a short circuit logic, meaning if at any time it gets the 'accept' target, it goes ahead and executes the current chain.
So in the end you will have these chains on each of the tables:
Filter: On the chain Forward, all packets what match the mark of 0x42, accept. (Is this redundent with the nat chain below?)
Mangle: All packets coming in (PreRouting) that match a MAC address, mark them with 0x42.
Nat: All packets that come through prerouting matching mark of 0x42, accept.
Accept all port DHCP requests on in udp on port 53.
Finally, anything that doesn't match above and is coming in on port 80, redirect to local host port 80.
---
Here is a decent writeup (although it's a bit long) hxxp://iptables-tutorial.frozentux.net/iptables-tutorial.html