TOC

iptables (2): 基本操作

命令参数

iptables -[ACD] chain rule-specification [options]
iptables -I chain [rulenum] rule-specification [options]
iptables -R chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LS] [chain [rulenum]] [options]
iptables -[FZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]

链相关

  • --new -N [chain] 链:创建
  • --delete-chain -X [chain] 链:删除
  • --rename-chain -E old-chain new-chain 链:更名
  • --list -L [chain [rulenum]] 列出指定链或所有链中的所有规则(表格形式)
  • --list-rules -S [chain [rulenum]] 同上,不过是按照规则定义的格式列出 很好用
  • --flush -F [chain] 清空规则
  • --zero -Z [chain [rulenum]] 计数器清零(数据包计数器,流量计数器)
  • --policy -P chain target 修改策略

规则相关

  • --append -A chain rule-specification 附加规则
  • --check -C chain rule-specification 检查规则是否存在
  • --delete -D chain rule-specification 删除匹配规则
  • --delete -D chain rulenum 删除 指定序号的 规则
  • --insert -I chain [rulenum] 插入到指定位置(默认插入到第一个)
  • --replace -R chain rulenum 替换 指定序号的 规则

规则说明

常用命令

查看

sudo iptables -S
sudo iptables -t nat -S POSTROUTING

sudo iptables -nL
sudo iptables -nL INPUT

sudo iptables -nL --line-numbers

sudo iptables -Z
sudo iptables -Z INPUT
sudo iptables -Z INPUT 1

# 如果是这么定义的话:
#             -A INPUT -m conntrack --ctstate INVALID -j DROP
sudo iptables -D INPUT -m conntrack --ctstate INVALID -j DROP
sudo iptables -D INPUT 3

访问拦截

# 对指定端口放行
sudo iptables -I INPUT -p tcp --dport 1022 -j ACCEPT

# 禁止来自无线网络的流量访问某端口(突发奇想的一个小例子)
sudo iptables -A PREROUTINE -i wlp6s0 --dport 22 -j DROP

NAT

iptables -t nat -A POSTROUTING -d 192.168.0.102 -j SNAT --to 192.168.0.1
iptables -t nat -A PREROUTING -d 202.202.202.2 -j DNAT --to-destination 192.168.0.102
iptables -t nat -D PREROUTING -p tcp --dport 8080 -i eth2.2 -j REDIRECT --to 80

对指定流量打标记

内核可以给这个包加上一个标记(可能存在包的数据结构中,总之,只对本地环境有效),可以实现流量的统计、限制等其他复杂的控制。

标记值最大可以到 2^32

iptables -t mangle -A PREROUTING -s 192.168.1.3 -j MARK --set-mark 60
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2

//打标记
iptables -t mangle -A PREROUTING -j MARK --set-mark 33
//匹配标记
iptables -t nat -A PREROUTING -m mark --mark 33  -j ACCEPT
//or-mark
iptables -t mangle -A PREROUTING -j MARK --or-mark 0x400
//掩码匹配
iptables -t nat -A PREROUTING -m mark --mark 0x400/0x400  -j ACCEPT

iptables -t mangle -A INPUT -m state --state NEW -j MARK --set-mark 1
iptables -t mangle -A INPUT -j CONNMARK --save-mark
iptables -t mangle -A INPUT -j CONNMARK --restore-mark

iptables -t mangle -A PREROUTING -mttl --ttl-eq 64 -j MARK --set-mark 10
iptables -t mangle -A PREROUTING -mttl --ttl-eq 123 -j MARK --set-mark 20
iptables -t filter -A FORWARD -m mark--mark 10 -j ACCEPT
iptables -t filter -A FORWARD -m mark--mark 20 -j DROP

iptables -t mangle -A QOS_MARK_FORWARD_eth1 -j CONNMARK --restore-mark --nfmask 0xfffff --ctmask 0xfffff
iptables -t mangle -A QOS_MARK_FORWARD_eth1 -m mark --mark 0x0/0xfffff -j QOS_RULES_FORWARD_eth1
iptables -t mangle -A QOS_RULES_FORWARD_eth1 -j CONNMARK --save-mark --nfmask 0xfffff --ctmask 0xfffff

iptables -t mangle -A POSTROUTING -m iprange --src-range 192.168.0.2-192.168.0.200 -j MARK --or-mark 0x1

-m mark
-m connmark
-j MARK
-j CONNMARK
-j CONNSECMARK
-j SECMARK

  • --set-mark value 设置nfmark值
  • --and-mark value nfmark与value与运算
  • --or-mark value nfmark与value或运算

匹配

  • [!] --mark value[/mask]
iptables -t mangle -A INPUT -m mark --mark 1

限速

思路:hashlimit 模块

屏蔽指定网站

利用 string 模块 (xt_string.ko) 做域名匹配:

sudo iptables -A OUTPUT -m string --string baidu.com --algo bm -j LOG --log-prefix "iptables-test:blocked:baidu.com: "
sudo iptables -A OUTPUT -m string --string baidu.com --algo bm -j DROP
sudo iptables -vnL
curl https://www.baidu.com/
tail -f /var/log/syslog | grep "iptables-test"
sudo iptables -F OUTPUT

sudo iptables -A FORWARD -m string --string baidu.com --algo bm -j LOG --log-prefix "iptables-test:blocked:baidu.com: "
sudo iptables -A FORWARD -m string --string baidu.com --algo bm -j DROP

HTTPS 居然也可以生效,其原理我还不清楚,到底是匹配到了包的哪一部分包含了 baidu.com 呢?

提示:

  1. 这个规则也可以放到 INPUT 链上。
  2. 如果加上 -p tcp –dport 80 可能更加精确,免得别的什么包里面包含了 baidu.com 被拦截。
  3. 可以加多个 string 参数。

如果是 HTTP 的话,在我的理解范围之内,可以做到更细致的匹配,比如匹配到路径,甚至 Cookie。

string match options:
--from                       Offset to start searching from
--to                         Offset to stop searching
--algo                       Algorithm
--icase                      Ignore case (default: 0)
[!] --string string          Match a string in a packet
[!] --hex-string string      Match a hex string in a packet

algo 的选项:bm, kmp,参考 man iptables-extensions

参考资料与拓展阅读