iptables 包过滤和NAT
简介
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]
描述
Iptables 和 ip6tables 用于在Linux内核中设置、维护和检查IPv4和IPv6包过滤规则表,可以定义几个不同规则表,每个表包含许多内置 chain(链),还可能包含用户定义 chain(链)。
- 每个chain(链)是一个规则列表,可以匹配一组包。
- 每个规则指定如何处理匹配的包。这种动作称为 “target(目标)”。
TARGETS(目标)
防火墙规则为包和TARGETS(目标)指定标准。
- 如果包不匹配,将检查 chain 中的下一个规则
- 如果匹配,则下一条规则由target(目标)的值指定,该值可以是用户定义chain(链)的名称、iptables-extensions(8) 中描述的目标之一,或是其中一个特殊值:ACCEPT(接受)、RETURN(拒绝)、或者 DROP(丢弃)
- ACCEPT :表示让包通过
- RETURN :表示拒绝包
- DROP :表示丢弃包
TABLES(表)
! 注意:目前 iptables 有五个独立的 tables(表),和五条 chain(链)iptables 有五条控制Chain(链),分别为 (INPUT、FORWARD、OUTPUT、PREROUTING、POSTROUTING),且前三条 Chain (链)的默认动作为:ACCEPT。如果需要更改 (INPUT、FORWARD、OUTPUT) 这三条链的默认动作请使用:iptables -t[tables] -P [INPUT|FORWARD|OUTPUT] [ACCEPT|DROP]
表名称 | 说明 |
---|---|
filter | 这是默认的表(如果不使用-t选项)。它包含内置的 INPUT、FORWARD、OUTPUT |
nat | 在2.4.17内核之前,它有两个内置链: PREROUTING(在数据包进来时改变) 、OUTPUT(在路由出去前更改本地生成的数据包) 或者 POSTROUTING(即将出去时更改数据包) |
mangle | 在2.4.17内核之前,它有两个内置链: PREROUTING(在路由前更改进来的数据包) 和 OUTPUT(在路由出去前更改本地生成的数据包)、 从内核2.4.18开始,还支持其他三个内置链 INPUT(进入本身的数据包)、FORWARD(更改正在通过该路由的包)、POSTROUTING(即将外出时更改数据包). |
raw | 此表主要用于与 NOTRACK 目标组合配置连接跟踪豁免权。提供了以下内置链: PREROUTING(通过任何网络接口到达的数据包)、 OUTPUT(用于由本地进程生成的包) |
security | 此表用于强制访问控制(MAC)网络规则,例如 SECMARK 和 CONNSECMARK 目标启用的那些规则。 强制访问控制由Linux安全模块(如SELinux)实现。安全表在过滤表之后调用,允许过滤表中的任意访问控制(DAC)规则在MAC规则之前生效。 此表提供以下内置链:INPUT(用于进入本身的数据包)、 OUTPUT(用于在路由之前更改本地生成的包) 和 FORWARD(用于更改正在通过该路由的包) |
OPTIONS
iptables和ip6tables所识别的选项可以分为几个不同的组。
COMMANDS(命令组)
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 |
-A, --append chain rule-specification # 将一个或多个规则附加到所选链的末端。 -C, --check chain rule-specification # 检查所选链中是否存在与规范匹配的规则。 -D, --delete chain rule-specification -D, --delete chain rulenum # 从选择的链中删除一个或多个规则。规则可以为链中的数字(第一个规则从1开始) -I, --insert chain [rulenum] rule-specification # 在选定的链中插入一个或多个规则作为给定的规则编号,因此,如果规则数是1,则将规则插入链的开头。如果没有指定规则号,这也是默认值。 -R, --replace chain rulenum rule-specification # 替换所选链中的规则。如果源和/或目标名称解析为多个地址,则命令将失败。规则从1开始编号。 -L, --list [chain] # 列出所选链中的所有规则。如果没有选择链,则列出所有链。 iptables -t nat -n -L --line-numbers iptables -t nat -n -v -L --line-numbers --line-numbers # 当列出规则时,在每个规则的开头添加行号,对应于该规则在链中的位置。 -S, --list-rules [chain] # 打印所选链中的所有规则。如果没有选择链,所有链都像iptab -save一样打印 -F, --flush [chain] # 刷新所选的链(如果没有给出表中的所有链)。这相当于逐个删除所有规则。 -Z, --zero [chain [rulenum]] # 使所有链中的包和字节计数器为零,或仅为给定链中的给定规则为零。还可以指定-L、-list (list)选项,以便在计数器被清除之前立即查看计数器。 -N, --new-chain chain # 根据给定的名称创建一个新的用户定义链。 -X, --delete-chain [chain] # 删除指定的可选用户定义链。必须没有对链的引用。如果有,在删除链之前必须删除或替换引用规则。链必须是空的,即不包含任何规则。 # 如果没有给出参数,它将尝试删除表中的每个非内置链。 -P, --policy chain target # 设置链到指定目标的策略,而内置链和用户定义链都不能成为策略目标 -E, --rename-chain old-chain new-chain # 将用户指定的链重命名为用户提供的名称 -h Help. Give a (currently very brief) description of the command syntax. |
PARAMETERS(参数)
下面的参数构成了规则规范(在allZ(添加)、delete(删除)、insert(插入)、replace(替换) 和 append(追加) 命令中使用)。
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 |
-4, --ipv4 -6, --ipv6 [!] -p, --protocol protocol # 指定的协议可以是tcp、udp、udplite、icmp、icmpv6、esp、ah、sctp、mh或特殊关键字“all”之一,也可以是一个数值,表示其中之一协议或不同的协议。 # 还允许使用/etc/protocols中的协议名称 [!] -s, --source address[/mask][,...] [!] -d, --destination address[/mask][,...] --dst -m, --match match # 指定要使用的匹配,即测试特定属性的扩展模块。 -j, --jump target # 这指定了规则的目标;即。,如果数据包匹配,该怎么办。(即动作) -g, --goto chain # 这指定处理应该在用户指定的链中继续进行 [!] -i, --in-interface name [!] -o, --out-interface name [!] -f, --fragment -c, --set-counters packets bytes # 使管理员能够初始化规则的包和字节计数器(在插入、追加、替换操作期间)。 |
iptables-extensions(指令)
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 |
mac [!] --mac-source address # 匹配源MAC地址。 用法:mac --mac-source address mark [!] --mark value[/mask] multiport # 最多可以指定15个端口。一个端口范围(端口:端口)算作两个端口 [!] --source-ports,--sports port[,port|,port:port]... [!] --destination-ports,--dports port[,port|,port:port]... [!] --source-port,--sport port[:port] [!] --destination-port,--dport port[:port] [!] --ports port[,port|,port:port]... # 如果源端口或目的端口等于指定端口之一,则匹配。 --log level # 将确定的类型记录到dmesg中,即使它们不匹配所需的类型 [!] --rcheck # 检查数据包的源地址是否在列表中 [!] --update # Like --rcheck, except it will update the "last seen" timestamp if it matches. [!] --remove # 检查包的源地址是否当前在列表中,如果是,该地址将从列表中删除,规则将返回true。如果没有找到地址,则返回false。 --log-level level # 日志级别,可以是(系统特定的)数字或助记符。可能的值是(按优先级递减顺序):emerg、警告、暴击、错误、警告、通知、信息或调试。 --log-uid # 记录生成包的进程的用户id。 --to address[/mask] --to-ports port[-port] # 这指定了要使用的目的端口或端口范围:如果没有这个,目标端口就不会改变。只有当规则还指定以下协议之一时才有效:tcp、udp、dccp或sctp。 --src-pfx [prefix/length] # Set source prefix that you want to translate and length # --dst-pfx [prefix/length] Set destination prefix that you want to use in the translation and length |
连接状态 -m state –state=
状态 | 说明 |
---|---|
INVALID | 未知的或者、不安全的、无效的状态,建议将 INVALID 状态拒绝掉 |
NEW | 信息包已经启动了一个新的连接(TCP 的第一次握手) |
ESTABLISHED | 包与一个在两个方向都看到包的连接相关联(TCP 的第二次握手) |
REALTED | 报文跟踪,根据接收的报文需要,开放一个报文中指定的随机端口,比如FTP服务 |
UNTRACKED | 包根本没有被跟踪,如果您在原始表中使用-j CT -notrack显式地取消跟踪,就会发生这种情况。 |
SNAT | 虚拟状态,如果原始源地址与应答目的地不同,则匹配该状态。 |
DNAT | 是一个虚拟状态,如果原始目标与应答源不同,则匹配。 |
EXPECTED | 这是一个预期的连接(例如,一个conntrack助手设置它)。 |
SEEN_REPLY | Conntrack 在两个方向都看到过信息包。 |
ASSURED | Conntrack的入口不应该提前过期。 |
CONFIRMED | 连接确认:发起包已离开 |
MATCH AND TARGET EXTENSIONS(匹配和目标扩展)
ptables可以使用扩展包匹配和目标模块。iptables-extensions(8) 手册中提供了这些内容的列表。
SEE ALSO
- iptables-apply(8), iptables-save(8), iptables-restore(8), iptables-extensions(8),
实例
- -L 列出规则表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
iptables -L -n # 列出规则表,并使用反响解析 Chain INPUT (policy ACCEPT) target prot opt source destination REJECT all -- 0.0.0.0/0 0.0.0.0/0 state INVALID reject-with icmp-port-unreachable ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 MAC 00:50:56:C0:00:08 ACCEPT tcp -- 192.168.57.0/24 0.0.0.0/0 tcp dpt:22 Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination REJECT all -- 0.0.0.0/0 0.0.0.0/0 state INVALID reject-with icmp-port-unreachable ACCEPT tcp -- 0.0.0.0/0 192.168.57.0/24 state ESTABLISHED |
- -t 指定规则表,如果没有指定则使用默认的表:filter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
iptables -t nat -L -n # 列出指定的表 nat Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT tcp -- 0.0.0.0/0 192.168.57.13 tcp dpt:80 to:192.168.57.144:80 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination |
- –line-numbers 列出规则的序列号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
iptables -t nat -L -n --line-numbers # 列出指定的表 nat,并将规则的序列号从 1 开始打印 Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 DNAT tcp -- 0.0.0.0/0 192.168.57.13 tcp dpt:80 to:192.168.57.144:80 Chain INPUT (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination Chain POSTROUTING (policy ACCEPT) num target prot opt source destination |
- -I 在指定的序号号之前插入规则
1 2 3 4 5 |
iptables -I INPUT 1 -m state --state=INVALID -j REJECT # 在序列号1中插入、状态为:未知的流量,动作为拒绝 iptables -I INPUT 2 -s 0.0.0.0 -p all -j ACCEPT # -I 在 INPUT流 中插入一条序列号为1、源地址:所有、协议为:all、动作为允许 |
- -D 删除指定的序列号规则表
1 2 3 4 5 |
iptables -D INPUT 2 # 删除序列号为 1 的策略 iptables -t nat -D INPUT 3 # 删除表 nat 中序列号为 3 的规则 |
- -A 在规则末尾,添加一条规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
iptables -A INPUT -s 192.168.57.1 -p tcp --dport 22 -j REJECT # 添加一条自动编排序列号,原地址为 192.168.57.1 协议为 tcp 的主机,到本地端口22的策略、动作为拒绝 iptables -A INPUT -s 192.168.57.1 -p tcp --dport 22 -j LOG # 动作为记录事件日志,并将触发信息记录到 /var/log/messages 日志中 iptables -I INPUT 2 -s 192.168.57.1 -p tcp --dport 22 -j ACCEPT # 动作为允许 iptables -I INPUT 2 -p tcp --dport 22 -j ACCEPT # 插入一条序列号为2、源地址为0.0.0.0/24、协议为tcp、到本机端口22的策略、动作为允许 iptables -A INPUT -s 192.168.57.1 -p all -j ACCEPT # 添加一条规则,源地址为192.168.57.1、协议为all、的动作为 允许 iptables -I INPUT 3 ! -s 192.168.58.0/24 -p tcp --dport 22 -j REJECT # 插入一条序列号为 3、!除了源地址为192.168.58.0/24、协议为tcp的流量到本机的22端口为允许外,其他地址都拒绝 iptables -I INPUT 4 -m mac --mac=00:50:56:C0:00:08 -p tcp --dport 22 -j REJECT # 插入一条序列号为4、MAC地址为00:50:……、协议为tcp的流量到本机的22端口的策略、动作为拒绝 iptables -I INPUT 1 -m mac --mac=00:50:56:C0:00:08 -p tcp --dport 22 -j LOG # 动作为记录事件日志,并将触发信息记录到 /var/log/messages 日志中 iptables -I INPUT 2 -m mac --mac=00:50:56:C0:00:08 -p tcp --dport 22 -j REJECT # 动作为拒绝 |
- 示例配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
iptables -I INPUT 1 -m state --state=INVALID -j REJECT # 拒绝:状态为未知的流量进入 iptables -I INPUT 2 -p icmp -j ACCEPT # 允许:所有的主机的协议类型为 ICMP 的协议进入 iptables -I INPUT 3 -m mac --mac=00:50:56:C0:00:08 -p all -j ACCEPT # 允许:指定的 MAC 地址的所有流量进入 iptables -I INPUT 4 -s 192.168.57.1 -p all -j ACCEPT # 允许:指定的 IP 地址的所有流量进入 iptables -I INPUT 5 -s 192.168.57.0/24 -p tcp --dport 22 -j ACCEPT # 允许:指定子网的 tcp 端口为22 的流量进入 iptables -A INPUT -p tcp --dport '80' -j ACCEPT # 允许:所有80端口的流量进入 iptables -A INPUT -p tcp --dport '443' -j ACCEPT # 允许:所有443端口的流量进入 service iptables save # 保存 iptables -L -n -v --line-numbers # 列出防火墙的详细规则 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID reject-with icmp-port-unreachable 2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 3 200 16300 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 MAC 00:50:56:C0:00:08 4 0 0 ACCEPT all -- * * 192.168.57.1 0.0.0.0/0 5 0 0 ACCEPT tcp -- * * 192.168.57.0/24 0.0.0.0/0 tcp dpt:22 6 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 7 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 |
- 禁止内网中的源 MAC地址 访问本机
1 2 3 4 5 |
iptables -I INPUT 2 -m mac --mac-source=D0:50:99:5B:AA:7D -p tcp --dport 80 -j LOG iptables -I INPUT 3-m mac --mac -source=D0:50:99:5B:AA:7D -p tcp --dport 80 -j REJECT |
- 示例配置
1 2 3 4 5 6 7 8 |
iptables -I OUTPUT 1 -m state --state=INVALID -j REJECT # 拒绝:所有的未知的流量出去 iptables -I OUTPUT 2 -p icmp -j ACCEPT iptables -I OUTPUT 3 -d 192.168.57.1 -p all -j ACCEPT iptables -I OUTPUT 4 -d 192.168.57.144 -p tcp --sport 22 -j ACCEPT iptables -I OUTPUT 5 -d 192.168.57.0/24 -p tcp -m state --state=ESTABLISHED -j ACCEPT #--state=ESTABLISHED tcp二次握手 service iptables save |
- 安装服务
1 2 3 4 5 6 |
yum install iptables-services systemctl enable iptables.service systemctl restart iptables.service service iptables save |