如何设置Iptables防火墙以保护服务器之间的流量

引言

将应用程序设置中的离散组件部署到不同的节点上,是减少负载和开始进行横向扩展的常见方法。一个典型的例子是将数据库配置到与应用程序分开的服务器上。虽然这种设置有许多优点,但通过网络连接也涉及一组新的安全问题。

在本指南中,我们将演示如何在分布式设置中为每个服务器设置防火墙。我们将配置我们的策略,允许组件之间的预期流量,同时拒绝其他流量。

您还可以配置Silicon Cloud的云防火墙,它作为Silicon Cloud基础设施上服务器的额外外部层运行。通过这种方式,您无需为服务器本身配置防火墙。

在本指南中的演示中,我们将使用两台Ubuntu 22.04服务器。其中一台将使用Nginx提供Web应用程序,另一台将托管该应用程序的MySQL数据库。尽管我们将使用此设置作为示例,但您应该能够推广所涉及的技术以适应您自己的服务器要求。

先决条件

要开始,您需要准备两台全新的Ubuntu 22.04服务器。在每台服务器上添加一个带有sudo权限的普通用户账户。要执行此操作,请按照我们的Ubuntu 22.04初始服务器设置指南进行操作。

我们要保护的应用程序设置是基于这个指南。如果您想按照该示例进行操作,请按照教程中指示设置您的应用程序和数据库服务器。否则,您可以将本文作为一般参考。

步骤1——设置防火墙

您将首先为每个服务器实施基线防火墙配置。我们将实施一个以安全为首要考虑的策略。除了SSH流量之外,我们将封锁几乎所有其他流量,并为我们的特定应用程序在防火墙上打孔。

这个指南遵循iptables的语法。在Ubuntu 22.04上,iptables将自动安装,并使用nftables后端,因此您无需安装任何额外的包。

使用nano或您最喜欢的文本编辑器,打开/etc/iptables/rules.v4文件。

  1. sudo nano /etc/iptables/rules.v4

复制防火墙模板指南中的配置。

iptables规则文件的路径为/etc/iptables/rules.v4。
*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

# Commit the changes
COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

保存并关闭文件。如果您正在使用nano编辑器,请按Ctrl+X退出,然后在提示时按Y,并按Enter键确认。

如果您正在实际环境中进行实施,请暂时不要重新加载防火墙规则。按照这里所提供的规则集加载后,将立即中断您的应用程序和数据库服务器之间的连接。在重新加载之前,您需要调整规则以符合我们的运营需求。

第二步——发现您的服务正在使用的端口

为了允许组件之间进行通信,您需要了解正在使用的网络端口。您可以通过检查配置文件来找到正确的网络端口,但是一个不依赖于具体应用的找到正确端口的方法是仅仅检查每台机器上哪些服务正在监听连接。

您可以使用netstat工具来找出这个。由于您的应用程序只通过IPv4进行通信,我们将添加-4参数,但如果您也在使用IPv6,可以将其删除。您需要找到正在运行的服务的其他参数是-p,-l,-u,-n和-t,您可以提供为-plunt。

这些论点可以分解如下:

  • p: Show the PID and name of the program to which each socket belongs.
  • l: Show only listening sockets.
  • u: Show UDP traffic.
  • n: Show numeric output instead of service names.
  • t: Show TCP traffic.
  1. sudo netstat -4plunt

在您的网服务器上,您的输出可能如下所示:

Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1058/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4187/nginx

第一个突出显示的列显示了服务在行末突出显示的IP地址和端口。特殊的0.0.0.0地址意味着所讨论的服务正在监听所有可用地址。

在您的数据库服务器上,您的输出可能如下所示:

  1. sudo netstat -4plunt
Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1097/sshd tcp 0 0 192.0.2.30:3306 0.0.0.0:* LISTEN 3112/mysqld

在这个例子中,你可以完全相同地阅读这些列。192.0.2.30地址代表了数据库服务器的私有IP地址。在先决条件教程中,出于安全原因,你将MySQL限制为私有接口。

在此步骤中,注意到您找到的值。这些是您需要调整防火墙配置所需的网络详细信息。

在您的网络服务器上,您需要确保以下端口是可访问的:

  • Port 80 on all addresses
  • Port 22 on all addresses (already accounted for in firewall rules)

您的数据库服务器需要确保以下端口可访问:

  • Port 3306 on the address 192.0.2.30 (or the interface associated with it)
  • Port 22 on all addresses (already accounted for in firewall rules)

第三步——调整Web服务器防火墙规则。

现在您已经获取到所需的端口信息,您将调整您的Web服务器的防火墙规则集。以sudo特权打开编辑器中的规则文件。

  1. sudo nano /etc/iptables/rules.v4

在网络服务器上,您需要将端口80添加到可接受的流量列表中。由于该服务器正在侦听所有可用地址-通常情况下, web服务器希望从任何地方都可以访问-您将不会通过界面或目标地址限制规则。

您的网络访问者将使用TCP协议进行连接。您的框架已经有一个名为TCP的自定义链用于处理TCP应用程序异常。您可以在该链的下方添加80端口,就在您的SSH端口的异常之后。

/etc/iptables/rules.v4:

四个选项,只需要使用一个:

/etc/iptables/rules.v4
/etc/iptables/v4规则
IP表生效路径:/etc/iptables/rules.v4
IP表路径:/etc/iptables/rules.v4

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 80 -j ACCEPT

. . .

您的网络服务器将发起与数据库服务器的连接。您的出站流量在防火墙中没有任何限制,已建立连接相关的入站流量也是被允许的,因此我们不需要在此服务器上打开任何额外的端口来允许这个连接。

当你完成后,请保存并关闭文件。你的网络服务器现在具有防火墙策略,将允许所有合法的流量而阻止其他所有流量。

测试您的规则文件是否有语法错误。

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

如果没有显示语法错误,请重新加载防火墙以实施新的规则集。

  1. sudo service iptables-persistent reload

第四步 — 调整数据库服务器防火墙规则

在您的数据库服务器上,您需要允许访问服务器的私有IP地址上的3306端口。在这种情况下,该地址为192.0.2.30。您可以针对该地址限制访问,也可以通过匹配与分配了该地址的接口来限制访问。

要找到与该地址相关联的网络接口,请运行 ip -4 addr show scope global。

  1. ip -4 addr show scope global
Output
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 203.0.113.5/24 brd 104.236.113.255 scope global eth0 valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.0.2.30/24 brd 192.0.2.255 scope global eth1 valid_lft forever preferred_lft forever

突出显示的区域表明eth1接口与该地址相关联。

接下来,您将在数据库服务器上调整防火墙规则。在数据库服务器上使用sudo权限打开规则文件。

  1. sudo nano /etc/iptables/rules.v4

再次强调,您将在我们的TCP链中添加一条规则,为您的Web和数据库服务器之间的连接创建一个例外。

为了根据实际地址来限制访问权限,您可以按照以下方式添加规则。

/etc/iptables/rules.v4 可以翻译为:
第一个选项:/etc/iptables/rules.v4
*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -d 192.0.2.30 -j ACCEPT

. . .

如果你更愿意根据包含该地址的接口允许例外情况,你可以添加类似于这个规则的规定。

规则文件 “/etc/iptables/rules.v4″。
*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -i eth1 -j ACCEPT

. . .

在你完成后保存并关闭文件。

用这条命令检查语法错误。

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

当你准备好时,重新加载防火墙规则。

  1. sudo service iptables-persistent reload

你们的两个服务器现在应该得到保护了,而且之间必要的数据流不会受到限制。

结论

在设置应用程序时,始终将实施适当的防火墙作为部署计划的一部分。尽管我们在上述演示中使用了运行Nginx和MySQL的两台服务器,但上述演示的技术无论您选择什么具体技术都是适用的。

要更加了解防火墙和iptables,可以参考以下指南:

  • How To Choose an Effective Firewall Policy to Secure your Servers
  • A Deep Dive into Iptables and Netfilter Architecture
  • How To Test your Firewall Configuration with Nmap and Tcpdump
发表回复 0

Your email address will not be published. Required fields are marked *