帮助

配置 iptables 防火墙

Iptables 是专为 Linux 操作系统设计的防火墙,用于控制网络流量的通行。当有连接尝试访问服务器(或服务器向外发送请求)时,Iptables 会针对该连接检查规则链,并执行相应的设置。

所有现代 Linux 发行版都默认安装了 Iptables。

链的类型

iptables 有三种类型的链:INPUT、OUTPUT 和 FORWARD。

  • INPUT — 用于处理入站连接。
  • OUTPUT — 用于处理出站连接。
  • FORWARD — 用于处理转发流量,例如路由器上的流量。如果您不需要配置路由,则不需要此类规则。

链是一组有序的规则。每条规则都包含一个匹配条件(例如数据包的源 IP 地址)以及对符合该条件的数据包要执行的动作(例如“允许”)。如果没有指定条件,则该规则适用于所有数据包。

在决定如何处理数据包时,iptables 会从规则列表的开头依次检查相应的链,直到找到匹配项为止。如果没有找到匹配项(连接不符合任何已创建的规则),则应用默认规则。

配置 iptables 规则时需要注意,许多端口要成功传输数据,需要先建立连接并收到响应。另外要小心,不要意外把自己拦在外面,例如通过 SSH 远程连接服务器也属于入站连接。

对连接执行的动作

可以对连接执行以下三种动作:

Accept — 允许连接。

Drop — 忽略(阻止)连接,且不向来源发送阻止通知。建议对连接到互联网的端口上的流量使用此动作,因为这样攻击者在扫描端口时获得的信息最少。

Reject — 拒绝连接,并通知请求来源连接已被阻止。默认会返回 "icmp-port-unreachable" 响应包,也可以另外指定其他消息(例如 "icmp-host-unreachable"、"icmp-net-prohibited"、"icmp-host-prohibited" 等)。

配置规则

本文中配置规则的通用格式如下:

iptables 操作 链 规则

该格式中省略了表,因为我们讨论的是主过滤表 filter 的配置,iptables 命令默认使用该表,无需额外指定。

这里的操作是指对规则执行的步骤(例如添加或删除规则)。

iptables 中可用操作的示例:

  • -A — 向链中添加规则;
  • -I — 按指定编号向链中插入规则;
  • -D — 删除规则;
  • -F — 删除所有规则;
  • -L — 列出当前链中的所有规则;
  • -P — 设置默认动作。

其他选项:

  • -p — 指定数据包的协议;
  • -s — 指定数据包的源 IP 地址;
  • -j — 指定如何处理数据包(允许、阻止等)。

查看现有规则

使用以下命令列出所有规则:

iptables -L

或者使用输出更详细的命令:

iptables -L -n -v

您也可以查看特定链的规则,例如 INPUT 链:

iptables -L INPUT

默认规则

如果已创建的规则都不匹配入站数据包,则会应用默认规则。

要查看默认规则,请执行以下命令:

iptables -L | grep policy

如果您没有更改过默认策略,那么所有链初始都设置为允许。

配置 iptables 防火墙

要设置默认规则,请使用 -P 选项,例如:

iptables -P FORWARD DROP

配置示例

要向现有链中添加规则,请执行:

iptables -A

如果需要将规则放在列表中的其他位置而非末尾,可以使用以下命令格式并指定规则在列表中的编号:

iptables -I 链 编号 规则

例如,以下规则将成为 INPUT 链中的第一条规则:

iptables -I INPUT 1 --dport 80 -j ACCEPT

阻止来自特定 IP 的所有入站连接:

iptables -A INPUT -s 1.2.3.4 -j DROP

阻止来自特定子网的连接:

iptables -A INPUT -s 1.2.3.4/24 -j DROP

来源既可以是 IP 地址,也可以是主机名。例如,禁止来自 test.domain.ru 的所有连接:

iptables -A INPUT -s test.domain.ru -j DROP

禁止来自 test.domain.ru 以外主机的连接:

iptables -A INPUT ! -s test.domain.ru -j DROP

向所有人开放 25 端口(SMTP):

iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT

对所有人封禁 25 端口(SMTP)(只需将 ACCEPT 替换为 DROP):

iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j DROP

向所有人开放 Apache 端口:

iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT 
iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT

允许特定 IP 访问 3306 端口(MySQL):

iptables -A INPUT -s 1.2.3.4 -p tcp -m tcp --dport 3306 -j ACCEPT

配置日志记录:

iptables -A INPUT -p tcp -m multiport --dports 22,53,8080,139,445 -j LOG --log-level INFO --log-prefix "New connection from 1.2.3.4/24:" 
iptables -A INPUT -s 1.2.3.4/24 -m multiport --dports 22,8080,139,445 -j ACCEPT

这样配置后,来自 1.2.3.4/24 子网到服务器的每个新连接都会被记录到日志中。

为防御常见攻击,可以添加以下设置:

阻止所有“无法识别”的数据包:

iptables -A INPUT -m state --state INVALID -j DROP

阻止空数据包:

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

防御 syn-flood 攻击:

iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP 
iptables -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP

阻止分片数据包并防御 ping flood:

iptables -A INPUT -p icmp --fragment -j LOG --log-prefix "ping flooding" 
iptables -A INPUT -p icmp --fragment -j DROP

禁止 ping:

iptables -A INPUT -p icmp --icmp-type echo-request -j DROP 
iptables -A INPUT -i eth0 -p icmp --icmp-type echo-request -j DROP

允许特定地址 ping:

iptables -A INPUT -s 1.2.3.4 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -s 1.22.33.44 -p icmp --icmp-type echo-request -j ACCEPT

将 80 端口的并发连接数(connlimit)限制为 5:

iptables -A INPUT -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 5 --connlimit-mask 32 -j DROP

保存更改

为了让已创建的规则在系统重启后仍然有效,需要将其保存。

在 CentOS 上使用以下命令:

/sbin/service iptables save

如果您使用的是 Debian 或 Ubuntu,建议安装 iptables-persistent 软件包来保存规则。可以使用以下命令安装:

apt install iptables-persistent

安装过程中会询问是否保存当前规则,请选择“是”。

修改 iptables 规则后,执行以下命令保存:

netfilter-persistent save

删除规则

要删除特定规则,请使用 -D 选项,例如:

iptables -D INPUT -s 1.2.3.4 -j DROP

要删除所有规则,请执行以下命令:

iptables -F

要删除特定链的规则,请执行:

iptables -F INPUT

如有任何疑问,请联系我们