iptables
{Back to Index}
Table of Contents
1 概述
1.1 命令格式
iptables [ -t 表名] 命令选项 [链名] [匹配] [-j 目标动作或跳转]
1.1.1 表 (操作维度)
在 iptables 中,每种表对应不同的功能(操作),由相应的内核模块提供支持:
filter (iptables_filter)
负责过滤功能,防火墙。
nat (iptable_nat)
提供网络地址转换,端口映射功能。
mangle (iptable_mangle)
拆解报文,做出修改,并重新封装。
raw (iptable_raw)
优先级最高的表 ,设置 raw 时一般是为了不再做数据包的链接跟踪处理,以提高性能。
因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理,即数据包在某个链上由 raw 表处理完后, 就意味着跳过了 nat 表(和 iptables_nat 模块中对 ip_conntrack 的处理,相当于不再做地址转换和数据包的链接跟踪处理了)
可以应用在那些 不需要做 nat 的情况下 ,以提高性能。如大量访问的 web 服务器,可以让 80 端口不再做数据包的链接跟踪处理, 以提高用户的访问速度。
1.1.2 链 (执行维度)
- PREROUTING
- raw, mangle, nat
- INPUT
- mangle, filter
- FORWARD
- mangle, filter
- OUTPUT
- raw, mangle, nat, filter
- POSTROUTING
- mangle, nat
数据包经过一个链的时候,会将当前链的所有规则都匹配一遍,但是 匹配是有顺序的 ,当 4 张表处于同一条链时,执行的优先级如下:
raw -> mangle -> nat -> filter
拥有 过滤功能 的链只有 3 条:INPUT, OUTPUT, FORWARD 。
1.1.3 命令选项
1.1.3.1 rule 管理
-A: 在指定链的末尾添加( --append )一条新的规则 -D: 删除( --delete )指定链中的某一条规则,按规则序号或内容确定要删除的规则 -I: 在指定链中插入( --insert )一条新的规则,默认在链的开头插入 -R: 修 改、替换( --replace )指定链中的一条规则,按规则序号或内容确定
1.1.3.2 链管理
-F: 清空( --flush )指定链中的所有规则,默认清空表中所有链的内容 -N: 新建( --new-chain )一条用户自己定义的规则链 -X: 删除指定表中用户自定义的规则链( --delete-chain ) -P: 设置指定链的默认策略( --policy ) -z: 置零计数器 -r [CHAIN]: 清空指定规则链,如果省略 CHAIN,则删除对应表中的所有链
1.1.3.3 查看信息
-L: 列出( --list )指定链中的所有的规则进行查看,默认列出表中所有链的内容 -n: 用数字形式( --numeric )显示输出结果,若显示主机的 IP 地址而不是主机名 -v: 查看规则列表时显示详细( --verbose )的信息 -x: 计数器取消近似 -line-numbers: 查看规则列表时,同时显示规则在链中的顺序号
1.1.4 匹配
1.1.4.1 通用匹配
-p {tcp|udp|icmp}: 指定隐含扩展,其余扩展(如 state)必须由 -m 指定 -s, --src: 指定源地址 -d, --dst: 指定目标地址 -i <INTERFACE>: 指定报文流入接口,仅适用于 PREROUTING,INPUT,FORWARD -o <INTERFACE>: 指定报文流出接口,仅适用于 OUTPUT,POSTROUTING,FORWARD
1.1.4.2 隐含匹配
-p tcp: --sport PORT|STARTPORT-ENDPORT: 源端口 --dport PORT|STARTPORT-ENDPORT: 目标端口 --tcp-flags <mask> <comp>: 检查<mask>中列出的标志位, <comp>中指明的必须为1,其余必须为零 如:--tcp-flags SYN,FIN,ACK,RST SYN,ACK --syn: 等效于 --tcp-flags SYN,FIN,ACK,RST SYN,ACK -p icmp: --icmp-type: 0(echo-reply), 8(echo-request) -p udp: --sport --dport
1.1.4.3 显式匹配
-m state: --state NEW|ESTABLISHED|RELATED|INVALID -m multiport: --source-ports --destination-ports -m iprange: --src-range --dst-range -m connlimit: --connlimit-above -m limit: --limit --limit-burst -m time: --datestart --datestop --timestart --timestop -m string: --algo: 用于指定匹配算法,可选的算法有 bm 与 kmp --string: 指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件
1.1.5 目标动作
ACCEPT
允许数据包通过。
DROP
直接丢弃数据包,不给任何回应信息。
REJECT
拒绝数据包通过,客户端刚请求会收到拒绝的信息。
SNAT
源地址转换,解决内网用户用同一个公网地址上网的问题。
MASQUERADE
是 SNAT 的一种特殊形式 , 适用于网关 NAT 的情况 ,例如:
iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o eth1 -j MASQUERADE
在网关上仅针对由内网到 Internet 的流量进行 NAT 转换:【10.0.0.0/8 为公司内部网段】
DNAT
目标地址转换。
REDIRECT
在本机做端口映射。
LOG
在
/var/log/messages
文件中记录日志信息,然后将数据包传递给下一条规则(除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配)。
1.2 四表五链
Figure 1: 链与表的分布
Figure 2: iptables/netfilter 整体架构
通过以下命令设置主机支持转发功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
2 应用场景 1
2.1 NAT
Figure 3: 网络地址映射
使用 NAT 技术一定会发生两次 IP 地址的转换(下面以内网访问外网为例):
- 内部网络的报文发送出去时,报文的源 IP 会被修改,也就是源地址转换(SNAT)
- 外部网络的报文响应时,响应报文的目标 IP 会再次被修改,也就是目标地址转换(DNAT)
上述过程被称为 SNAT ,是因为先发生了 SNAT。如果先使用 DNAT (比如外网穿透内网的场景,下面会讲到),则整个过程被称为 DNAT 。
也就是说,NAT 属于 SNAT 还是 DNAT ,取决于整个过程的最先使用了 SNAT 还是 DNAT 。
2.1.1 SNAT
Figure 4: SNAT 网络拓扑
只是配置 SNAT 的话,并不用手动配置 DNAT ,iptables 会自动维护 NAT 表,自动执行 DNAT 将响应报文的目标地址转换回来。
2.1.2 DNAT
Figure 5: DNAT 网络拓扑
只是配置 DNAT 的话,并不用手动配置 SNAT ,iptables 会自动维护 NAT 表,自动执行 SNAT 将响应报文的源地址转换回来。
2.1.3 本地端口转发
iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j REDIRECT --to-port 8080 # 若 8080 监听于 localhost,则可能需要执行:sysctl -w net.ipv4.conf.all.route_localnet=1
2.2 封堵端口
iptables -I INPUT -p tcp --dport <port> -j REJECT iptables -I OUTPUT -p tcp --sport <port> -j REJECT
2.3 禁止 SYN floods
# Limit the number of incoming tcp connections # Incoming syn-flood protection iptables -N syn_flood iptables -A INPUT -p tcp --syn -j syn_flood iptables -A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN iptables -A syn_flood -j REJECT # --limit 1/s: Maximum average matching rate in seconds # --limit-burst 3: Maximum initial number of packets to match
2.4 限制连接数
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP # 超过 3 个连接则拒绝
2.5 防止 DoS
利用 recent 和 state 模块限制单个 IP 在 300 秒内只能与本机建立 3 个新连接,被限制 5 分钟周恢复访问。
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP # --name: 指定记录名称 # --set: 记录数据包的来源 IP,若已存在,则更新 # --update: 每次建立连接都要更新记录 # --seconds: 必须与 --rcheck 或 --update 同时使用 # --hitcount: 必须与 --rcheck 或 --update 同时使用 # 记录保存于:/proc/net/ipt_recent/SSH
2.6 LOG
for c in PREROUTING OUTPUT; do iptables -t nat -I $c -d <dest-ip> -j LOG --log-prefix "DBG@$c: " --log-level 4 # log level: 0 - 7 [emerg,alert,crit,error,warning,notice,info,debug] # 4: standard syslog level (warning) done