iptables中定义的表,分别表示提供的功能,有filter表(实现包过滤, deny, drop etc)、nat表(实现网络地址转换)、mangle表(实现包修改)、raw表(实现数据跟踪),这些表具有一定的优先级, table priority is fixed at each Hook point.
raw–>mangle–>nat–>filter
Inside each table, rules are executed by order one by one
insert (head)
append (tail)
iptables command
iptables [-t 表] [操作命令] [链] [规则匹配器] [-j 目标动作]
Table
Operation
Condition
Target:
ACCEPT will terminate rule matching in the same table? REJECT, DROP will terminate all, stop here. one more target: 用户自定义的链名:跳转到这条链下,进行匹配
# Please NOTE this may not show all rules!!! as user may create custom chain like docker does # show all rules at DOCKER chain(can be used as target) $ iptables -nv -L PREROUTING -t nat Chain PREROUTING (policy ACCEPT 24 packets, 2840 bytes) pkts bytes target prot opt in out source destination 6 272 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}...";iptables -nvL DOCKER -t $table;done
# show all rules at PREROUTING chain $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -nvL PREROUTING -t $table;done # show command used by iptable to add the rule $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -S PREROUTING -t $table;done
# show all rules at INPUT chain $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -nvL INPUT -t $table;done $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -S INPUT -t $table;done
# show all rules at FORWARD chain $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -nvL FORWARD -t $table;done $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -S FORWARD -t $table;done
# show all rules at OUTPUT chain $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -nvL OUTPUT -t $table;done $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -S OUTPUT -t $table;done
# show all rules at POSTROUTING chain $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -nvL POSTROUTING -t $table;done $ for table in raw mangle nat filter security; doprintf'=%.0s' {1..50}; echo -e "\n${table}..."; iptables -S POSTROUTING -t $table;done
######################## Another way to show all rules####################################################################################### # show all nat table at different chains(target or hook point) $ iptables -nvL -t nat # show command to replay the rule $ iptables -S -t nat
# show nat table at given chain(target) $ iptables -nvL PREROUTING -t nat # show command to replay the rule $ iptables -S PREROUTING -t nat ######################## Another way to show all rules#######################################################################################
show iptable rules in particular network namespace
Chain INPUT (policy ACCEPT 1792K packets, 399M bytes) pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 2614K packets, 196M bytes) pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 2614K packets, 196M bytes) pkts bytes target prot opt in out source destination
Chain DIVERT (2 references) pkts bytes target prot opt in out source destination 1796K 399M MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x1 1796K 399M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
root@dev:~/ping# nsc bb2fdae4-44bf-40a3-8acc-dfb554d79d76 iptables -nv -L DIVERT -t mangle Chain DIVERT (2 references) pkts bytes target prot opt in out source destination 1797K 400M MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x1 1797K 400M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
show rules with number root@dev:~/ping# nsc bb2fdae4-44bf-40a3-8acc-dfb554d79d76 iptables -nv -L DIVERT -t mangle --line-number Chain DIVERT (2 references) num pkts bytes target prot opt in out source destination 1 1798K 400M MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x1 2 1798K 400M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain INPUT (policy ACCEPT 1795K packets, 399M bytes) num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 2618K packets, 197M bytes) num pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 2618K packets, 197M bytes) num pkts bytes target prot opt in out source destination
Chain DIVERT (2 references) num pkts bytes target prot opt in out source destination 1 1799K 400M MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x1 2 1799K 400M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
# Delete rule by rule number root@dev:~/ping# nsc bb2fdae4-44bf-40a3-8acc-dfb554d79d76 iptables -D PREROUTING 1 -t mangle
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 52 packets, 3120 bytes) num pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 52 packets, 3120 bytes) num pkts bytes target prot opt in out source destination
Chain DIVERT (1 references) num pkts bytes target prot opt in out source destination 1 1799K 400M MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x1 2 1799K 400M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
# flush all rules in filter table(default) $ iptables -F
# flush all rules in mangle table $ iptables -F -t mangle
# set default policy in filter table for INPUT chain $ iptables -P INPUT DROP
# 阻止来自IP地址x.x.x.x eth0 tcp的包 $ iptables -A INPUT -i eth0 -p tcp -s x.x.x.x -j DROP
# check rule exist or not $ iptables -C OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT # if no rule $? == 1, otherwise 0 $ echo $?
# 允许所有来自外部的SSH连接请求,即只允许进入eth0接口,并且目标端口为22的数据包 $ iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $ iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
save and restore
使用iptables-save可以保存到特定文件中
1
$ iptables-save >/etc/sysconfig/iptables_save
使用iptables-restore可以恢复规则
1
$ iptables-restore</etc/sysconfig/iptables_save
iptables match with module condition
As basic iptables only supports protocol, saddr, sport etc conditions when matching, so some extensions add more conditions when matching packet, these extensions are organized as module like (time, limit, socket, ttl, state, mark etc)
[!] --src-type type[,...] Match source address type [!] --dst-type type[,...] Match destination address type --limit-iface-in Match only on the packet's incoming device --limit-iface-out Match only on the packet's outgoing device
--mode mode Set the matching mode of the matching rule, supported modes are `random and nth`.
[!] --probability p Set the probability for a packet to be randomly matched. It only works with the random mode. p must be within 0.0 and 1.0. The supported granularity is in 1/2147483648th increments.
[!] --every n Match one packet every nth packet. It works only with the nth mode (see also the --packet option).
--packet p Set the initial counter value (0 <= p <= n-1, default 0) for the nth mode.
# random $ iptables -A PREROUTING -t nat -d 172.17.64.8 -m statistic --mode random --probability 0.5 -j DNAT --to-destination 192.168.100.160 $ iptables -A PREROUTING -t nat -d 172.17.64.8 -m statistic --mode random --probability 0.5 -j DNAT --to-destination 192.168.100.161
iptables with extended target modules
Basically, iptables is very simple, only support ACCEPT, DROP, more targets are provided by modules Here are frequently used target.
BALANCE This allows you to DNAT connections in a round-robin way over a given range of destination addresses.
1
$ iptables -A PREROUTING -t nat -j BALANCE --to-destination 192.168.1.1-192.168.1.10
DNAT
1 2
$ iptables -A PREROUTING -t nat -j DNAT --to-destination 192.168.1.1-192.168.1.10 $ iptables -A PREROUTING -t nat -j DNAT --to-destination 192.168.1.1-192.168.1.10:1000-2000
Only valid in nat table at PREROUTING and OUTPUT chains
LOG Turn on kernel logging of matching packets
1 2
$ iptables -A PREROUTING -t nat -j LOG --log-level info $ iptables -A PREROUTING -t nat -j LOG --log-level info --log-prefix tag1
MARK This is used to set the netfilter mark value associated with the packet. It is only valid in the mangle table iptables -A PREROUTING -t mangle -j MARK –set-mark 0x10
MASQUERADE This target is only valid in the nat table, in the POSTROUTING chain, like SNAT but use address of out dev as the source ip.
1
$ iptables -A POSTROUTING -t nat -j MASQUERADE
REDIRECT(change the receiving ip(port is optional)) 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 redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface, special DNAT without providing dest by admin!!
1 2 3 4
# --to-ports port[-port] # This specifies a destination port or range of ports to use
REJECT This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD and OUTPUT chains, and user-defined chains which are only called from those chains
1 2 3 4 5 6 7 8 9
# --reject-with type # The type given can be # icmp-net-unreachable # icmp-host-unreachable # icmp-port-unreachable # icmp-proto-unreachable # icmp-net-prohibited # icmp-host-prohibited or # icmp-admin-prohibited (*)
SNAT This target is only valid in the nat table, in the POSTROUTING chain
1
# --to-source ipaddr[-ipaddr][:port-port]
comment to a rule For a single rule, you can add 256 characters for it to explain what is used for!
Let’s say there are several rules in one Chain, if the first rule doesn’t match, check next one, what about the rule matches, should we go to check next rule depends on the action of the matched rule.
1 2 3 4
- ACCEPT: check next one in the chain - REJECT/DROP: NOT check next one, return out of iptables - SNAT/DANT: after SNAT or DNAT, check next one in the chain - RETURN: just jump out the Chain, next one in this chain is not checked, check next chain
what’s conntrack table
nat is stateful, that means you should save info after nat, conntrack table is actually flow table, the initial use is for NAT, as when you do SNAT after post routing, you need to save the 5 tuples to a flow entry orig: src, dst, src_port, dst_port, protocol nat change: m_src, dst, m_src_port, dst_port, protocol, when reply packet comes back, it should match the nat_change port, then do DNAT then goes routing.
In order to support this, conntrack table was introduced, it insert some callbacks at NF_HOOK POINT with different priority.
let’s explain how conntrack fit the example, when you do SNAT after POSTROUTING, one entry is create at conntrack table, when reply packet comes back, as conntrack table is examined before nat table, hence we found a matched entry in conntrack table, will never check nat table at all at PREROUTING, skip nat table but check other table if insert rule at PREROUTING
Note: now conntrack is not only used for nat, but for all connection, even without NAT, you can also delete/create/update entry in this table by $conntrack command
show command used for each rule
dump the command used for all rules with
1 2 3 4 5 6 7 8
$ iptables-save ... -A PREROUTING -j LOG --log-prefix nat-pre-jason --log-level 6 -A PREROUTING -d 172.17.0.1/32 -j LOG --log-prefix nat-pre --log-level 6 -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A DOCKER -i docker0 -j RETURN
how custom chain is used
custom chain is similar like other chains(INPUT, OUTPUT), belongs to a table(filter, nat etc) you can create rules in it, but it has some difference
must create custom chain before creating rule in it, unlike other chains, they are kernel built-in chains
custom chain has no fixed hook point unlike other built-in chains have fixed hook point in kernel, custom chain only works when a rule in other built-in chain refers to it by -j CUSTOM_CHAIN.