配置防火墙iptables
介绍
实施防火墙是保护服务器安全的重要一步。其中很大一部分是决定将对您的网络实施流量限制的单个规则和策略。像iptables
这样的防火墙还允许您对应用规则的结构框架有发言权。
在本指南中,您将学习如何构建防火墙,作为更复杂规则集的基础。该防火墙将主要关注提供合理的默认值和建立鼓励扩展性的框架。
安装持久防火墙服务
首先更新本地包缓存:
现在安装iptables-persistent
软件包。这允许您保存规则集,并在引导时自动应用它们:
1
| apt install iptables-persistent
|
在安装过程中,系统会询问您是否要保存当前规则,请选择****。请注意,您将运行netfilter-persistent
命令来执行iptables
永久防火墙服务。接下来,您将编辑生成的规则文件。
本指南中关于IPv6的说明
在开始之前,我们将简要讨论IPv4与IPv6。iptables
命令仅处理IPv4流量。对于IPv6流量,使用了一个名为ip6tables
的单独配套工具。规则存储在单独的表和链中。对于netfilter-persistent
命令,IPv4规则写入/etc/iptables/rules.v4
并从中读取,IPv6规则存储在/etc/iptables/rules.v6
中。
本指南假设您没有在服务器上积极使用IPv6。如本指南所示,如果您的服务不利用IPv6,则完全阻止访问更安全。
重置防火墙
首先重置防火墙规则,以便查看如何从命令行构建策略。运行以下命令刷新所有规则:
1
| netfilter-persistent flush
|
现在验证规则是否已重置:
您应该有输出,显示filter
表中的规则已消失,并且所有链上的默认策略设置为ACCEPT
:
1 2 3
| -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT
|
清空配置
1 2 3
| iptables -F iptables -X iptables -Z
|
ipv6
1 2 3
| ip6tables -F ip6tables -X ip6tables -Z
|
创建协议特定链
接下来,您将创建所有特定于协议的链。这些将用于保存为要公开的服务创建拒绝策略例外的规则。您将为UDP
流量创建一个:
然后是TCP
的另一个:
ICMP
还有一个:
配置,允许回环网卡
您还需要允许来自本地环回接口的所有流量。这是由服务器生成并发送到服务器的流量。主机上的服务使用它来相互通信:
1
| iptables -A INPUT -i lo -j ACCEPT
|
1
| ip6tables -A INPUT -i lo -j ACCEPT
|
允许ping
1
| iptables -A INPUT -p icmp -j ACCEPT
|
1
| ip6tables -A INPUT -p icmpv6 -j ACCEPT
|
允许DHCPv6
1
| ip6tables -I INPUT -p udp --dport 546 -j ACCEPT
|
允许ssh
1
| iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
1
| ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
|
允许ftp
1 2
| iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --dport 20 -j ACCEPT
|
1 2
| ip6tables -A INPUT -p tcp --dport 21 -j ACCEPT ip6tables -A INPUT -p tcp --dport 20 -j ACCEPT
|
允许ftp被动接口范围,在ftp配置文件里可以设置
1
| iptables -A INPUT -p tcp --dport 20000:30000 -j ACCEPT
|
1
| ip6tables -A INPUT -p tcp --dport 20000:30000 -j ACCEPT
|
学习felix,把smtp设成本地
1 2
| iptables -I INPUT -p tcp -m tcp --dport 25 -j ACCEPT -s 127.0.0.1 iptables -I INPUT -p tcp -m tcp --dport 25 -j REJECT
|
1 2
| ip6tables -I INPUT -p tcp -m tcp --dport 25 -j ACCEPT -s 127.0.0.1 ip6tables -I INPUT -p tcp -m tcp --dport 25 -j REJECT
|
允许DNS
1 2
| iptables -I INPUT -p tcp -m tcp --dport 53 -j ACCEPT iptables -I INPUT -p udp -m udp --dport 53 -j ACCEPT
|
1 2
| ip6tables -I INPUT -p tcp -m tcp --dport 53 -j ACCEPT ip6tables -I INPUT -p udp -m udp --dport 53 -j ACCEPT
|
允许http和https
1 2
| iptables -I INPUT -p tcp --dport 80 -j ACCEPT iptables -I INPUT -p tcp --dport 443 -j ACCEPT
|
1 2
| ip6tables -I INPUT -p tcp --dport 80 -j ACCEPT ip6tables -I INPUT -p tcp --dport 443 -j ACCEPT
|
允许已建立的或相关连的通行
在INPUT
链中,所有传入流量开始过滤,我们需要添加通用规则。这些是一些常识规则,通过接受低风险的流量(本地流量和与我们已经检查的连接相关的流量)和丢弃明显无用的流量(无效数据包),为防火墙设置基线。
首先,创建一个例外,以接受作为已建立连接的一部分或与已建立连接相关的所有流量:
1 2 3
| iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
1 2 3
| ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
该规则使用conntrack
扩展,该扩展提供了内部跟踪,因此iptables
具有所需的上下文,以将数据包作为更大连接的一部分进行评估,而不是作为离散的、不相关的数据包流。TCP是一种基于连接的协议,因此已建立的连接定义得相当好。对于UDP和其他无连接协议,已建立的连接指的是已看到响应的流量(原始数据包的源将是响应数据包的目的地,反之亦然)。相关连接是指与现有连接关联启动的新连接。这里的经典示例是FTP数据传输连接,它与已经建立的FTP控制连接有关。
禁止其他未允许的规则访问
1 2
| iptables -A INPUT -j REJECT iptables -A FORWARD -j REJECT
|
1 2
| ip6tables -A INPUT -j REJECT ip6tables -A FORWARD -j REJECT
|
最后,拒绝所有无效数据包。由于多种原因,数据包可能无效。它们可能指的是不存在的连接,可能指向不存在的接口、地址或端口,也可能格式不正确。在任何情况下,您都会丢弃所有无效数据包,因为没有适当的方法来处理它们,而且它们可能代表恶意活动:
1
| iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
|
1
| ip6tables -A INPUT -m conntrack --ctstate INVALID -j DROP
|
创建到协议特定链的跳转规则
到目前为止,我们已经在INPUT
链中创建了一些一般规则,并在我们的协议特定链中为特定的可接受服务创建了一些规则。然而,目前,流量进入INPUT
链,无法到达我们的协议特定链。
现在,您需要将INPUT
链中的流量引导到适当的协议特定链中。您可以匹配协议类型以将其发送到正确的链。此外,确保数据包代表一个新的连接(任何已建立的或相关的连接都应该提前处理)。从UDP
流量开始:
1
| iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
|
1
| ip6tables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
|
接下来,对TCP
流量运行以下命令。请注意,对于TCP数据包,您将添加额外的要求,即数据包是_SYN_数据包,这是启动TCP连接的唯一有效类型:
1
| iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
|
1
| ip6tables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
|
然后对ICMP
流量运行以下操作:
1
| iptables -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
|
1
| ip6tables -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
|
拒绝所有剩余流量
如果传递给协议特定链的数据包不符合其中的任何规则,则控制将传递回INPUT
链。防火墙不允许任何达到这一点的行为。
您将使用REJECT
目标拒绝流量,该目标向客户端发送响应消息。这允许您指定出站消息传递,以便您可以模拟客户端尝试将数据包发送到常规封闭端口时将给出的响应。响应取决于客户端使用的协议。
试图到达关闭的UDP
端口将导致ICMP
消息,说明“无法访问端口”。您可以通过运行以下命令来模拟此操作:
1
| iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
|
1
| ip6tables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
|
尝试在封闭端口上建立TCP
连接会导致TCP RST响应:
1
| iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
|
1
| ip6tables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
|
对于所有其他数据包,您可以发送ICMP
“protocol unreachable”消息,以指示服务器不响应该类型的数据包:
1
| iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
|
1
| ip6tables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
|
调整默认策略
您添加的最后三条规则应处理INPUT
链中的所有剩余流量。但是,作为预防措施,您应该将默认策略设置为DROP
,如下所示:
如果此服务器未配置为其他机器的路由器,则还应在FORWARD
链中设置此策略:
1
| iptables -P FORWARD DROP
|
**警告:**当策略设置为DROP
时,如果用sudo iptables -F
清除iptables
,则当前SSH连接将被删除!使用sudo netfilter-persistent flush
刷新是清除规则的更好方法,因为它还将重置默认策略。
为了匹配删除所有流量的IPv6策略,可以使用以下ip6tables
命令,从INPUT
开始:
然后对FORWARD
运行以下操作:
1
| ip6tables -P FORWARD DROP
|
最后,设置OUTPUT
的策略:
1
| ip6tables -P OUTPUT DROP
|
这应该相当紧密地复制您的规则集。
保存iptables
条规则
在这一点上,你应该测试你的防火墙规则,确保它们阻止了你想要阻止的流量,同时不妨碍你的正常访问。一旦您确信您的规则运行正常,您可以保存它们,以便它们在引导时自动应用于您的系统。
通过运行以下命令保存当前规则(IPv4和IPv6):
1
| netfilter-persistent save
|
这将使用您在命令行上制定的策略覆盖/etc/iptables/rules.v4
和/etc/iptables/rules.v6
文件。
Docker与iptables 只允许特定ip访问Docker的服务
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
| Docker与iptables (在DOCKER-USER链中处理) Docker至少会在iptables规则中自动安装两个新链,一个是DOCKER,一个是DOCKER-USER,可以通过如下方式查看 iptables -S -t nat 查看DOCKER链规则 iptables -S 查看DOCKER-USER链规则 随着docker版本不同,可能还会有其他链,但一般来说,我们应该只修改DOCKER-USER链即可。 如果想要对docker端口做访问限制,可以参考如下规则:
iptables -I DOCKER-USER -i lo ! -s 127.0.0.1 -j DROP
ip6tables -I DOCKER-USER -i lo ! -s ::1 -j DROP
iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
iptables -I DOCKER-USER -m iprange -i ext_if ! --src-range 192.168.1.1-192.168.1.3 -j DROP
iptables -I DOCKER-USER -i eth1 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -I DOCKER-USER -i eth1 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
原文链接: Docker and iptables https://docs.docker.com/network/iptables/
|
结论
通过遵循本指南,或者直接将防火墙规则粘贴到配置文件中,或者在命令行上手动应用并保存它们,您已经创建了一个良好的初始防火墙配置。您必须添加单独的规则,以允许访问您想要提供的服务。
本指南中建立的框架应允许您进行调整,并有助于澄清您现有的政策。查看我们的其他一些指南,了解如何使用一些流行的服务构建防火墙策略:
- Iptables要点:通用防火墙规则和命令
- 如何设置Iptables防火墙以保护服务器之间的通信
- 如何通过带有Iptables的Linux网关转发端口
- 如何使用Nmap和Tcpdump测试防火墙配置