iptables 命令是 Linux 上常用的防火墙软件,是 netfilter 项目的一部分。可以直接配置,也可以通过许多前端和图形界面配置。这篇文章主要介绍 iptables 的安装,添加规则,清除规则,开放指定端口,屏蔽指定 ip,ip 段,等等基本功能。

安装

sudo apt-get install iptables

iptables 防火墙用于创建过滤规则和 NAT(网络地址转换) 规则,几乎所有 Linux 发行版都能使用。 iptables 的结构 iptables -> Tables -> Chains -> Rules ,简单地,Tables 由 Chains 组成,Chains 又由 Rules 组成。

Table 组成

iptables 具有 Filter,NAT,Mangel,Raw,security 这几种内建表:

Filter 表

Filter 是 iptables 默认表,内建链

  • INPUT 链,处理来自外部的数据
  • OUTPUT 链,处理向外发送的数据
  • FORWARD 链,将数据转发到本机的其他网卡设备

NAT 表

三种内建链:

  • PREROUTING 链,处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标 IP 地址(destination ip address),通常用于 DNAT
  • POSTROUTING 链,处理即将离开本机的数据包,将会转换数据包中的源 IP 地址(source ip address),通常用于 SNAT(source NAT)
  • OUTPUT 链,处理本机产生的数据包

Mangel 表

Mangle 表用于指定如何处理数据包,它能改变 TCP 头中的 QoS 位,5 个内建链:

  • PREROUTING
  • INPUT
  • FORWARD
  • OUTPUT
  • POSTROUTING

Raw 表

Raw 表用于处理异常,具有两个内建链:

  • PREROUTING
  • OUTPUT

iptables 规则

关键点

  • Rules 包括一个条件和一个目标
  • 如果满足条件,就执行目标 target 中的规则或者特定值
  • 如果不满足条件,就判断下一条 rule

下面是 target 中指定的特殊值:

  • ACCEPT 允许防火墙接受数据包
  • DROP 防火墙丢弃包
  • QUEUE 防火墙将数据包移交到用户空间
  • RETURN 防火墙停止执行当前链后续 rules,并返回到调用链中

查看规则

查看已添加的 iptables 规则

iptables -t filter --list           # 使用 -t 来指定表,默认为 filter 表
iptables -L -n
iptables -nvL --line-numbers

解释

  • -t: 指定 table
  • -n:只显示 IP 地址和端口号,不将 ip 解析为域名

将所有 iptables 以序号标记显示

iptables -L -n --line-numbers

在输出结果中可以看到如下字段:

  • num 指定链中规则编号
  • target 前文中提及的 target 指定值
  • prot 协议 tcp, udp,icmp 等
  • source 数据包源 IP 地址
  • destination 数据包目标 IP 地址

常用参数

常见的一些命令选项

-A

使用 -A 命令追加新规则,其中 -A 表示 Append,新规则将追加到链尾。

iptables -A [chain] [firewall-rule]

解释:

  • -A chain 指定要追加规则的链
  • firewall-rule 具体的规则参数

下面是描述规则的基本参数

-p 协议

可以使用 -p 来指定规则协议,比如 tcp,udp, icmp 等等,使用 all 来指定所有协议。

另外也可以使用协议值(比如 6 代表 tcp)来指定协议,映射关系可以查看 /etc/protocols

-s 源地址

使用 -s 来指定数据包的源地址,参数可以使用 IP 地址,网络地址,主机名

  • -s 192.168.1.101 指定 IP
  • -s 192.168.1.10/24 网络地址
  • 如果不指定 -s 表示所有地址

-d 目标地址

-d 来指定目的地址,参数和 -s 相同

-j 执行目标

-j 代表 jump to target,指定了当与规则匹配时如何处理包

可能值为 ACCEPT,DROP,QUEUE,RETURN,也能指定其他链(chain) 来作为目标

-i 输入接口

-i 代表输入接口,-i 指定了要处理来自哪个接口的数据包,这些包即将进入 INPUT,FORWARD,PREROUTE 链。

比如 -i eth0 指定了要处理通过 eth0 进入的数据包,如果不指定 -i 参数那么将处理所有接口的数据包。

  • ! -i eth0 处理所有经由 eth0 以外的接口进入的数据包
  • -i eth+ 将处理所有经由 eth 开头的接口进入的数据包

也可以使用 --in-interface

-o 输出

-o 代表 output interface, -o 制定了数据包由哪个接口输出,这些数据包即将进入 FORWARD,OUTPUT,POSTROUTING 链

如果不指定 -o 选项,那么系统上所有接口都可以作为输出接口

  • ! -o eth0 那么将从 eth0 以外的接口输出
  • -i eth+ 那么将仅从 eth 开头的接口输出

也可以使用 --out-interface 参数

–sport 源端口

针对 -p tcp 或者 -p udp 缺省情况下,将匹配所有端口。可以指定端口号或者端口名,比如

  • --sport 22
  • --sport ssh
  • --sport 22:100 # 使用冒号匹配端口范围

上述关系可以再 /etc/services 文件中查阅

同理 --dport 是指定目的端口

新建或者删除 Chain

使用 -N,比如:

iptables -t nat -N SHADOWSOCKS
iptables -t nat -X SHADOWSOCKS
iptables -t nat -E SHADOWSOCKS SS
iptables -t nat -F SHADOWSOCKS

解释:

  • -N 新建 Chain
  • -X 删除
  • -E 重命名
  • -F 删除 Chain 中所有规则

清理规则

清除已有 iptables 规则

iptables -F     # 刷新所有链
iptables --flush     # 刷新所有链
iptables -t NAT -F      # 有些发行版 `-F` 命令并不会清除 NAT 表中的规则
iptables -X     # 删除表中所有非默认链

允许本地回环接口(即运行本机访问本机)

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT

允许所有本机向外的访问

iptables -A OUTPUT -j ACCEPT

允许访问 22 端口,允许某 IP 访问指定端口,以 22 端口为例命令是

iptables -A INPUT -p tcp --dport 22 -j ACCEPT                         # 允许所有的 IP 访问 22 端口
iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j ACCEPT           # 允许某个 IP 访问
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT       # 允许 IP 段访问

允许外部访问 80 端口

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

允许 FTP 服务的 21 和 20 端口

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT

如果有其他端口稍微修改上述语句中的端口号即可

允许已建立的或相关连的通行

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

禁止访问

禁止其他未允许的规则访问

注意:如果 22 端口未加入允许规则,SSH 链接会直接断开

屏蔽单个 IP 的命令是

iptables -I INPUT -s 123.45.6.7 -j DROP

封整个段即从 123.0.0.1 到 123.255.255.254 的命令

iptables -I INPUT -s 123.0.0.0/8 -j DROP

封 IP 段即从 123.45.0.1 到 123.45.255.254 的命令

iptables -I INPUT -s 124.45.0.0/16 -j DROP

封 IP 段即从 123.45.6.1 到 123.45.6.254 的命令是

iptables -I INPUT -s 123.45.6.0/24 -j DROP

屏蔽某 IP 访问指定端口,以 22 端口为例命令是

iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j DROP

删除规则

删除已添加的 iptables 规则

比如要删除 INPUT 里序号为 8 的规则,执行:

iptables -D INPUT 8

保存和恢复配置规则

保存生效的配置,让系统重启的时候自动加载有效配置(iptables 提供了保存当前运行的规则功能)

iptables-save > /etc/iptables.rules

恢复规则可以使用:

iptables-restore < /etc/iptables.rules

但是系统并不会在启动时自动执行该规则,所以需要在 /etc/network/if-pre-up.d/ 目录中添加脚本

#!/bin/bash
iptables-restore < /etc/iptables.rules

让系统在开机时自动加载规则

其他应用

防止 DDos

iptables -A INPUT -p tcp --dport 80 -m limit --limit 30/minute --limit-burst 100 -j ACCEPT

解释:

  • -limit 30/minute: 最大每个分钟 30 个连接
  • limit-burst 100: 用来表示只有达到这个连接数量之后才会触发 limit/minute 限制

端口转发

下面的例子,将 422 端口的流量转发到 22 端口,意味着 incoming ssh 连接可以从 22 端口或者 422 端口:

iptables -t nat -A PREROUTING -p tcp -d 192.168.2.104 --dport 422 -j DNAT --to 192.168.2.104:22

另外也要显示的让 422 流量通过

iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT

reference