Linux 防火墙:关于 iptables 和 firewalld 你需要了解的

这里是如何使用 iptables 和 firewalld 工具来管理 Linux 防火墙连接规则。
410 位读者喜欢此文。
open network

Opensource.com

本文摘自我的书 Linux in Action 和即将发布的第二个 Manning 项目。

防火墙

防火墙是一组规则。当数据包进入或离开受保护的网络空间时,其内容(特别是关于其来源、目标和计划使用的协议的信息)会根据防火墙规则进行测试,以查看是否允许通过。这是一个简单的例子

firewall filtering request

防火墙可以根据协议或基于目标的规则过滤请求。

一方面,iptables 是一种在 Linux 机器上管理防火墙规则的工具。

另一方面,firewalld 也是一种在 Linux 机器上管理防火墙规则的工具。

你对此有意见吗? 如果我告诉你还有另一个叫做 nftables 的工具,你会觉得扫兴吗?

好吧,我承认整件事闻起来有点奇怪,所以让我解释一下。这一切都始于 Netfilter,它控制 Linux 内核模块级别对网络堆栈的访问。 几十年来,用于管理 Netfilter 钩子的主要命令行工具是 iptables 规则集。

因为调用这些规则所需的语法可能有点晦涩难懂,所以引入了各种用户友好的实现,例如 ufw 和 firewalld 作为更高级别的 Netfilter 解释器。 然而,Ufw 和 firewalld 主要旨在解决独立计算机面临的各种问题。 构建完整的网络解决方案通常需要 iptables 的额外力量,或者自 2014 年以来,需要其替代品 nftables(通过 nft 命令行工具)。

iptables 并没有消失,并且仍然被广泛使用。 事实上,作为管理员,您应该期望在您的工作中遇到受 iptables 保护的网络很多年。 但是,nftables 通过添加到经典的 Netfilter 工具集,带来了一些重要的新功能。

从现在开始,我将通过示例说明 firewalld 和 iptables 如何解决简单的连接问题。

使用 firewalld 配置 HTTP 访问

正如您可能从其名称中猜到的那样,firewalld 是 systemd 系列的一部分。 firewalld 可以安装在 Debian/Ubuntu 机器上,但默认情况下存在于 Red Hat 和 CentOS 上。 如果您的机器上运行着像 Apache 这样的 Web 服务器,您可以通过浏览到您服务器的 Web 根目录来确认防火墙是否正常工作。 如果该站点无法访问,则 firewalld 正在完成其工作。

您将使用 firewall-cmd 工具从命令行管理 firewalld 设置。 添加 –state 参数会返回当前的防火墙状态

# firewall-cmd --state
running

默认情况下,firewalld 将处于活动状态,并且会拒绝所有传入流量,但有几个例外,例如 SSH。 这意味着您的网站不会获得太多的访问者,这肯定会为您节省大量数据传输成本。 但是,由于这可能不是您对 Web 服务器的期望,因此您需要打开通常指定为 80 和 443 的 HTTP 和 HTTPS 端口。 firewalld 提供了两种方法来做到这一点。 一种是通过 –add-port 参数,该参数直接引用端口号以及它将使用的网络协议(在这种情况下为 TCP)。 –permanent 参数告诉 firewalld 每次服务器启动时都加载此规则

# firewall-cmd --permanent --add-port=80/tcp
# firewall-cmd --permanent --add-port=443/tcp

–reload 参数会将这些规则应用于当前会话

# firewall-cmd --reload

想知道防火墙上的当前设置吗? 运行 –list-services

# firewall-cmd --list-services
dhcpv6-client http https ssh

假设您已按照之前的描述添加了浏览器访问权限,则 HTTP、HTTPS 和 SSH 端口现在都应该打开,以及 dhcpv6-client,它允许 Linux 从本地 DHCP 服务器请求 IPv6 IP 地址。

使用 iptables 配置锁定的客户自助服务终端

我相信你已经见过自助服务终端了——它们是机场、图书馆和企业随意摆放的平板电脑、触摸屏和类似 ATM 的盒装电脑,邀请顾客和路人浏览内容。 大多数自助服务终端的问题是,您通常不希望用户让他们宾至如归,并将它们视为自己的设备。 它们通常不是用于浏览、观看 YouTube 视频或对五角大楼发起拒绝服务攻击。 因此,为了确保它们不被滥用,你需要锁定它们。

一种方法是应用某种自助服务终端模式,无论是通过巧妙地使用 Linux 显示管理器还是在浏览器级别。 但为了确保你堵住了所有的漏洞,你可能还需要通过防火墙添加一些硬网络控制。 在以下部分中,我将描述如何使用 iptables 来做到这一点。

关于使用 iptables,有两件重要的事情需要记住:你给出规则的顺序至关重要,并且 iptables 规则本身在重新启动后不会保留。 我将在这里一次解决一个问题。

自助服务终端项目

为了说明这一切,让我们想象一下,我们为一家名为 BigMart 的大型连锁店工作。 他们已经存在了几十年了; 事实上,我们想象中的祖父母可能在那里购物长大。 但如今,BigMart 公司总部的家伙们可能只是在计算亚马逊彻底击垮他们之前的剩余时间。

尽管如此,BigMart 的 IT 部门正在尽最大努力,他们刚刚向您发送了一些支持 WiFi 的自助服务终端设备,您需要将它们安装在商店内的战略位置。 想法是,他们将显示一个 Web 浏览器,该浏览器已登录到 BigMart.com 产品页面,允许他们查找商品功能、通道位置和库存水平。 自助服务终端还需要访问 bigmart-data.com,其中存储了许多图像和视频媒体。

除此之外,您还需要允许更新,并在必要时允许软件包下载。 最后,您只想允许从您的本地工作站进行入站 SSH 访问,并阻止其他所有人。 下图说明了它的工作原理

kiosk traffic flow ip tables

由 iptables 控制的自助服务终端流量。

脚本

以下是如何将所有这些整合到 Bash 脚本中

#!/bin/bash
iptables -A OUTPUT -p tcp -d bigmart.com -j ACCEPT
iptables -A OUTPUT -p tcp -d bigmart-data.com -j ACCEPT
iptables -A OUTPUT -p tcp -d ubuntu.com -j ACCEPT
iptables -A OUTPUT -p tcp -d ca.archive.ubuntu.com -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j DROP
iptables -A OUTPUT -p tcp --dport 443 -j DROP
iptables -A INPUT -p tcp -s 10.0.3.1 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP

我们规则的基本结构以 -A 开头,告诉 iptables 我们想要添加以下规则。 OUTPUT 表示此规则应成为 OUTPUT 链的一部分。 -p 表示此规则仅适用于使用 TCP 协议的数据包,其中 -d 告诉我们,目的地是 bigmart.com-j 标志指向 ACCEPT 作为数据包匹配规则时要采取的操作。 在第一个规则中,该操作是允许或接受请求。 但在下面,您可以看到将被丢弃或拒绝的请求。

请记住,顺序很重要。 这是因为 iptables 会将请求传递给它的每个规则,但仅在获得匹配时才会停止。 因此,例如,对 youtube.com 的传出浏览器请求将通过前四个规则,但当它到达 –dport 80–dport 443 规则时,它将被丢弃,具体取决于它是 HTTP 还是 HTTPS 请求。 iptables 不会费心进一步检查,因为这是一个匹配项。

另一方面,当系统请求 ubuntu.com 进行软件升级时,它会在命中其适当的规则时通过。 显然,我们在这里做的是仅允许对我们的 BigMart 或 Ubuntu 目的地(而不是其他目的地)发出 HTTP 或 HTTPS 请求。

最后两个规则将处理传入的 SSH 请求。 它们不会因为它们不使用端口 80 或 443,而是使用 22,而被之前的两个丢弃规则拒绝。 在这种情况下,来自我的工作站的登录请求将被接受,但来自其他任何地方的请求将被丢弃。 这很重要:确保您用于端口 22 规则的 IP 地址与您用于登录的机器的地址匹配——如果您不这样做,您将被立即锁定。 当然,这没什么大不了的,因为按照当前的配置方式,您可以简单地重新启动服务器,并且所有 iptables 规则都将被删除。 如果您使用 LXC 容器作为您的服务器并从您的 LXC 主机登录,则使用您的主机用于连接到容器的 IP 地址,而不是其公共地址。

如果我的机器的 IP 发生变化,您需要记住更新此规则; 否则,您将被锁定。

在家玩(希望是在某种一次性虚拟机上)? 很好。 创建你自己的脚本。 现在我可以保存脚本,使用 chmod 使其可执行,并以 sudo 身份运行它。 不用担心 bigmart-data.com not found 错误——当然找不到它; 它不存在。

chmod +X scriptname.sh
sudo ./scriptname.sh

您可以使用 cURL 从命令行测试您的防火墙。 请求 ubuntu.com 可以工作,但 manning.com 失败。

curl ubuntu.com
curl manning.com

配置 iptables 在系统启动时加载

现在,如何让这些规则在每次自助服务终端启动时自动加载? 第一步是使用 iptables-save 工具将当前规则保存到 .rules 文件。 这将在根目录中创建一个包含规则列表的文件。 管道,然后是 tee 命令,对于将我的 sudo 权限应用于字符串的第二部分是必要的:实际将文件保存到其他受限的根目录。

然后,我可以告诉系统每次启动时都运行一个名为 iptables-restore 的相关工具。 我们在前一个模块中看到的常规 cron 作业没有帮助,因为它们是在设置的时间运行的,但我们不知道我们的计算机何时可能会决定崩溃并重新启动。

有很多方法可以处理这个问题。 这是一个

在我的 Linux 机器上,我会安装一个名为 anacron 的程序,它会在 /etc/ 目录下生成一个名为 anacrontab 的文件。我会编辑该文件并添加这个 iptables-restore 命令,告诉它每天(必要时)在启动后一分钟将 .rules 文件的当前值加载到 iptables 中。我会为该作业指定一个标识符 (iptables-restore),然后添加命令本身。既然您在家也在跟我一起操作,您应该通过重启系统来测试所有这些。

sudo iptables-save | sudo tee /root/my.active.firewall.rules
sudo apt install anacron
sudo nano /etc/anacrontab
1 1 iptables-restore iptables-restore < /root/my.active.firewall.rules

我希望这些实际例子说明了如何使用 iptables 和 firewalld 来管理基于 Linux 的防火墙上的连接问题。

标签
David Clinton
DAVID CLINTON 是一名系统管理员、教师和作家。他管理、撰写并创建了许多重要技术主题的培训材料,包括 Linux 系统、云计算(尤其是 AWS)和容器技术,如 Docker。

10 条评论

您也可以考虑使用 iptables-persistent 包,作为一种在启动时自动恢复 iptables 的方法。比使用 anacron 更容易。

感谢您的解释。在此之前,每次我使用 iptables 时,我都只是盲目地按照别人的说明操作,而不理解我正在做什么 :p

您好 David,

在以下几行中

iptables -A OUTPUT -p tcp -d bigmart.com -j ACCEPT
iptables -A OUTPUT -p tcp -d bigmart-data.com -j ACCEPT
iptables -A OUTPUT -p tcp -d ubuntu.com -j ACCEPT
iptables -A OUTPUT -p tcp -d ca.archive.ubuntu.com -j ACCEPT

看来*所有*的 TCP 流量,而不仅仅是 TCP 80 和 443,都将被允许到这四个主机。 这是因为没有使用“--dport”(或“目标端口”)开关。 这是你的意图吗?

第 5 行和第 6 行很好地说明了这一点。 在这里,你*将*阻止 TCP 端口 80 和 443,而且只有这两个端口。 其他一切都将被允许出去,包括在 TCP 8080、TCP 8443 等端口上运行的代理。

特定于 SSH 的阻止是可以的。 但是,它只会阻止来自其他主机的 SSH。 听起来像 kiosk 机器应该阻止更多的入站流量。

我锁定流量的方法是专门允许仅将 TCP 80 和 443 端口到这些主机,以及仅将 DNS 流量到我的 DNS 服务器,出站,如下所示。

#!/bin/bash
# 让我们打开连接跟踪,也就是有状态跟踪,以让
# 我们允许的出站流量返回
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# 允许环回与我们通信,否则可能会破坏一些东西
iptables -A INPUT -i lo -j ACCEPT

# 首先,仅允许 DNS 出站到我的 DNS 服务器,包括 UDP 和 TCP
iptables -A OUTPUT -p udp -d --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp -d --dport 53 -j ACCEPT

# 然后,让我们想要发出的 Web 流量发出
iptables -A OUTPUT -p tcp -d bigmart.com --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -d bigmart.com --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp -d bigmart-data.com --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -d bigmart-data.com --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp -d ubuntu.com --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -d ubuntu.com --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp -d ca.archive.ubuntu.com --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -d ca.archive.ubuntu.com --dport 443 -j ACCEPT

# 仅允许从该工作站进行 SSH 流量
iptables -A INPUT -p tcp -s 10.0.3.1 --dport 22 -j ACCEPT

# 取消注释以下两行以在需要时允许 DHCP,
# 也就是说,如果此框通过 DHCP 获取其 IP 地址(而不是静态分配)
#iptables -A INPUT -p udp --dport 68
#iptables -A OUTPUT -p udp --dport 67

# 拒绝其他一切!
iptables -A INPUT -s 0.0.0.0/0 -j DROP
iptables -A OUTPUT -d 0.0.0.0/0 -j DROP

您好,
您说得对,我的规则确实允许所有出站流量。 我这样做是因为我不能 100% 确定软件和数据升级是否需要通过不同的(非 HTTP)端口进行访问。 不过,我的想法是,我完全信任这四个网站,因此允许完全访问不是一个主要风险。
谢谢!

回复 by Sum Yung Gai (not verified)

很好的信息,写得很好。

我不太擅长网络,但到目前为止,这一切似乎都很有意义。

除了他写的关于 iptables 的几乎所有内容都是不正确的。

他甚至没有引用 /etc/sysconfig/iptables,该文件是 iptables 启动时默认读取的文件。

回复 by dragonbite

好文章。 我注意到这篇文章没有提到 system-config-firewall
或 lokkit。 我仍然在 el6 服务器上同时使用这两个。

我刚刚发现 lokkit 在 el7 上可用。 有人使用它吗?

“iptables 规则在重新启动后不会保留” 错误的说法。

iptables-save > /etc/sysconfig/iptables

完成。

您好,有趣的文章!

但有两件小事

1- cron 实际上可以在重新启动时运行命令,您可以使用这样的行

@reboot /sbin/iptables-restore < /root/my.active.firewall.rules

请记住,cron 的 PATH 不包含 /sbin、/usr/sbin 或 /usr/local/sbin,因此请确保使用 iptables-restore 的完整路径。

2- 我通常更喜欢使用 REJECT 而不是 DROP 作为 iptables 规则。 后者会丢弃数据包,这意味着您必须等待一个(很长的)超时,前者会立即拒绝。

干杯!

Creative Commons License本作品已获得 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.