如何使用iptables隔离专用网络中的服务器
介绍
在本教程中,我们将教您如何将 Iptables 与 DigitalOcean 专用网络一起使用。 我们还将介绍您为什么要这样做,并提供一个示例来说明如何在您自己的环境中实现这一点。 本教程中给出的示例将解释这个概念,以便您能够根据自己的需要调整配置。
DigitalOcean 的专用网络选项为 VPS 提供了第二个网络接口,该接口只能由在同一帐户上配置且也位于同一数据中心的其他服务器访问。 这意味着通过 Droplet 的私有接口发送的数据只能由您团队中的人员或有权访问您的 DO 密码的人员访问。
注意: 本教程涵盖 IPv4 安全性。 在 Linux 中,IPv6 的安全性与 IPv4 分开维护。 例如,iptables
仅维护 IPv4 地址的防火墙规则,但它有一个称为 ip6tables
的 IPv6 对应项,可用于维护 IPv6 网络地址的防火墙规则。
如果您的 VPS 配置为 IPv6,请记住使用适当的工具保护您的 IPv4 和 IPv6 网络接口。 有关 IPv6 工具的更多信息,请参阅本指南:如何配置工具以在 Linux VPS 上使用 IPv6。
示例场景
对于我们的示例,我们将使用以下教程创建的环境:How To Optimize WordPress Performance With MySQL Replication On Ubuntu 14.04 。
这是环境的示意图:
示例环境使用五个 VPS(并且未配置 iptables):
- haproxy-www:反向代理负载均衡器
- wordpress-1:第一个应用服务器
- wordpress-2:第二个应用服务器
- mysql-1:主MySQL数据库服务器
- mysql-2:从 MySQL 数据库服务器
如果您的设置看起来不像这样,您应该仍然可以跟随。 此外,如果您想阅读有关使用私有网络或 iptables 基础知识设置 VPS 的信息,这里有一些您可能会发现有用的链接(本教程假设您了解 iptables 的基础知识):
- 如何设置和使用 DigitalOcean 专用网络
- 如何在现有 Droplet 上启用 DigitalOcean 专用网络
- iptables 防火墙的工作原理
- 如何在 Ubuntu 14.04 上使用 iptables 设置防火墙
如果您已经熟悉这些概念,并且想查看 iptables 设置,请随时跳到 iptables 配置概述 部分。
我们的目标
完成本教程后,我们应该有一个类似于下图的环境:
私有网络区域中的所有服务器只能与该私有网络中的其他服务器通信(橙色框)。 负载均衡器将可通过 Internet 访问,也可链接到专用网络。 此策略的执行将通过每台服务器上的 iptables 实施。
注意:要阻止到您的公共接口的流量,您可以禁用您的公共接口或设置防火墙规则以实现与 Iptables 类似的效果。 我们将使用防火墙选项,因为我们可以将其配置为阻止不需要的网络流量,同时允许我们的服务器在启动连接时访问 Internet(这对于在服务器上下载更新等事情很有用)。
访问您的 VPS 的方法
在我们讨论如何锁定您自己的私有网络之前,我们将讨论访问您的服务器的不同方法(尤其是命令行)。 了解连接到服务器的所有方法尤其重要,因为如果您不小心,可能会将自己锁定在自己的服务器之外。
如果您在 DigitalOcean VPS 上设置了私有网络,您可以通过三种方式访问它:
- 公共接口
- 私有接口
- 控制面板控制台访问
公共接口
公共界面可通过全球互联网访问。 这意味着您或 Internet 上的任何其他人都可以访问此界面,除非它被锁定。
在需要通过 Internet 访问的服务器上,公共接口是必需的,因此您的客户或用户可以连接到您提供的任何服务(例如 网页或应用程序)。 如果用户需要访问它,公共接口的 IP 地址通常会映射到域名(例如 example.com) 通过 DNS。
每个 VPS 都有一个默认启用的公共接口。 在本教程中,我们将使用 iptables 将公共接口限制为仅接受我们的应用程序正常运行所必需的网络流量(即 HTTP)。
私有接口
私有接口只能被同一私有网络上的其他 VPS 访问。 对于 DigitalOcean,这意味着只有在同一帐户下配置的其他 VPS 才能访问私有接口。
如果您在同一帐户下连接到多个 VPS,您可以通过 SSH 连接到另一个 VPS 的私有接口。 例如,您可以 SSH 到 haproxy-www 的公共接口,然后从那里 SSH 到 mysql-1 的私有接口。 如果您使用 iptables 从某些服务器的公共接口断开 SSH 连接,这很有用。
在本教程中,我们将私有接口上的网络流量限制在我们定义的“私有网络”(上图中的橙色框)内的 VPS 和一些其他必要的网络流量(负载均衡器和应用程序服务器之间) .
控制面板控制台访问
如果您无法访问公共和私有界面,您可以通过控制台访问连接到您的 VPS。 在现实世界中,这类似于将键盘、鼠标和显示器直接连接到您的服务器。 请记住,如果您不小心禁用了两个接口或 SSH 服务,您始终可以通过这种方式访问您的 VPS。
注意:如果您的VPS登录都是通过SSH密钥认证的,您需要通过控制面板重置root密码才能通过控制台登录。
确定接口/端口访问要求
在继续之前,确定您的接口和端口访问要求很重要。 许多应用程序使用默认端口,或者可以配置为绑定到特定的接口和端口。 在确定策略需要之前不要更改 iptables 配置,因为配置错误的防火墙可能会破坏您的应用程序。
以下是我们示例场景的网络访问需求细分:
- haproxy-www:
- wordpress-1:(全部私有)
- wordpress-2:(全部私有)
- mysql-1:(全部私有)
- mysql-2:从 MySQL 数据库服务器
您还需要允许 SSH 连接到至少一个公共接口,以及专用网络区域上所有服务器之间的 SSH。 在示例中,我们将允许公共 SSH 连接到另一个名为 tunnel-1 的 VPS,并且只允许其他服务器上的私有 SSH——这意味着我们需要通过隧道 1 的 SSH 隧道连接到任何的其他服务器。 从技术上讲,您可以为此目的使用任何(或全部)您的 VPS。
现在我们知道我们需要防火墙接受和可能丢弃的内容,让我们开始配置它。
iptables 配置概述
以下是我们将如何配置 iptables 以满足我们的需求的概述:
- 默认丢弃
- 允许 SSH 从私有网络接口到 tunnel-1 VPS
- 允许从您的服务器发起的 Internet 流量
- 明确允许特定的专用网络流量(通过 IP 地址和/或端口)
让我们从我们唯一面向公众的服务器 haproxy-www 开始。 注意iptables
命令中,eth0指的是VPS的公共接口,eth1指的是VPS的私有接口——如果你的接口名称不同,请替换它们在适当的时候。
配置公共服务器(haproxy-www)
SSH 到 tunnel-1:
ssh用户@ tunnel_1_public_IP
从这里,SSH 到 haproxy-www 的 private 接口:
ssh用户@haproxy_www_private_IP
在 haproxy-www 上,将所有链默认设置为 ACCEPT 并删除所有现有规则:
sudo iptables -P INPUT ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -F
允许 tunnel-1 通过其到 haproxy-www 的私有接口进行 SSH:
sudo iptables -A INPUT -p tcp -s tunnel_1_private_IP --dport 22 -i eth1 -j ACCEPT sudo iptables -A OUTPUT -p tcp -d tunnel_1_private_IP --sport 22 -o eth1 -m state --state ESTABLISHED -j ACCEPT
允许服务器上的环回流量。 这允许您的服务器使用 127.0.0.1 或 localhost:
sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A OUTPUT -o lo -j ACCEPT
允许从您的服务器发起的公共和私人流量。 这将允许您的服务器访问 Internet 以执行下载更新或软件等操作:
sudo iptables -I OUTPUT -o eth0 -d 0.0.0.0/0 -j ACCEPT sudo iptables -I INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
允许公共接口上的所有 HTTP 流量(端口 80)。 这是必要的,因此用户可以通过 http://www.example.com/ 访问我们的网站:
sudo iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED - j 接受
允许两个 WordPress 服务器通过其私有 IP 地址访问端口 80:
sudo iptables -A INPUT -p tcp -s wordpress_1_private_IP --sport 80 -j ACCEPT sudo iptables -A OUTPUT -p tcp -d wordpress_1_private_IP --dport 80 -j ACCEPT sudo iptables -A INPUT -p tcp -s wordpress_2_private_IP --sport 80 -j ACCEPT sudo iptables -A OUTPUT -p tcp -d wordpress_2_private_IP --dport 80 -j ACCEPT
现在我们已经允许所有必要的网络流量,我们可以通过将 DROP
设置为每个 iptables 链的默认行为来丢弃所有其他流量:
sudo iptables -P INPUT DROP sudo iptables -P OUTPUT DROP sudo iptables -P FORWARD DROP
现在您已经完成了 haproxy-www 的防火墙的配置,您需要确保一切正常。 如果您对您的配置感到满意,您可以通过使用以下 apt 命令安装 iptables-persistent 包来保存它:
sudo apt-get update sudo apt-get install iptables-persistent
在安装 iptables-persistent 期间,它会询问您是否要保存当前的防火墙设置。 回答是。
现在 haproxy-www 防火墙允许以下内容:
- 通过专用网络从隧道 1 进行 SSH
- 环回流量
- haproxy-www 发起的互联网活动
- 公共互联网上的 HTTP
- 自身与 WordPress 应用服务器之间的 HTTP
- 没有来自其他来源的传入流量
让我们继续保护我们剩余的服务器。
配置专用网络服务器
注意:对所有剩余的服务器执行所有这些步骤:wordpress-1、wordpress-2、mysql-1和[X127X ]mysql-2。 在本节中,我们通常将这些服务器称为 private-VPS。
由于需要在专用网络中进行通信的大量网络接口和端口,我们将通过将必要的 IP 地址列入白名单而不是只允许特定的 IP 地址和端口组合来简化事情。 此外,我们将默认允许传出流量,而仅限制传入流量。
SSH 到 tunnel-1:
ssh用户@ tunnel_1_public_IP
从这里,SSH 到 private-VPS 的 private 接口:
ssh用户@private_VPS_private_IP
在 private-VPS 上,将所有链默认设置为 ACCEPT 并删除任何现有规则:
sudo iptables -P INPUT ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -F
允许 tunnel-1 通过其私有接口到私有 VPS 进行 SSH:
sudo iptables -A INPUT -p tcp -s tunnel_1_private_IP --dport 22 -i eth1 -j ACCEPT
允许服务器上的环回流量。 这允许您的服务器使用 127.0.0.1 或 localhost:
sudo iptables -A INPUT -i lo -j ACCEPT
允许从您的服务器发起的公共和私人流量。 这将允许您的服务器访问 Internet 以执行下载更新或软件等操作:
sudo iptables -I INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
将所有只需要访问专用网络区域的服务器列入白名单(您可以省略正在处理的服务器的条目):
sudo iptables -A INPUT -p tcp -s wordpress_1_private_IP -j ACCEPT sudo iptables -A INPUT -p tcp -s wordpress_2_private_IP -j ACCEPT sudo iptables -A INPUT -p tcp -s mysql_1_private_IP -j ACCEPT sudo iptables -A INPUT -p tcp -s mysql_2_private_IP -j 接受
仅在 两台 WordPress 服务器 上,允许 haproxy-www HTTP 访问(端口 80),因此它可以检索页面:
sudo iptables -A INPUT -p tcp -s haproxy_www_private_IP --sport 80 -j ACCEPT sudo iptables -A OUTPUT -p tcp -d haproxy_www_private_IP --dport 80 -j ACCEPT
默认情况下删除 INPUT 和 FORWARD 链。 请注意,我们将 OUTPUT 的默认设置为 ACCEPT,因为我们信任我们专用网络上的服务器:
sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP
现在您已经完成了私有 VPS 防火墙的配置,您需要确保一切正常。 如果您对您的配置感到满意,您可以通过使用以下 apt 命令安装 iptables-persistent 包来保存它:
sudo apt-get update sudo apt-get install iptables-persistent
在安装 iptables-persistent 期间,它会询问您是否要保存当前的防火墙设置。 回答是。
现在 private-VPS 防火墙允许以下功能:
- 通过专用网络从隧道 1 进行 SSH
- 环回流量
- 私有 VPS 发起的 Internet 活动
- 所有传出网络流量
- 被列入白名单的服务器之间的所有传入网络流量(即 私网区域内的所有服务器)
- 没有来自其他来源的传入流量
故障排除:Iptables 列表和日志记录
如果您配置了防火墙并发现您的应用程序停止工作,排除故障的最佳方法是查看策略列表和日志。
显示 iptables 配置
要查看 iptables 配置或策略列表,请运行以下命令:
sudo iptables -vL --line-numbers
这将显示您设置的所有链和规则以及行号。 此外,它还显示丢弃的数据包数量。 如果您希望没有丢包,请检查日志。
读取 iptables 日志
创建一个名为 LOG 的新链:
iptables -N LOG
将 INPUT/OUTPUT/FORWARD 路由到 LOG 链(将 CHAIN
替换为您要监视的链,例如“INPUT”):
iptables -A输入-j 日志
现在使用以下命令记录数据包:
iptables -A LOG -m limit --limit 60/min -j LOG --log-prefix "Iptables DROP: " --log-level 7
现在您可以监控系统消息以查看正在丢弃哪些数据包。
在 Ubuntu 中,可以使用以下命令实时读取消息:
sudo tail -f /var/log/syslog
在 CentOS 中,可以使用以下命令实时读取消息:
sudo tail -f /var/log/messages
日志将列出接口、源端口、目标端口以及有关每个丢弃的数据包的其他一些信息。 这应该可以帮助您找出您可能遇到的任何问题。
结论
学习完本教程后,您应该对使用 iptables 保护您的 VPS 免受公共 Internet 和同一共享专用网络中的其他 VPS(即 同一个数据中心)。 请记住,在添加新服务器或更改服务器设置时,您需要更新防火墙。