如何使用 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

以下是环境看起来如何的图表:

Shared Private Network

示例环境使用五个VPS(并未配置iptables):

  • haproxy-www:反向代理负载平衡器
  • wordpress-1: 第一应用程序服务器
  • wordpress-2: 第二应用程序服务器
  • mysql-1: 主 MySQL 数据库服务器
  • mysql-2: 奴隶 MySQL 数据库服务器

此外,如果你想阅读关于设置一个VPS与私人网络或iptables的基础知识,这里有几个链接,你可能觉得有用(本教程假定你知道iptables的基础知识):

如果您已经熟悉这些概念,并且想看到iptables的设置,请轻松跳过 Iptables Configuration Overview部分。

我们的目标

当我们完成本教程时,我们应该有一个环境,看起来像下面的图表:

Private Network

所有在私有网络区域的服务器只能通过该私有网络内的其他服务器(橙色盒子)进行通信。负载平衡器将通过互联网访问,并连接到私有网络。

<$>[注意] 注意:要阻止流量到您的公共接口,您可以禁用您的公共接口或设置防火墙规则,以实现与Iptables相似的效果。我们将与防火墙选项一起使用,因为我们可以配置它来阻止不必要的网络流量,同时允许我们的服务器在启动连接时访问互联网(这对于像下载服务器上的更新等事情是有用的)。

如何访问您的VPS

在我们进入如何锁定自己的私人网络之前,我们将讨论不同的方法来访问您的服务器(特别是命令行)。

如果您在 DigitalOcean VPS 上有私人网络设置,您有三种方法可以访问它:

  • 公共接口
  • 私人接口
  • 控制面板控制控制台访问

公共接口(Public interface)

公共接口可通过全球互联网访问,这意味着您或互联网上的任何人都可以访问这个接口,除非它被锁定。

在需要通过互联网访问的服务器上,需要有一个公共接口,以便您的客户或用户可以连接到您提供的任何服务(例如网页或应用程序)。

在本教程中,我们将使用iptables来限制公共界面仅接受我们的应用程序正常运作所必需的网络流量(即HTTP)。

◎私人接口*

在DigitalOcean的情况下,这意味着只有在同一帐户下提供的其他VPS才能访问私人接口。

如果你在同一个帐户下连接到多个VPS,你可以通过SSH连接到另一个VPS的私人接口。例如,你可以将SSH连接到haproxy-www的公共接口,然后从那里连接到MySQL-1的私人接口。

在本教程中,我们将限制私人接口上的网络流量仅限于我们定义的私人网络内的VPS(上图中的橙色框)和一些其他必要的网络流量(负载平衡器和应用服务器之间)。

控制面板 控制控制面板 控制面板 控制面板 控制面板

如果您失去访问您的公共和私人接口,您可以通过控制台访问连接到您的VPS。在现实世界中,这类似于将键盘,鼠标和监视器直接连接到您的服务器。

** 注意**:如果您的 VPS 登录都使用 SSH 密钥进行身份验证,则需要通过控制面板重置根密码以通过控制台登录。

识别接口/端口访问要求

在继续之前,重要的是确定您的接口和端口访问要求。许多应用程序使用默认端口,或可配置以连接到特定接口和端口。

以下是我们示例场景的网络访问需求的分布:

  • haproxy-www:
    • Internet (public) / port 80
    • WordPress servers (private) / port 80
  • wordpress-1: (all private)
    • haproxy_www / port 80
    • wordpress-2 / various glusterFS ports
    • MySQL servers / port 3306
  • wordpress-2: (all private)
    • haproxy_www / port 80
    • wordpress-1 / various glusterFS ports
    • MySQL servers / port 3306
  • mysql-1: (all private)
    • WordPress servers / port 3306
    • mysql-2 / port 3306
  • mysql-2: Slave MySQL database server
    • WordPress servers / port 3306
    • mysql-1 / port 3306

例如,我们将允许公共SSH到另一个VPS称为 tunnel-1,并且只允许私人SSH在其他服务器上,这意味着我们将需要通过隧道-1向任何其他服务器的SSH隧道。

现在我们知道我们需要我们的防火墙接受什么,并可能下降,让我们开始配置它。

Iptables 配置的概述

以下是我们将如何配置 iptables 以满足我们的需求的概述:

  • 默认下载
  • 允许从私人网络接口到 tunnel-1 VPS
  • 允许从您的服务器启动的互联网流量
  • 明确允许特定的私人网络流量(通过IP地址和/或端口)

请注意,在iptables命令中, eth0指的是VPS的公共接口,和 eth1指的是VPS的私人接口 - 如果您的接口名称不同,请在适当的情况下替换它们。

配置公共服务器(haproxy-www)

SSH 到 tunnel-1:

ssh user@tunnel_1_public_IP

从这里, SSH 到 haproxy-www私人 接口:

ssh user@haproxy_www_private_IP

haproxy-www上,将所有链子默认设置为接受并删除任何现有规则:

1sudo iptables -P INPUT ACCEPT
2sudo iptables -P OUTPUT ACCEPT
3sudo iptables -P FORWARD ACCEPT
4sudo iptables -F

允许 tunnel-1 到 SSH 通过其私人接口到 haproxy-www:

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:

1sudo iptables -A INPUT -i lo -j ACCEPT
2sudo iptables -A OUTPUT -o lo -j ACCEPT

允许从您的服务器启动的公共和私人流量,这将允许您的服务器访问互联网,以执行下载更新或软件等操作:

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 ACCEPT

允许两个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链的默认行为来放弃所有其他流量:

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

现在你已经完成了 haproxy-www 的防火墙的配置,你会想确保一切正常工作. 如果你对你的配置感到满意,你可以通过安装 iptables-persistent 包来保存它,使用以下 apt 命令:

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

在安装 iptables-persistent 时,它会询问您是否想保存当前的防火墙设置。

现在 haproxy-www 防火墙允许:

  • SSH从隧道-1 通过私人网络
  • Loopback 流量
  • Internet 活动 haproxy-www 启动
  • HTTP 在公共互联网上
  • HTTP 自己和 WordPress 应用程序服务器之间
  • 没有来自其他来源的流量

让我们继续保护我们的剩余服务器。

配置私人网络服务器

** 注意**:对所有剩余的服务器执行所有这些步骤: wordpress-1, wordpress-2, mysql-1mysql-2. 在本节中,我们将通常将这些服务器称为 **private-VPS。

由于需要在私人网络内进行通信的网络接口和端口数量很大,我们将通过列出必要的IP地址来简化事情,而不是只允许特定IP地址和端口组合。

SSH 到 tunnel-1:

ssh user@tunnel_1_public_IP

从这里, SSH 到 private-VPSprivate 接口:

ssh user@private_VPS_private_IP

private-VPS上,将所有链子默认设置为接受并删除任何现有规则:

1sudo iptables -P INPUT ACCEPT
2sudo iptables -P OUTPUT ACCEPT
3sudo iptables -P FORWARD ACCEPT
4sudo iptables -F

允许 tunnel-1 到 SSH 通过其私人接口到私人 VPS:

sudo iptables -A INPUT -p tcp -s tunnel_1_private_IP --dport 22 -i eth1 -j ACCEPT

允许在您的服务器上反转流量. 这允许您的服务器使用 127.0.0.1 或 localhost:

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

允许从您的服务器启动的公共和私人流量,这将允许您的服务器访问互联网,以执行下载更新或软件等操作:

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 ACCEPT

仅在 两个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,因为我们信任我们私人网络上的服务器:

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

现在你已经完成了配置private-VPS的防火墙,你会想确保一切正常工作. 如果你对你的配置感到满意,你可以通过安装 iptables-persistent 包来保存它,使用以下 apt 命令:

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

在安装 iptables-persistent 时,它会询问您是否想保存当前的防火墙设置。

现在 private-VPS 防火墙允许:

*从隧道-1通过私人网络的SSH *路由流量 *私人VPS启动的互联网活动

  • 所有输出网络流量
  • 白名单中的所有服务器之间的所有输入网络流量(即私人网络区域内的所有服务器)
  • 没有来自其他来源的输入流量

故障排除: Iptables 列表和日志

如果您配置防火墙并发现应用程序停止工作,解决问题的最佳方法是查看策略列表和日志。

显示 Iptables 配置

若要查看 iptables 配置或策略列表,请运行以下命令:

1sudo iptables -vL --line-numbers

它会显示您设置的所有链条和规则,包括行号码,还会显示丢失的包的数量,如果您预计没有丢失的包,请检查日志。

阅读 Iptables 日志

创建一个名为 LOG 的链条:

1iptables -N LOG

路由 INPUT/OUTPUT/FORWARD 到 LOG 链(用您要监控的链代替CHAIN,例如INPUT):

iptables -A INPUT -j LOG

现在用这个命令登录这些包:

1iptables -A LOG -m limit --limit 60/min -j LOG --log-prefix "Iptables DROP: " --log-level 7

现在你可以监控你的系统消息,看看哪些包正在被丢弃。

在Ubuntu中,可以通过以下命令实时阅读消息:

1sudo tail -f /var/log/syslog

在CentOS中,可以通过以下命令实时阅读消息:

1sudo tail -f /var/log/messages

日志将列出接口、源端口、目的地端口以及关于每个丢弃的包的其他信息,这应该有助于您找出您可能遇到的任何问题。

结论

遵循本教程后,你应该有一个很好的基础,使用iptables来保护你的VPS从公共互联网和其他VPS在相同的共享私人网络(即相同的数据中心)内。

Published At
Categories with 技术
comments powered by Disqus