Linux常用命令-iptables

命令

iptables

描述

administration tool for IPv4/IPv6 packet filtering and NAT
用于IPv4/IPv6数据包过滤和NAT的管理工具

用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
iptables [-t table] command chain rule-specification [options]
iptables [-t table] {-A|-C|-D} chain rule-specification
ip6tables [-t table] {-A|-C|-D} chain rule-specification
iptables [-t table] -I chain [rulenum] rule-specification
iptables [-t table] -R chain rulenum rule-specification
iptables [-t table] -D chain rulenum
iptables [-t table] -S [chain [rulenum]]
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
iptables [-t table] -N chain
iptables [-t table] -X [chain]
iptables [-t table] -P chain target
iptables [-t table] -E old-chain-name new-chain-name

rule-specification = [matches...] [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
Commands:
-A, --append 追加rule到chain末尾
-C, --check 检查chain中是否存在匹配的rule
-D, --delete 从chain中删除匹配的rule,可以指定rule或rulenum
-I, --insert 在指定chain中插入rule,可以指定rule位置编号rulenum,默认为1,即插入到chain的第一行
-R, --replace 替换指定chain中的rule,必须指定rulenum,即指定替换第几条rule
-L, --list 显示指定chain中的rule,如果未指定chain则显示所有chain
-S, --list-rules 显示指定chain中的rule,显示格式和iptables save命令格式一致
-F, --flush 删除chain中的rule
-Z, --zero 将指定chain中的数据包和字节计数器归零
-N, --new-chain 创建用户定义chain
-X, --delete-chain 删除用户定义chain,chain必须为空,即不包含任何rule.如果未指定chain,则会删除所有非内置chain
-P, --policy 设置内置chain的默认policy,可以是ACCEPT or DROP
-E, --rename-chain 重命名用户定义chain

Rule-specification:
-4, --ipv4 此选项在iptables和iptables-restore命令中无效
-6, --ipv6 同上
[!] -p, --protocol 指定协议,可选参数tcp,udp,icmp,icmpv6,all等,也可以指定协议号,0相当于all.加!表示反向匹配
[!] -s, --source 指定源地址,可以是hostname,网段,IP地址.如果指定的是域名则会自动添加解析后所有IP
[!] -d, --destination 指定目标地址
-m, --match 指定要使用的匹配项
-j, --jump 指定动作,可选ACCEPT, DROP or RETURN等
-g, --goto 指定chain中处理
[!] -i, --in-interface 接收数据包的接口,仅适用于进入 INPUT、FORWARD 和 PREROUTING chain的数据包
[!] -o, --out-interface 发送数据包的接口,对于送出 FORWARD、OUTPUT 和 POSTROUTING chain的数据包
如果-i或-o选项定义的接口名称以'+'结尾,则将匹配以该名称开头的接口,如果省略此选项,则匹配任何接口名称
[!] -f, --fragment 在分片的包中,规则只询问第二及以后的片
-c, --set-counters 初始化数据包和字节计数器

Options:
-t, --table 指定table,默认为filter
-v, --verbose 显示详情
-w, --wait [seconds] 等待xtables锁,路径/run/xtables.lock
-W, --wait-interval microseconds 每次迭代等待的时间间隔
-n, --numeric 显示数字格式,即显示IP地址和端口号
-x, --exact 扩展显示数字,显示包和字节计数器的精确数值,配合-L使用
--line-numbers 显示行号
--modprobe=command 使用命令加载模块

扩展选项: man iptables-extensions
tcp,udp,icmp,icmp6可以省略-m选项,直接使用-p xxx来启用,如-p tcp --sport 80,
其他扩展选项需要使用-m xxx来启用,如-m multiport --sports 80,443
tcp
-p tcp, --protocol tcp
[!] --source-port,--sport port[:port] 指定源端口或端口范围,可以指定服务名或端口号
[!] --destination-port,--dport port[:port] 指定目标端口或端口范围
[!] --tcp-flags mask comp 匹配指定的TCP标记,mask参数表示要检查的标记,comp参数表示必须设置的标记,可选标记参数SYN ACK FIN RST URG PSH ALL NONE
例如 iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST SYN 表示只匹配设置了SYN标记,而没有设置ACK,FIN,RST的包
[!] --syn 只匹配那些设置了SYN位而清除了ACK和FIN位的TCP包,等同于--tcp-flags SYN,RST,ACK,FIN SYN
[!] --tcp-option number 匹配设置了TCP选项的

udp
--protocol udp
[!] --source-port,--sport port[:port] 指定源端口或端口范围
[!] --destination-port,--dport port[:port] 指定目标端口或端口范围

icmp (IPv4-specific)
--protocol icmp
[!] --icmp-type {type[/code]|typename} 指定ICMP类型,使用命令iptables -p icmp -h显示可用的ICMP类型
8 echo-request
0 echo-reply

icmp6 (IPv6-specific)
--protocol icmpv6
[!] --icmpv6-type type[/code]|typename 指定ICMP类型,使用命令iptables -p icmpv6 -h显示可用的ICMP类型

iprange
-m iprange
[!] --src-range from[-to] 在指定IP范围内匹配源IP
[!] --dst-range from[-to] 在指定IP范围内匹配目标IP

ipvs
-m ipvs
[!] --ipvs 数据包属于IPVS连接
[!] --vproto protocol 匹配VIP协议,可以是名称或数字,如tcp
[!] --vaddr address[/mask] 匹配VIP地址
[!] --vport port 匹配VIP端口,如http
--vdir {ORIGINAL|REPLY} 指定数据包的流向
[!] --vmethod {GATE|IPIP|MASQ} 指定IPVS的转发方式
[!] --vportctl port 要匹配的控制连接的VIP端口,如FTP的21端口

limit
-m limit
--limit rate[/second|/minute|/hour|/day] 最大平均匹配速率,可选单位/second,/minute,/hour,/day,默认为3/hour
--limit-burst number 待匹配包初始个数的最大值,默认为5

mac
-m mac
[!] --mac-source address 匹配MAC物理地址,格式使用:作为分隔符,仅对于以太网设备的PREROUTING,FORWARD,INPUT chains有效

mark
-m mark
[!] --mark value[/mask] 匹配那些无符号标记值的包,英文说明如下
Matches packets with the given unsigned mark value (if a
mask is specified, this is logically ANDed with the mask
before the comparison).

multiport
-m multiport
[!] --source-ports,--sports port[,port|,port:port]... 指定多个源端口,如果源端口是指定端口之一则匹配
指定多个端口用逗号,分隔,如80,443
指定端口范围用冒号:分隔,如1024:65535
例如--sports 80,443,1024:65535表示将匹配80,443端口和1024-65535范围内的所有端口
[!] --destination-ports,--dports port[,port|,port:port]... 指定多个目标端口,如果目标端口是指定端口之一则匹配
[!] --ports port[,port|,port:port]... 指定多个端口,如果源端口或目标端口是指定端口之一则匹配

comment
-m comment
--comment comment 给rule添加注释,最大256个字符 例如 iptables -A INPUT -i eth1 -m comment --comment "LAN"

state
-m state
[!] --state state 允许访问此数据包的连接跟踪状态,其中 state 是要匹配的连接状态,
多个参数用逗号,分隔,可选参数INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED

set
-m set
[!] --match-set setname flag[,flag]... 指定匹配的ipset名称,可以指定src,dst表示源和目标
[!] --set flag[,flag]... 如果选项--match-set与其他扩展的选项不冲突,则可以简写为--set
如-m set --set badip src表示匹配源地址在badip这个ipset集合里的数据包
############
其他动作-target
LOG
开启匹配数据包的内核日志记录,开启后可以通过dmesg命令查看日志,或直接查看日志文件
注意如果需要记录拒绝的数据包,则需要指定2条相同的规则,并分别指定LOG和DROP(或REJECT)动作
--log-level level 指定日志级别,可选参数emerg,alert,crit,error(3),warning(默认4),notice,info,debug
--log-prefix prefix 指定日志信息前缀,用于和系统日志区分开,也便于日志过滤,最多29个字符
--log-tcp-sequence 记录TCP序列号
--log-tcp-options 记录来自TCP包头部的选项
--log-ip-options 记录来自IP包头部的选项
--log-uid 记录生成数据包的进程的UID

REDIRECT
此目标仅在nat表的PREROUTING和OUTPUT链以及仅从这些链调用的用户定义链中有效,
它通过将目标IP修改为传入接口的主IP地址来将数据包重定向到机器本身,
本地生成的数据包映射到localhost,IPV4对应127.0.0.1,IPv6对应::1,
到达未配置IP地址的接口的数据包将被丢弃
--to-ports port[-port]
指定使用的目的端口或端口范围,不指定的话,目标端口不变,仅用于tcp或udp规则
--random 随机映射端口

REJECT (IPv6-specific)
此目标仅在INPUT,FORWARD,OUTPUT链以及仅从这些链调用的用户定义链中有效,
返回一个错误包以响应匹配的数据包,其他和DROP相同.
--reject-with type
可选类型icmp6-no-route, no-route, icmp6-adm-prohibited, adm-prohibited,
icmp6-addr-unreachable, addr-unreach, icmp6-port-unreachable(默认)

REJECT (IPv4-specific)
此目标仅在INPUT,FORWARD,OUTPUT链以及仅从这些链调用的用户定义链中有效,
返回一个错误包以响应匹配的数据包,其他和DROP相同.
--reject-with type
可选类型icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable(默认),
icmp-proto-unreachable, icmp-net-prohibited, icmp-host-prohibited,
icmp-admin-prohibited(需要内核支持)

DNAT
此目标仅在nat表的PREROUTING和OUTPUT链以及仅从这些链调用的用户定义链中有效,
目标地址转换,修改数据包中的目标地址
--to-destination [ipaddr[-ipaddr]][:port[-port]]
指定目标IP或IP范围,端口或端口范围
--random 随机映射端口
--persistent 为每个连接的客户端提供相同的源/目标地址

SNAT
此目标仅在nat表的POSTROUTING和INPUT链以及仅从这些链中调用的用户定义链中有效,
源地址转换,修改数据包中的源地址
--to-source [ipaddr[-ipaddr]][:port[-port]]
指定新的源IP或IP范围,可选端口范围,仅用于tcp或udp规则
如果不指定端口范围,默认512以下端口映射到512以下的其他端口,512-1023之间的端口映射到1024以下的短裤,其他端口映射到1024以上端口
--random 随机映射端口
--persistent 为每个连接的客户端提供相同的源/目标地址

MASQUERADE
此目标仅在nat表的POSTROUTING链中有效,
它只能与动态分配的IP一起使用,如果是静态IP,则应该使用SNAT,MASQUERADE是SNAT的一种特例
--to-ports port[-port] 指定源端口范围,仅用于tcp或udp规则
--random 随机映射源端口

SET
此模块用于管理ipset集合,注意-j SET和-m set --match-set的区别,前者是添加或删除ipset集合条目,后者是调用ipset集合
--add-set setname flag[,flag...] 添加数据包中的IP或端口到ipset集合中
--del-set setname flag[,flag...] 删除,可以指定src或dst
--timeout value 添加条目时指定超时时间
--exist 如果添加的条目已存在,则将重置超时时间或指定超时时间

使用不同的策略实现内外网的相互访问
SNAT,MASQUERADE: 解决内网多个客户端访问互联网
DNAT: 实现Internet中的客户端访问局域网内的服务器

其他命令
iptables-save
iptables-restore
# 以下两个命令参考ubuntu 20.04的man帮助
iptables-apply
iptables-translate


table 表,包括5张内置表 filter(默认表),nat,mangle,raw,security
chain 链,包括 PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
rule 规则
policy 策略
target 目标,动作,如ACCEPT,DROP,RETURN,REJECT,LOG等

一张表中包括多条链,一条链中包括多条规则

内置表
filter: INPUT,FORWARD,OUTPUT
nat: PREROUTING,OUTPUT,POSTROUTING
mangle: PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
raw: PREROUTING,OUTPUT
security: INPUT,FORWARD,OUTPUT

注意

iptables可以在关闭系统防火墙firewalld的情况下,对网络访问做限制,iptables默认策略为全部允许
iptables命令大小写敏感,table为小写,chain和target为大写
iptables命令即时生效,任何DROP操作之前请先确认ACCEPT允许的流量,否则会导致网络中断
如果要实现转发,需要设置内核参数net.ipv4.ip_forward = 1

参考
https://ipset.netfilter.org/iptables.man.html
https://ipset.netfilter.org/iptables-extensions.man.html
https://www.cnblogs.com/pycode/p/9495797.html
https://www.cnblogs.com/pycode/p/9495798.html
https://www.cnblogs.com/hftian/p/8280841.html

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
$ iptables -V
iptables v1.4.21

$ iptables -vnL
Chain INPUT (policy ACCEPT 5583 packets, 385K 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 3048 packets, 265K bytes)
pkts bytes target prot opt in out source destination

$ lsmod | grep iptable
iptable_security 12705 0
iptable_mangle 12695 0
iptable_raw 12678 0
iptable_nat 12875 0
nf_nat_ipv4 14115 1 iptable_nat
iptable_filter 12810 1
ip_tables 27126 5 iptable_security,iptable_filter,iptable_mangle,iptable_nat,iptable_raw

# 定义默认策略
# 指定filter表的INPUT链默认策略为DROP
iptables -P INPUT DROP

# 查看iptables规则
iptables -vnL
iptables -S
# 查看nat表的INPUT链
iptables -t nat -vnL INPUT
# 显示规则序号
iptable -vnL --line-numbers

# 追加
# 默认追加为规则链的最后一条,源地址-s和目标地址-d,均支持域名,IP和网段,如果添加的为域名,则自动添加解析后的所有IP
iptables -A INPUT -d www.a.com -p tcp -j DROP
iptables -A INPUT -s 192.168.31.12 -p tcp --dport 22 -j DROP
# 禁止所有协议
iptables -A INPUT -s 192.168.31.12 -p all -j DROP
# 禁止除了icmp外的所有协议
iptables -A INPUT -s 192.168.31.12 ! -p icmp -j DROP
# 指定源网段
iptables -A INPUT -s 192.168.31.0/24 -p tcp --dport 80 -j ACCEPT
# 指定目标网段
iptables -A INPUT -d 192.168.31.0/24 -p tcp --dport 80 -j ACCEPT
# 添加规则时指定注释信息
iptables -A INPUT -i eth1 -m comment --comment "LAN"
# 指定多个不连续的端口
iptables -A INPUT -s 192.168.31.12 -p tcp -m multiport --dports 80,443,22 -j ACCEPT


# 插入
# 默认插入到规则链的第一条
iptables -I INPUT -p tcp --dport 80 -j DROP
# 指定插入到规则链的第3条
iptables -I INPUT 3 -p tcp --dport 8080 -j DROP

# 替换
# 替换规则链中的第3条规则
iptables -R INPUT 3 -p tcp --dport 8081 -j DROP

# 删除
# 删除指定内容的规则
iptables -D INPUT -p tcp --dport 80 -j DROP
# 删除指定编号的规则
iptables -D INPUT 3

# 计数器置零
# 重置INPUT链计数器
iptables -Z INPUT
# 重置nat表所有计数器
iptables -t nat -Z

# 清除规则
# 删除filter表的INPUT链中的规则
iptables -F INPUT
# 清空filter表中的所有规则
iptables -F
# 清空nat表中的所有规则
iptables -t nat -F

# 创建自定义规则链
iptables -N MYCHAIN
# 重命名自定义规则链
iptables -E MYCHAIN YOURCHAIN
# 删除自定义规则链
iptables -X YOURCHAIN

# 记录iptables日志,先插入一条DROP规则,然后再插入一条相同的LOG规则
# 注意顺序必须是LOG在DROP规则之上,即先记录日志再拒绝连接.默认日志级别为warn,可以更改为error
iptables -I INPUT -s 192.168.31.12 -p tcp --dport 22 -j DROP
iptables -I INPUT -s 192.168.31.12 -p tcp --dport 22 -j LOG --log-prefix "[iptables_log] " --log-level error
# 默认iptables日志保存在/var/log/messages,或者通过dmesg命令查看
$ tail /var/log/messages
$ dmesg | tail
# 指定日志文件,iptables为kernel日志,默认日志级别为warn,添加如下配置指定日志文件路径
$ vim /etc/rsyslog.conf
kern.warn /var/log/iptables.log
$ systemctl restart rsyslog

# 如下命令表示把所有192.168.10.0/24网段的数据包SNAT成192.168.31.11的ip然后发出去
iptables-t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j SNAT --to-source 192.168.31.11
# 如下命令表示把所有192.168.10.0/24网段的数据包SNAT成192.168.31.11-13这3个ip然后发出去
iptables-t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j SNAT --to-source 192.168.31.11-192.168.31.13
# 如下命令实现动态SNAT,即出口IP为动态获取时无需指定SNAT的目标ip,MASQUERADE会自动读取eth0的ip地址然后做SNAT转换
iptables-t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE

# 关机之前保存规则
iptables-save > /etc/sysconfig/iptables
# 开机之后加载规则
iptables-restore /etc/sysconfig/iptables

# iptables调用ipset
# 创建ipset-banip,并添加多个IP
ipset create banip hash:ip
ipset add banip 192.168.10.10
ipset add banip 10.11.12.10
ipset add banip 172.17.1.15
# 匹配源地址在banip中的IP,拒绝访问,后续只需要添加IP到banip集合中,而不需要更改iptables规则
iptables -I INPUT -m set --set banip src -j DROP
ipset add banip 10.22.1.2