简介
Iptables 是一种应用程序,充许对 Linux 内核防火墙中的表进行管理。对于防火墙修改和常见的系统管理任务,您无需预先具备有关内核或其实际表的知识。
在一些 Linux 发行版中,默认启用 iptables。通常建议无经验的用户完全禁用 iptable,以避免出现网络问题。本文将帮助您快速上手并根据您的需求操作 iptables。
有时会使用 iptables 来指 Linux 内核级组件。在本文中,与 iptables 相关的一切均专指 Linux 发行版中控制协议(如 ipv4、ipv6 和 ARP 表)的应用程序。
与其他的 Linux 应用程序相似,您可以在命令行面或在纯文本文件中配置 iptables,允许使用任何文本编辑器进行编辑。虽然它易于修改,但与一般防火墙设备相比,则有点相形见拙,因为在一般防火墙设备中,可通过图形界面进行大多数设备和配置交互。有一些使用 iptables 的应用程序可通过图形界面管理防火墙,但是本文主要介绍在本地环境中(Linux 终端)实现 iptables 交互。
在使用 Linux 终端(也称为控制台或终端模拟器)方面具有一定的水平有助于开发人员利用下面所提供的示例和配置。命令行界面是与 iptables 进行交互的主要方法,Linux 终端则是允许访问该界面的应用程序。
所应用的规则大多数都具有非常强的可读性,并且可轻松地传输到其他服务器。此功能可在处理无反应硬件时节省大量的时间。
应用程序要求
虽然 iptables 是本文的主题,并且有可能已经安装在您的环境中,但是我们还是使用 nmap,它是另一款功能强大的应用程序。
继续之前请先检查是否已安装 nmap。您可以在 Debian/Ubuntu Linux 发行版中安装此高效的网络扫描仪。
清单 1. 在 Debian/Ubuntu 中安装 nmap
sudo apt-get install nmap
入门
几乎所有 Linux 发行版均提供 iptables,可供随时使用。确保在您的首选 shell 中具备可用的 iptables
命令。本文使用 Debian/Ubuntu 约定配置 iptables。
因为我们要在内核级上进行一些修改,所以要确保您拥有 root 权限。
清单 2 显示当前应用于服务器的规则。清单 2 将会在本文中重复使用以验证当前所使用的规则内容,以及检验是否成功实现更改。
清单 2. 当前应用的规则
root@desktop:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
在 清单 2 中,我们指示 iptables 列出当前应用于防火墙的所有规则。这是通过 -L 标志实现的。
该输出还提到了 Chain
。您可以将 iptable 链视为防火墙的一部分,允许某种类型的网络流量。例如,阻止从专用网络到互联网的所有网络流量,将在 OUTPUT 部分中设置该规则。同样地,将在 INPUT 链中显示影响传入流量的任何规则。
此三个链每个都应用于防火墙中的某一种类型的活动。此时,还未进行任何设置。这表示还未设立任何限制,所有的网络流量均可自由传入传出。
Chain INPUT
-
Chain FORWARD
,和 Chain OUTPUT
继续之前,有必要检查锁定后服务器上的哪些端口处于打开状态以进行比较。如前所述,nmap 是一款功能强大的命令行工具,可提供网络安全信息。清单 3 显示网络上远程服务器中 nmap 的输出。
清单 3. 使用 nmap 进行网络扫描
~ $ nmap 10.0.0.120
Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-11-21 20:44 EST
Nmap scan report for 10.0.0.120
Host is up (0.012s latency).
Not shown: 991 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
53/tcp open domain
80/tcp open http
631/tcp open ipp
3306/tcp open mysql
4001/tcp open unknown
5900/tcp open vnc
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 6.57 seconds
那些均是处于打开状态的端口!仅几个步骤,您就能了解配置 iptables 后如何修改以上这些内容。
虚拟并不一定就是好
当您掌握了 iptables,它能更好地帮助您在安装 Linux 的计算机而非虚拟机 (VM) 上执行本文的示例。虚拟主机和虚拟客户端之间的网络策略可能会使调试变得更加困难,并导致一些示例无法工作。先从物理环境开始,然后再不断努力创建一些更高级的虚拟环境。
可通过手动方式在纯文本文件中对防火墙规则进行应用与添加或编辑。我比较喜欢使用文本文件应用更改。在文本文件中进行编写,语法错误往往都能轻易地捕捉到。通过直接添加规则编辑规则带来的另一个问题是,当服务器重启时,无法保存这些规则。因此,在编辑文件前,我们要先告知 iptables 导出当前的规则,以便文件可作为我们的初始模板。请参见 清单 4。
清单 4. 将规则保存至一个文件
root@desktop:~# iptables-save > /etc/iptables.rules
root@desktop:~# cat /etc/iptables.rules
# Generated by iptables-save v1.4.4 on Sun Nov 21 14:48:48 2010
*filter
:INPUT ACCEPT [732:83443]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [656:51642]
COMMIT
# Completed on Sun Nov 21 14:48:48 2010
使用 iptables-save
命令,并将输出重定向至 "/etc" 目录下的一个文本文件中。我已经对此文件进行连接 (concatenated),所以您能看到我机器上的文件。
首要要求之一是允许创建连接以接收通信。在您希望防火墙(在专用网络中)背后的任何事项均可无限制地发送和接收网络数据时,您需要执行此项操作。在 清单 5 中,我们将向 iptables 发送一个直接的规则,并验证事后防火墙的状态。
清单 5. 创建的会话规则
root@desktop:~# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
root@desktop:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
要更好地了解发送的内容,让我们将命令拆开,并逐一进行解释:
-A INPUT
:将此规则添加至 INPUT
链。
-m conntrack
:对下列连接通信与当前的包/连接进行匹配。
-ctstate ESTABLISHED, RELATED
:规则将应用到的连接状态。在本例中,ESTABLISHED
连接代表能够看到两个方向数据包的连接,而 RELATED
类型代表,数据包开启一个新连接,但是与现有连接相关联。
-j ACCEPT
:告知防火墙接收之前描述的连接。-j
标记的另一个有效设置是 DROP
我还通过 SSH 协议连接至该服务器,所以在锁定防火墙时,清单 6 中的一条规则会允许所有传入的 SSH 通信。我指定了网络协议类型 (tcp) 以及方便与此 SSH 服务关联的端口。如果需要,您可以直接指定端口号。
清单 6. 接收入站 SSH 连接
root@desktop:~# iptables -A INPUT -p tcp --dport ssh -j ACCEPT
root@desktop:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
最后,让我们设置防火墙以阻止其他事项。在执行下列命令时要特别注意。如果将此放在所有其他规则前,那么它会阻止传入服务器的任何流量。Iptables 会以程序方式(自上而下)读取规则,并且在某条规则匹配后,就不会对其他事项进行评估。
清单 7. 阻止所有的传入流量
root@desktop:~# iptables -A INPUT -j DROP
root@desktop:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
DROP all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
清单 7 显示规则处于正常顺序,但是为了进行具体更改,让我们将这些规则保存到一个文件中,并对该文件进行连接以检查内容,如 清单 8 所示。
清单 8. 验证防火墙配置
root@desktop:~# iptables-save > /etc/iptables.rules
root@desktop:~# cat /etc/iptables.rules
# Generated by iptables-save v1.4.4 on Sun Nov 21 15:10:42 2010
*filter
:INPUT ACCEPT [1234:120406]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1522:124750]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -j DROP
COMMIT
# Completed on Sun Nov 21 15:10:42 2010
iptables-=save
命令有助于我们在纯文本文件中进行更改。它看起来与在命令行中列出规则的命令略有不同,但是实际上是一回事。和以前一样,我们拥有三个部分:INPUT、FORWARD 和 OUTPUT。我们最初指定的规则涉及 OUTPUT 连接,所以这就是我们所添加的规则放置的部分。
此时,服务器被锁定,配置也已保存至一个文件中。但是,当我们执行网络扫描时会发生什么事了?让我们再次在该服务器上运行 nmap,并检查其结果,如 清单 9 所示。
清单 9. 使用锁定的服务器进行网络扫描
~ $ nmap 10.0.0.120
Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-11-21 20:56 EST
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.04 seconds
~ $ nmap -Pn 10.0.0.120
Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-11-21 20:56 EST
Nmap scan report for 10.0.0.120
Host is up (0.017s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 12.19 seconds
注意,会尝试根据服务器所在的 IP 进行扫描,但是 nmap 无法列出打开的端口。出现这种情况是因为将防火墙设置为阻止除了打开的 SSH 端口外的任何一切。因为 nmap 使用了一个特定的网络协议来验证主机是否正常运行,所以并不返回任何内容。第二次尝试成功了,并告诉我们只有 SSH 打开。只使用三条规则,我们就可以有效地锁定服务器。
保存和恢复规则
在上一部分中,我们将规则保存至一个文本文件。然而,这并不能有效地告知服务器,它需要加载规则。此外,当服务器重启时,会丢失所有已执行的配置。
如果您正在使用命令行添加规则,那么您应该已经非常熟悉将那些更改保存至文本文件的操作。请参见 清单 10 了解保存防火墙规则。
清单 10. 保存防火墙规则
iptables-save > /etc/iptables.rules
根据正在使用的操作系统,有几种方法可在启动时载入那些规则。一种简单方法是导航至一个公共接口,并告知它在联机前先加载那些规则。请参见 清单 11。
清单 11. 公共网络接口加载规则
<![CDATA[
auto eth0
iface eth0 inet static
address 99.99.99.0
netmask 255.255.255.0
pre-up iptables-restore < /etc/iptables.rules
]]>
我们拥有 eth0 接口,并声明在接口启动前载入规则。正如您所想的,您可以使用这些命令手动更新文件中的防火墙规则。
灾难恢复
前不久,我负责管理一个防火墙设备。虽然我定期进行规则和配置备份工作,但是却没意识到那些备份属于专门的格式,只能由所拥有的设备型号读取。当然,如果您所拥有的两个设备为同一品牌、型号和固件版本,那么这就不是问题,但是,在小型企业中,通常预算并不允许这样做。
有一天,设备无法运行了,我不得不实施同样可靠的(或更佳的)快速工具来替换它。我从中了解到,拥有可读配置和快速解决问题的功能非常重要。
很幸运的,我找到了一个状态良好的旧服务器,该服务器具备若干个网络接口,能够代替坏掉的设备。
到目前为止,我已经历了许多这样的场景,获取一个可轻松应用于任何服务器的规则副本以防止故障发生。现在让我们启用防火墙作为小型家用或商业网络的主要网关。
Iptables 充当主要网关
如果您是在个人计算机上运行 iptables,那么到目前为止我们所谈及的一切对您非常有益,但是,如果整个办公室均需要共享 Internet 连接,那么我们所谈及的这一些就对您毫无意义。通过一些配置设置,我们就能够正确完成创建。
网关 服务器需要至少两个网络接口来作为合适的网关。一个接口 "告知" 公共连接,而另一个则 "告知" 内部受保护的连接。
我们将假设,此服务器拥有两个物理网络接口:eth0(公共的)和 eth1(专用的)。我需要对他们进行网络地址转换 (NAT),以便网络流量能从一个接口无缝地流动到另一个接口。专用网络的子网为 192.168.0.0/255.255.0.0,所以让我们看看带有转发功能的 NAT 规则,如 清单 12 所示。
清单 12. NAT 和转发规则
iptables -A FORWARD -s 192.168.0.0/255.255.0.0 -i eth0 -o eth1 -m\
conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE
清单 13 显示如何修改 proc
中的一些设置以启用服务器的转发功能。
清单 13. 启用服务器的转发功能
sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
注意,proc
更改不稳定,在重启后会全部丢失。有几种方法可确保重启后这些修改依然存在。在 Debian/Ubuntu 发行版中,将这些行添加至 /etc/rc.local 并执行。
最后,如 清单 14 所示,还需要一个设置更改,修改运行时 (sysctl) 的内核参数。这些配置通常已位于 sysctl.conf 中,但都被注释掉。取消注释(或者,如果它们不包含在您的发行版中,请添加它们)。
清单 14. Sysctl/内核转发
net.ipv4.conf.default.forwarding=1
net.ipv4.conf.all.forwarding=1
DNS 阈值
将 Linux 服务器作为网关运行会导致 DNS 出现某种问题。内核旨在保存 DNS 映射表,但是它提供的条目为最少,并不适合于过大的通信量。当到达此水平值时,就不会向询问的主机返回任何 DNS 查询。如果只有若干个客户端,那么很少出现超过这个水平值的情况,但是如果有超过 30 个客户端共用防火墙,就会出问题。
可能需要对环境进行一些调整,但是 清单 15 中的值会在看见 DNS 问题之前提供空间。
清单 15. 增加 DNS 阀值
echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
注意观察与 清单 16 相似的消息,这些消息会在需要增加刚刚设置的数值时发出警告。
清单 16. 系统日志记录 DNS 溢出的警告
Nov 22 11:36:16 firewall kernel: [92374.325689] Neighbour table overflow.
Nov 22 11:36:20 firewall kernel: [92379.089870] printk: 37 messages suppressed.
Nov 22 11:36:20 firewall kernel: [92379.089876] Neighbour table overflow.
Nov 22 11:36:26 firewall kernel: [92384.333161] printk: 51 messages suppressed.
Nov 22 11:36:26 firewall kernel: [92384.333166] Neighbour table overflow.
Nov 22 11:36:30 firewall kernel: [92389.084373] printk: 200 messages suppressed.
结束语
我们已经通过一些简单的步骤使 iptables 正常运行并安全锁定 Linux 服务器。所应用的规则应该提供一个良好功能来判断使用 iptables 作为防火墙的服务器所发生的情况。我建议您试用一下 iptables,特别是在您依赖设备并想要拥有更多的控制和易于复制的高可读性配置的情况下。
虽然我们在此处所使用的规则非常简单,但是 iptables 的灵活性和复杂性已超出了本文所谈论的范围。有许多复杂的规则,您可以组合使用它们来创建一个安全且可控的防火墙环境。
iptables 中一个令人感兴趣的高级功能示例是负载平衡。大多数时间,在浏览高可用性 Web 服务时,您会寻求负载平衡解决方案。使用 iptables,可以通过 random 或 nth 标志进行设置和配置。
您也可以执行基于时间的规则。在小型办公室环境中,在周一至周五限制某些服务,而在周六和周日让防火墙以另一种方式进行工作,可能非常有用。在这种情况下可能用到的标志有:--timestart、--timestop 和 days。
我碰到的一个问题是,在某种类型的故障转移中我无法同一时间拥有两个防火墙。实现此项工作并不容易,但是有多种途径。最简单的解决方法是让路由器来完成此项作业,并负载平衡两个相同的防火墙服务器。如果网络环境是非常重要的资源,比如办公室或小型企业,那么我建议好好考虑此选项。
Iptables 拯救了我,我希望它也能拯救您!