本文摘录自我的书《Linux in Action》以及 Manning 的第二个尚未发布的项目。
防火墙
防火墙是一组规则。当数据包移入或移出受保护的网络空间时,会根据防火墙规则测试其内容(特别是关于其来源、目标以及计划使用的协议的信息),以查看是否应允许其通过。 这是一个简单的例子

防火墙可以根据协议或基于目标的规则过滤请求。
一方面,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 的盒装 PC,邀请顾客和路人浏览内容。 大多数自助服务终端的问题在于,您通常不希望用户随意使用它们,并将它们当作自己的设备。 它们通常不用于浏览、观看 YouTube 视频或对五角大楼发起拒绝服务攻击。 因此,为了确保它们不被滥用,您需要锁定它们。
一种方法是应用某种自助服务终端模式,无论是通过巧妙地使用 Linux 显示管理器还是在浏览器级别。 但是为了确保您已堵住所有漏洞,您可能还需要通过防火墙添加一些硬网络控制。 在以下部分中,我将描述如何使用 iptables 来完成此操作。
关于使用 iptables,有两件重要的事情要记住:您给出规则的顺序至关重要,并且 iptables 规则本身在重新启动后无法生存。 我将在这里逐一解决这些问题。
自助服务终端项目
为了说明这一切,让我们想象一下,我们为一家商店工作,该商店是一家名为 BigMart 的大型连锁店的一部分。 他们已经存在了几十年; 事实上,我们想象中的祖父母可能在那里长大。 但如今,BigMart 公司总部的员工可能只是在倒计时亚马逊彻底击垮他们的日子。
尽管如此,BigMart 的 IT 部门正在尽最大努力,他们刚刚向您发送了一些支持 WiFi 的自助服务终端设备,您需要将这些设备安装在您商店的战略位置。 这样做的目的是,它们将显示一个 Web 浏览器,该浏览器已登录到 BigMart.com 产品页面,允许他们查找商品功能、通道位置和库存水平。 自助服务终端还需要访问 bigmart-data.com,其中存储了许多图像和视频媒体。
除此之外,您还需要允许更新,并在必要时允许软件包下载。 最后,您需要仅允许从本地工作站进行入站 SSH 访问,并阻止其他人。 下图说明了这一切将如何运作

由 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 发出软件升级请求时,当它命中其适当的规则时,它将通过。 显然,我们在这里所做的是仅允许传出的 HTTP 或 HTTPS 请求到达我们的 BigMart 或 Ubuntu 目标,而没有其他目标。
最后两个规则将处理传入的 SSH 请求。 它们不会被之前的两个 drop 规则拒绝,因为它们不使用端口 80 或 443,而是 22。 在这种情况下,来自我的工作站的登录请求将被接受,但来自其他任何地方的请求将被丢弃。 这很重要:确保您用于端口 22 规则的 IP 地址与您用于登录的计算机的地址匹配——如果您不这样做,您将被立即锁定。 当然,这没什么大不了的,因为按照当前的配置方式,您可以简单地重新启动服务器,iptables 规则将被全部删除。 如果您使用 LXC 容器作为服务器并从 LXC 主机登录,请使用您的主机用于连接到容器的 IP 地址,而不是其公共地址。
如果我的机器的 IP 发生更改,您需要记住更新此规则; 否则,您将被锁定。
在家一起玩(希望在某种一次性 VM 上)? 太棒了。 创建您自己的脚本。 现在我可以保存脚本,使用 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 的防火墙上的连接问题。
10 条评论