SIMPLIFICATIONS Can simplify understanding by skipping anything to do with the following specialized features which we won't use. "mangle" table "raw" table RULES Rules are evaluated in sequence for each packet, beginning with the first rule of a predefined chain. Every examined packet gets passed through: nat/PREROUTING for incoming packets (does DNAT) + ONE filter chain (depending on source and dest) + nat/OUTPUT for locally-generated packets + nat/POSTROUTING for outgoing packets (does SNAT) [EXAMPLES: forwarded does nat/PRE + filter/FOR + nat/POST; local-outgoing does filter/OUTPUT + nat/OUTPUT + nat/POST). If criteria match, the rule's counter is incremented and the -j TARGET (if any) is performed: ACCEPT, DROP, QUEUE, RETURN, LOG, user-defined-chain-in-same-table. (Note that you can't chain to a built-in chain). TARGETS There are many "extension" targets. user-defined-chain-in-same-table: It's possible that we will eventually continue to the next rule (same as if criteria did not match), if the called chain RETURNs. TODO: Test if called-chain having no rule matches is same as it matching a rule with RETURN target. QUEUE: Passes to user-space. Probably not generally useful. RETURN: In built-in chain, executes the chain's default action. LOG: An NON-TERMINATING extension target. DNAT: An extension target which implies ACCEPT Only valid for nat/PREROUTING-, nat/OUTPUT-initiated chains. REDIRECT: DNAT that auto-maps a DNAT addr to primary incoming iface (or 127.0.0.1 for Local-generateds) SNAT: An extension target which implies ACCEPT Only valid for nat/POSTROUTING-initiated chains. MASQUERADE: SNAT that auto-maps a SNAT addr to dynamic IP addr of outgoing iface. I think that "-j MASQUERADE" always effectively implies a pseudo "--to-source...". REJECT: An extension target only for filter table chains. TABLES We are only concerned with the "filter" and "nat" rule tables. BUILT-IN CHAINS table chain ----- ------- filter* INPUT Terminating here filter* OUTPUT Locally-generated outgoing filter* FORWARD Passing-through nat PREROUTING. Changes a packet before any filters. For DNAT. Only invoked for incoming packets (filter/INPUT + filter/FORWARD). nat OUTPUT Locally-generated outgoing before any filters. For DNAT. Just like PREROUTING, but only for locally-generated. nat POSTROUTING Changes a packet after any filters. For ALL SNAT. Only invoked for outgoing (filter/OUTPUT + filter/FORWARD) packs, therefore cannot SNAT incoming traffic destined for firewall. mangle 5 of 'em raw** PREROUTING, OUTPUT * = default, if no -t given ** Pretty safe to assume no rules present iptables [-t table] -* [chain...] [-options] where the principal commands are [-p type|-m module] -h: Help (specific help after general help :( ). -F: Drop rules (n.b. does not reset the -P policy). -P: Set default (non-extension, non-chain) target for a built-in chain -X: Delete empty non-built-in chain (but I see old examples of removing build-ins???) -A: Append a rule -I: Insert a rule (at beginning or at specified linenum) -D: Insert a rule (specified linenum or matching rule) -N: add a New chain -L: List rules and counts -Z: Zero counters There are also commands to add/remove/modify rules at specific positions. Principal options: -v: Verbose -n: Numeric -x: Exact values (for -L count output). --line-numbers: For -L output. (Seems that you used to be able to start like "iptables table..." without the -t?). iptables-batch Binary program. Reads text commands of format: iptables... commit exit Where the iptables are of exact format as normal iptables commands. RULE SYNTAX MOST GENERALLY: iptables [-t ] -A -switches or iptables [-t
] -I -switches (NUM dflts. to 1, top) Can only specify multiple addresses by specifying subnets or with the iprange match extension. Can specify contiguous port ranges with -p tcp|udp with -[sd]port x:y. Otherwise, need the multiport match extension. -p [!]tcp|udp|icpm PROTOCOL. Defaults to "all" May also use a protocol value from /etc/protocols, or numeric. -s [!]hostname|1.2.3.4|1.2.3.4/24|1.2.3.4/255.255.255.0 SOURCE ADDR -d [!]hostname|1.2.3.4|1.2.3.4/24|1.2.3.4/255.255.255.0 DEST ADDR -j TARGET TARGET. By default, rule counter just increments. -g user-defined-chain. Just like -j except the next rule will never be executed. If child chain RETURNs, parent of this chain will resume. (I guess may only be called by user-defined-chain?) -i [!]iface[+] Only for chain runs initiating with filter/INPUT, filter/FORWARD, nat/PREROUTING. + acts like an iface name * glob. -o [!]iface[+] Only for chain runs initiating with filter/FORWARD, filter/OUTPUT, nat/POSTROUTING. + acts like an iface name * glob. [!] -f: Fragment packet other than head packet. WILL SILENTLY FAIL IF PORTS OR ICMP TYPE SPECIFIED. -c packets bytes: Set counter values. MATCH EXTENSIONS I think that the extension-specific switches must always follow the -m or extension target which enables them. -m addrtype --src-type|--dst-type TYPE TYPE of UNICASE, LOCAL, BROADCAST, ANYCAST, MULTICAST, BLACKHOLE, UNREACHABLE, PHOHIBIT, THROW, NAT, XRESOLVE. -m comment --comment 'Any comment' -p icmp... --icmp-type [!]TYPE MANY Types. Use -h for list. Most comonly used: echo-reply, echo-request -m iprange [!] --srcrange|--dst-range ip1-ip2 [!] -m limit [--limit 3/hour] [--limit-burst 5] Matches until lmit is reached. Sample limits here are the defaults. I think that --limit-burst is the limit within the --limit limit. -m mac --mac-source [!]XX:YY:ZZ:AA:BB:CC Only for eth chain runs initiating with filter/INPUT, filter/FORWARD, nat/PREROUTING. -p tcp|udp -m multiport --sport[s]|--dport[s]|--port[s] [!] port[,:...] -p tcp|udp --sport|--dport [!] port[:...] -p tcp --tcp-flags [!] TO,EXAMINE POSITIVE,LIST (non-positive must not be set) Flags: SYN ACK FIN RST URG PSH ALL NONE Nb. [!] --syn == --tcp-flags SYN,RST,ACK,FIN SYN. This matches requests for TCP connections. -m pkttype --pkt-type unicast|broadcast|multicast] Link-layer packet type. -m policy... For IPsec. -m quota --quota types Uses a decrementing quota counter. -m state --state INVALID|ESTABLISHED|NEW|RELATEED. Connection state. -t nat -j DNAT|REDIRECT --random OR -t nat -j DNAT --to-destination [ipaddr] OR -t nat -p tcp|udp -j DNAT --to-destination [ipaddr][:port] -t nat -p tcp|udp -j REDIRECT --to-ports port THESE ONLY VALID FOR nat/PREROUTING-, nat/OUTPUT-initiated chains. I think implies ACCEPT (I think for this and all future rule matches). -j LOG --log-level SYSLOG_LEVEL --log-prefix PREFIX Non-terminating target! Remember to add some whitespace at end of PREFIX if you want some! -t nat --random -j SNAT|MASQUERADE OR -t nat --to-source [ipaddr] -j SNAT OR -t nat -tcp|udp --to-source [ipaddr][:port] -j SNAT -t nat -tcp|udp --to-port port -j MASQUERADE THESE ONLY VALID FOR nat/POSTROUTING-initiated chains. I think implies ACCEPT (I think for this and all future rule matches). (Can't NAT to or from a RANGE of addrs w/ recent Kernels. TODO Test if this means any means of multiple addrs.) --reject-with tcp-reset -j REJECT Override default reject type of port-unreaclable. Only for filter table. DYNAMICALLY CHANGING RULES based on DNS changes: http://dave.thehorners.com/tech-talk/unix-linux-bsd-osx-etc/86-iptables-a-real-mans-firewall TO BLOCK A PC iptables -L FORWARD -n --line-num iptables -I FORWARD 3 -s 192.168.101.24 ! -d 192.18.101.0/24 -j DROP iptables -I FORWARD 1 -s 192.168.101.24 -p tcp --dport 443 -j ACCEPT iptables -I FORWARD 1 -s 192.168.101.24 -p tcp --dport 80 -j ACCEPT To delete those rules... iptables -D FORWARD 1 SIMPLE INCOMING DNAT FORWARING from firewall Per https://www.linuxtopia.org/Linux_Firewall_iptables/x4013.html (I'm neglecting access attempts from firewall itself, which I won't do). iptables -t nat -A PREROUTING --dst -p tcp --dport -j DNAT --to-destination iptables -t nat -A POSTROUTING -p tcp --dst --dport -j SNAT --to-source To delete: #delete-by-line-number is just not working, so #iptables -D PREROUTING -i I can't get this to work either. WTF!