如何在 Ubuntu 14.04 上使用 Iptables 实施基本防火墙模板

介绍

实施防火墙是确保服务器安全的重要步骤,其中很大一部分是决定将流量限制强加于您的网络的个别规则和政策。

在本指南中,我们将构建一个可以作为更复杂的规则集的基础的防火墙,该防火墙将主要集中在提供合理的默认值和建立一个鼓励易于扩展的框架上。

前提条件

在你开始之前,你应该有一个基本的想法,你想实施的防火墙策略. 你可以遵循 这个指南得到一个更好的想法,一些你应该考虑的事情。

为了跟进,您需要访问 Ubuntu 14.04 服务器. 我们将在本指南中使用具有sudo特权的非根用户。您可以在我们的 Ubuntu 14.04 初始服务器设置指南中学习如何配置此类用户。

当你完成后,继续下方。

安装永久性防火墙服务

要开始,您需要安装iptables-persistent包,如果您还没有这样做,这将使我们能够保存我们的规则集,并在启动时自动应用它们:

1sudo apt-get update
2sudo apt-get install iptables-persistent

在安装过程中,您将被问及是否要保存当前的规则,在这里说,我们会暂时编辑生成的规则文件。

关于IPv6的注意事项在本指南中

在我们开始之前,我们应该简要谈谈IPv4和IPv6。iptables命令只处理IPv4流量。对于IPv6流量,使用一个名为ip6tables的单独伴侣工具。规则存储在单独的表和链条中。对于iptables-persistent,IPv4规则被写成并从/etc/iptables/rules.v4读取,而IPv6规则被保留在/etc/iptables/rules.v6

本指南假定您在服务器上没有积极使用IPv6;如果您的服务不利用IPv6,则更安全地完全阻止访问,正如我们在本文中所做的那样。

实施基本防火墙政策(快速方式)

为了尽快起步并运行,我们将向您展示如何直接编辑规则文件以复制和粘贴完成的防火墙策略。

为了实施我们的防火墙政策和框架,我们将编辑 /etc/iptables/rules.v4/etc/iptables/rules.v6 文件。

1sudo nano /etc/iptables/rules.v4

在里面,你会看到一个看起来像这样的文件:

1[label /etc/iptables/rules.v4]
2# Generated by iptables-save v1.4.21 on Tue Jul 28 13:29:56 2015
3*filter
4:INPUT ACCEPT [0:0]
5:FORWARD ACCEPT [0:0]
6:OUTPUT ACCEPT [0:0]
7COMMIT
8# Completed on Tue Jul 28 13:29:56 2015

将内容替换为:

 1[label /etc/iptables/rules.v4]
 2*filter
 3# Allow all outgoing, but drop incoming and forwarding packets by default
 4:INPUT DROP [0:0]
 5:FORWARD DROP [0:0]
 6:OUTPUT ACCEPT [0:0]
 7
 8# Custom per-protocol chains
 9:UDP - [0:0]
10:TCP - [0:0]
11:ICMP - [0:0]
12
13# Acceptable UDP traffic
14
15# Acceptable TCP traffic
16-A TCP -p tcp --dport 22 -j ACCEPT
17
18# Acceptable ICMP traffic
19
20# Boilerplate acceptance policy
21-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
22-A INPUT -i lo -j ACCEPT
23
24# Drop invalid packets
25-A INPUT -m conntrack --ctstate INVALID -j DROP
26
27# Pass traffic to protocol-specific chains
28## Only allow new connections (established and related should already be handled)
29## For TCP, additionally only allow new SYN packets since that is the only valid
30## method for establishing a new TCP connection
31-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
32-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
33-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
34
35# Reject anything that's fallen through to this point
36## Try to be protocol-specific w/ rejection message
37-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
38-A INPUT -p tcp -j REJECT --reject-with tcp-reset
39-A INPUT -j REJECT --reject-with icmp-proto-unreachable
40
41# Commit the changes
42COMMIT
43
44*raw
45:PREROUTING ACCEPT [0:0]
46:OUTPUT ACCEPT [0:0]
47COMMIT
48
49*nat
50:PREROUTING ACCEPT [0:0]
51:INPUT ACCEPT [0:0]
52:OUTPUT ACCEPT [0:0]
53:POSTROUTING ACCEPT [0:0]
54COMMIT
55
56*security
57:INPUT ACCEPT [0:0]
58:FORWARD ACCEPT [0:0]
59:OUTPUT ACCEPT [0:0]
60COMMIT
61
62*mangle
63:PREROUTING ACCEPT [0:0]
64:INPUT ACCEPT [0:0]
65:FORWARD ACCEPT [0:0]
66:OUTPUT ACCEPT [0:0]
67:POSTROUTING ACCEPT [0:0]
68COMMIT

保存并关闭文件。

您可以通过键入此命令来测试文件的语法错误。

1sudo iptables-restore -t /etc/iptables/rules.v4

接下来,打开 /etc/iptables/rules.v6 文件来修改 IPv6 规则:

1sudo nano /etc/iptables/rules.v6

我们可以通过替换文件的内容以下面的配置来阻止所有IPv6流量:

 1[label /etc/iptables/rules.v6]
 2*filter
 3:INPUT DROP [0:0]
 4:FORWARD DROP [0:0]
 5:OUTPUT DROP [0:0]
 6COMMIT
 7
 8*raw
 9:PREROUTING DROP [0:0]
10:OUTPUT DROP [0:0]
11COMMIT
12
13*nat
14:PREROUTING DROP [0:0]
15:INPUT DROP [0:0]
16:OUTPUT DROP [0:0]
17:POSTROUTING DROP [0:0]
18COMMIT
19
20*security
21:INPUT DROP [0:0]
22:FORWARD DROP [0:0]
23:OUTPUT DROP [0:0]
24COMMIT
25
26*mangle
27:PREROUTING DROP [0:0]
28:INPUT DROP [0:0]
29:FORWARD DROP [0:0]
30:OUTPUT DROP [0:0]
31:POSTROUTING DROP [0:0]
32COMMIT

保存并关闭文件。

要测试此文件的语法错误,我们可以使用ip6tables-restore命令与-t选项:

1sudo ip6tables-restore -t /etc/iptables/rules.v6

当两个规则文件报告没有语法错误时,您可以通过键入应用内部的规则:

1sudo service iptables-persistent reload

您可以通过列出当前使用的iptables规则来验证此情况:

1sudo iptables -S
2sudo ip6tables -S

这些防火墙规则将在每次启动时再次应用,测试以确保您仍然可以登录并阻止所有其他访问。

解释我们的总体防火墙策略

在我们用上述规则构建的基本防火墙中,我们创建了一个可扩展的框架,可以轻松调整以添加或删除规则。对于IPv4流量,我们主要关心在过滤表中的INPUT链条。这个链条将处理用于我们的服务器的所有包。我们还允许所有输出流量,并拒绝了所有包转发,这只会适当,如果这个服务器作为其他主机的路由器。

一般来说,我们的规则设置了一个防火墙,默认情况下会拒绝流量进入,然后我们将为我们希望从本政策中排除的服务和流量类型创建例外。

例如,我们总是希望拒绝被认为是无效的包,我们总是希望允许在本地循环接口的流量和与已建立的连接相关的数据。

接下来,我们根据所使用的协议来匹配流量,并将其转移到一个特定协议的链条中。 这些特定协议的链条旨在保留符合并允许特定服务的流量规则。 在本示例中,我们允许的唯一服务是TCP链中的SSH。

任何不符合通用规则或协议特定的服务规则的流量都由INPUT链的最后几条规则来处理。我们已经为我们的防火墙设置了默认策略为DROP,这将拒绝通过我们的规则的包,但是INPUT链的末尾的规则会拒绝包,并向客户端发送一个信息,模仿服务器如果没有服务在该端口运行时会如何响应。

对于IPv6流量,我们只是放弃了所有的流量,我们的服务器不使用这个协议,所以最安全的是根本不参与流量。

(可选) 更新名称服务器

阻止所有 IPv6 流量可能会干扰您的服务器如何在互联网上解决问题,例如,这可能会影响您如何使用 APT。

如果您在尝试运行apt-get update时收到此类错误:

1[label Error]
2Err http://security.ubuntu.com trusty-security InRelease
3
4Err http://security.ubuntu.com trusty-security Release.gpg
5  Could not resolve 'security.ubuntu.com'
6
7. . .

您应该遵循此部分才能让 APT 再次工作。

首先,将您的名称服务器设置为外部名称服务器。本示例使用谷歌的名称服务器。

1sudo nano /etc/network/interfaces

如下所示,更新dns-nameservers行:

1[label /etc/network/interfaces]
2. . .
3iface eth0 inet6 static
4        address 2604:A880:0800:0010:0000:0000:00B2:0001
5        netmask 64
6        gateway 2604:A880:0800:0010:0000:0000:0000:0001
7        autoconf 0
8        dns-nameservers 8.8.8.8 8.8.4.4

更新您的网络设置:

1sudo ifdown eth0 && sudo ifup eth0

预计产量是:

1[label Output]
2RTNETLINK answers: No such process
3Waiting for DAD... Done

接下来,创建一个新的防火墙规则,强迫IPv4在可用时。

1sudo nano /etc/apt/apt.conf.d/99force-ipv4

将此单行添加到文件中:

1[label /etc/apt/apt.conf.d/99force-ipv4]
2Acquire::ForceIPv4 "true";

保存并关闭文件. 现在您应该能够使用 APT。

使用IPTables命令实现我们的防火墙

现在你了解了我们构建的策略背后的总体想法,我们将通过如何通过使用iptables命令来创建这些规则进行研究。我们将最终使用我们上面指定的相同的规则,但我们将通过反复添加规则来创建我们的策略。

重置您的防火墙

我们将开始通过重置我们的防火墙规则,以便我们可以看到如何从命令行构建策略。

1sudo service iptables-persistent flush

您可以通过键入检查您的规则是否被重置:

1sudo iptables -S

您应该看到过滤器表中的规则已经消失,默认策略在所有链条上设置为接受:

1[secondary_label output]
2-P INPUT ACCEPT
3-P FORWARD ACCEPT
4-P OUTPUT ACCEPT

创建特定协议链

我们将首先创建我们所有的协议特定的链条,这些链条将被用来维护我们想要暴露的服务的拒绝政策的规则,我们将创建一个用于UDP流量,一个用于TCP和一个用于ICMP:

1sudo iptables -N UDP
2sudo iptables -N TCP
3sudo iptables -N ICMP

SSH 使用 TCP,所以我们将添加一个规则来接受 TCP 流量为端口 22 的 TCP 链:

1sudo iptables -A TCP -p tcp --dport 22 -j ACCEPT

如果我们想添加额外的TCP服务,我们现在可以通过重复命令,代替端口号。

创建通用目的接受和否定规则

INPUT链中,所有的流量都开始过滤,我们需要添加我们的一般用途规则,这些是我们的防火墙的基线,通过接受低风险的流量(与我们已经检查的连接相关的本地流量和流量)和放弃明显无用的流量(无效的包)。

首先,我们将创建一个例外来接受所有是建立连接的一部分或与建立连接相关的流量:

1sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

这个规则使用了conntrack扩展,它提供内部跟踪,以便iptables具有它需要评估包作为较大的连接的一部分而不是作为一个分散,无关的包的流程的背景。TCP是一种基于连接的协议,因此建立的连接是相当明确的。对于UDP和其他无关联的协议,建立的连接是指已经看到响应的流量(原始包的来源将是响应包的目的地,反之亦然)。

我们还希望允许所有的流量源于本地循环接口. 这是由服务器生成的流量,用于服务器。

1sudo iptables -A INPUT -i lo -j ACCEPT

最后,我们希望否认所有无效的包. 包可能因多种原因而无效. 它们可能指不存在的连接,它们可能针对不存在的接口,地址或端口,或者它们可能只是错误的形式。

1sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

创建对特定协议链的跳跃规则

到目前为止,我们已经在INPUT链中创建了一些一般规则,以及我们协议特定的链内特定可接受的服务的一些规则。

我们需要将INPUT链中的流量导向适当的协议特定的链接,我们可以匹配协议类型以将其发送到正确的链接,我们还将确保该包代表一个新的连接(任何已建立或相关的连接都应该早些时候处理)。

1sudo iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
2sudo iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
3sudo iptables -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

拒绝所有剩余的流量

如果被传递到特定协议链的数据包不符合内部任何规则,则控制将被传回INPUT链。

我们将使用REJECT目标拒绝流量,该目标向客户端发送响应消息,这使我们能够指定出发消息,以便我们可以模仿如果客户端试图将包发送到正常的封闭端口时会得到的响应。

试图到达封闭的 UDP 端口会导致 ICMP 发出端口无法到达消息,我们可以通过键入来模仿:

1sudo iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable

试图在封闭的端口上建立 TCP 连接的结果在 TCP RST 响应中:

1sudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

对于所有其他包,我们可以发送一个 ICMP 协议无法访问 消息,表示服务器不响应此类型的包:

1sudo iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable

调整默认政策

我们添加的最后三条规则应该处理INPUT链中剩余的所有流量,但是,作为预防措施,我们应该将默认策略设置为DROP

1sudo iptables -P INPUT DROP
2sudo iptables -P FORWARD DROP

<$>[warning] [label Warning] 您的策略设置为DROP,如果您用sudo iptables -F清除您的iptables,您的当前SSH连接将被放弃!使用sudo iptables-persistent flush清除规则是一个更好的方法,因为它也将重置默认策略。

为了与我们的 IPv6 政策相匹配,我们可以使用以下ip6tables命令:

1sudo ip6tables -P INPUT DROP
2sudo ip6tables -P FORWARD DROP
3sudo ip6tables -P OUTPUT DROP

这应该复制我们相当紧密的规则。

保存IPTables规则

在这一点上,你应该测试你的防火墙规则,并确保它们覆盖了你想要保持的流量,而不会妨碍你的正常访问。

保存当前的规则(IPv4 和 IPv6)通过键入:

1sudo service iptables-persistent save

这将重写您的/etc/iptables/rules.v4/etc/iptables/rules.v6文件,用您在命令行上创建的策略。

结论

通过遵循本指南,或将您的防火墙规则直接粘贴到配置文件中,或通过手动应用并将其保存到命令行上,您已经创建了一个良好的启动防火墙配置。

本指南所建立的框架应该允许您轻松进行调整,并有助于澄清现有策略。查看我们的其他一些指南,了解如何使用一些流行的服务来构建您的防火墙策略:

Published At
Categories with 技术
Tagged with
comments powered by Disqus