如何使用Doctl使用DigitalOcean云防火墙保护Web服务器基础架构
介绍
DigitalOcean Cloud Firewalls 在网络级别提供强大的防火墙服务,保护您的资源免受未经授权的流量。
虽然您可以通过 DigitalOcean 控制面板配置云防火墙,但当您需要管理多个 Droplet、需要编写进程脚本或更喜欢从终端工作时,命令行界面可能是更好的选择。
在本教程中,我们将学习如何使用 doctl
(官方 DigitalOcean 命令行客户端 )来为 Web 服务器创建和管理云防火墙。
先决条件
对于本教程,您将需要:
doctl
1.7.0 版本按照doctl GitHub存储库中的官方安装说明进行安装和认证。 (使用doctl version
命令验证您正在运行的doctl
版本。)- 按照 如何将 SSH 密钥与 DigitalOcean Droplets 教程一起添加到您的 DigitalOcean 帐户的 SSH 密钥。
我们将在 nyc1 区域中创建运行 Ubuntu 16.04 的一键式 LAMP(Linux、Apache、MySQL、PHP)堆栈映像,并将其放在 512MB 的 Droplet 上。 不过,在开始本教程之前,我们建议您通过阅读 如何使用 Doctl、官方 DigitalOcean 命令行客户端 和 来熟悉 doctl
和云防火墙。 DigitalOcean 云防火墙。
第 1 步 — 设置 Web 服务器
首先,我们将为我们的 Droplet 选择一个区域。 我们将在本教程中使用 nyc1,但您可以使用以下命令查看所有区域及其 slug:
doctl compute region list
OutputSlug Name Available nyc1 New York 1 true sfo1 San Francisco 1 true ams2 Amsterdam 2 true sgp1 Singapore 1 true lon1 London 1 true nyc3 New York 3 true ams3 Amsterdam 3 true fra1 Frankfurt 1 true tor1 Toronto 1 true sfo2 San Francisco 2 true blr1 Bangalore 1 true
由于我们不想通过网络发送密码并且我们想减少 暴力攻击 的可能性,我们将使用 SSH 密钥身份验证来保护我们的 Web 服务器。
要创建包含 SSH 密钥的 Droplet,doctl
需要 SSH 密钥指纹,您可以使用以下命令获取:
doctl compute ssh-key list
OutputID Name FingerPrint 9763174 sammy_rsa your_ssh_key_fingerprint
复制要与 Droplet 一起使用的 SSH 密钥的指纹。
现在,让我们将所有内容放在一个命令中,该命令将在 nyc1 区域中创建一个名为 web-1 的 512MB 液滴,使用运行 Ubuntu 16.04 的一键式 LAMP 堆栈图像和我们的SSH 密钥。
doctl compute droplet create web-1 \ --region nyc1 \ --image lamp-16-04 \ --ssh-keys your_ssh_key_fingerprint \ --size 512mb
输出为我们提供了刚刚创建的 Droplet 的概览,包括 Droplet 的 ID、名称、IPv4 地址、内存等:
OutputID Name Public IPv4 Private IPv4 Public IPv6 Memory VCPUs Disk Region Image Status Tags 52059458 web-1 512 1 20 nyc1 Ubuntu LAMP on 16.04 new
注意: 您需要等待几分钟才能完成配置过程。 配置后,Droplet 将具有 IPv4 地址和状态 active
而不是 new
。
使用以下命令检查您的 Droplet 的状态,如果已完全配置,请记下 ID,因为我们在步骤 2 中将防火墙分配给 Droplet 时需要它。 在您的 Droplet 的状态显示为 active
之前,请勿越过此步骤。
doctl compute droplet list web-1
OutputID Name Public IPv4 Private IPv4 Public IPv6 Memory VCPUs Disk Region Image Status Tags 52059458 web-1 203.0.113.1 512 1 20 nyc1 Ubuntu LAMP on 16.04 active
接下来,使用 doctl
通过 SSH 登录 Droplet,启用 LAMP 安装并获取有关如何准备服务器以供生产使用的其他说明。 如果您收到 connection refused
错误消息,则您的 Droplet 尚未准备好。 等待几分钟,然后重新运行 list
命令以验证您的 Droplet 的状态是否设置为 active
,然后再继续。
doctl compute ssh web-1
Output... ------------------------------------------------------------------------------- Thank you for using DigitalOcean's LAMP Application. LAMP has now been enabled. You can access your LAMP instance at: Your web root is located at /var/www/html and can be seen from http://203.0.113.1 ...
根据需要配置 Droplet 后,退出 SSH 会话。
[environment] exit
最后,将您的网络浏览器指向 Droplet 的 IP 地址,以确保 LAMP 堆栈正常工作。 您应该会看到默认的 DigitalOcean 一键式 LAMP 堆栈登录页面,其中包含以下消息:“请通过 SSH 登录到您的 droplet 以配置您的 LAMP 安装。” 如果不这样做,请重新跟踪前面的步骤,以确保您已启用 LAMP,并且您已将 Droplet 的 IP 地址正确复制到浏览器中。
因为我们已经完成了本教程所需的 LAMP 配置,所以我们准备继续保护 Droplet 免受未经授权的流量。
第 2 步 — 为 Web 服务器创建防火墙
首先,我们将使用从步骤 1 中的 doctl compute droplet list
命令获得的 Droplet ID 创建一个名为 web-firewall
的云防火墙,允许端口 22
上的入站 SSH 连接以及所有出站 TCP、UDP 和 ICMP 连接。 这将使我们能够从命令行管理服务器,同时仍然让许多基础服务能够正常运行。
protocol
字段是必需的,必须设置为 tcp
、udp
或 icmp
,并且必须包含 ports
值对于除 icmp
之外的所有协议,根据其 规范 ,它不需要一个。
address
字段指定允许哪些 IP 地址访问给定端口。 如果要允许来自所有 IPv4 地址的流量,请使用 0:0:0:0/0
,如果要允许来自所有 IPv6 地址的流量,请使用 ::0/0
。
最后,您创建的每个防火墙必须至少有一个规则,在 --inbound-rules
或 --outbound-rules
标志下,并且所有值必须以逗号分隔的 key:value
列表形式输入。 对多个规则使用带引号的空格分隔值字符串。
现在,使用 create
命令创建防火墙:
doctl compute firewall create --name web-firewall \ --droplet-ids your_droplet_id \ --inbound-rules "protocol:tcp,ports:22,address:0.0.0.0/0,address:::/0" \ --outbound-rules "protocol:icmp,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:all,address:0.0.0.0/0,address:::/0 protocol:udp,ports:all,address:0.0.0.0/0,address:::/0"
输出包含新云防火墙的基本概述。 记下云防火墙的 ID,因为您将在第 3 步中使用它向防火墙添加其他规则。
OutputID Name Status Created At Inbound Rules Outbound Rules Droplet IDs Tags Pending Changes c7b39b43-4fcc-4594-88f2-160a64aaddd4 web-firewall waiting 2017-06-17T21:20:38Z protocol:tcp,ports:22,address:0.0.0.0/0,address:::/0 protocol:icmp,ports:0,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:0,address:0.0.0.0/0,address:::/0 protocol:udp,ports:0,address:0.0.0.0/0,address:::/0 your_droplet_id droplet_id:your_droplet_id,removing:false,status:waiting
如果您需要指定端口范围,请使用以下格式:
--inbound-rules "protocol:tcp,ports:8000-8080,address:0.0.0.0/0,address:::/0"
您也可以使用 droplet_id
标志代替 address
标志。 这在涉及多个 Droplet 相互通信的设置中特别有用。
--inbound-rules "protocol:tcp,ports:8000-8080,droplet_id:your_droplet_id"
而且,您可以将多个 address
或 droplet_id
字段组合成一个规则,例如:
--inbound-rules "protocol:tcp,ports:8000-8080,droplet_id:your_first_droplet_id,droplet_id:your_second_droplet_id"
此时,通过将 Web 浏览器指向 Droplet 的 IP 地址来确认云防火墙工作正常。 您应该会看到一条消息,指示该站点不再可访问。 如果不这样做,请仔细检查上一个 create
命令的输出,以确保您没有错过任何错误消息。
最后,即使我们的入站规则应该已经允许 SSH,我们仍将使用 doctl
对其进行验证。
doctl compute ssh web-1
如果您无法连接到 Droplet,如何排除 SSH 教程系列将帮助您诊断问题。
成功连接到 Droplet 后,退出 SSH 会话:
[environment] exit
由于我们现在已经验证云防火墙工作正常,我们将添加一个附加规则以允许传入 Web 服务器的流量。
第 3 步 — 添加附加规则
使用我们在步骤 2 中从 doctl compute firewall create
命令获得的防火墙 ID,我们现在将添加一个规则以允许端口 80
上的 Apache 入站 TCP 流量。
我们将使用 add-rules
命令,它需要防火墙 ID 和至少一个规则。 规则使用 --outbound-rules
和 --inbound-rules
标志指定,就像在步骤 2 中一样。
doctl compute firewall add-rules c7b39b43-4fcc-4594-88f2-160a64aaddd4 \ --inbound-rules "protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0"
如果您需要 HTTPS,请允许端口 443
上的入站 TCP 流量。
doctl compute firewall add-rules c7b39b43-4fcc-4594-88f2-160a64aaddd4 \ --inbound-rules "protocol:tcp,ports:443,address:0.0.0.0/0,address:::/0"
如果成功,此命令将不产生任何输出。 如果您收到错误消息,请按照屏幕上的说明诊断问题。
现在,将您的网络浏览器重新指向您的 Droplet 的 IP 地址。 这次您应该再次看到默认的 DigitalOcean 一键式 LAMP 堆栈登陆页面。 如果没有,请仔细检查您是否已将 IP 地址正确复制到 Web 浏览器中,然后重新跟踪前面的步骤。
如果您有其他要保护的 Web 服务器,请继续执行第 4 步。 否则,请跳至第 5 步,我们将使用标签管理云防火墙。
(可选)第 4 步 — 将 Droplet 添加到防火墙
如果您有多个 Droplet,则可以对每个 Droplet 应用相同的 Cloud Firewall。
使用 add-droplets
命令将额外的 Droplet 添加到云防火墙。 此命令需要云防火墙 ID 作为参数,它使用 droplet-ids
标志来确定将防火墙应用到哪些 Droplet。
如果您不知道云防火墙的 ID,请使用 list
命令:
doctl compute firewall list
OutputID Name Status Created At Inbound Rules Outbound Rules Droplet IDs Tags Pending Changes c7b39b43-4fcc-4594-88f2-160a64aaddd4 web-firewall succeeded 2017-06-17T21:20:38Z protocol:tcp,ports:22,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0 protocol:icmp,ports:0,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:0,address:0.0.0.0/0,address:::/0 protocol:udp,ports:0,address:0.0.0.0/0,address:::/0 52059458
您还可以使用 list
命令获取 Droplet 的 ID:
doctl compute droplet list
OutputID Name Public IPv4 Private IPv4 Public IPv6 Memory VCPUs Disk Region Image Status Tags 51146959 test-1 203.0.113.1 512 1 20 nyc1 Ubuntu LAMP on 16.04 active 52059458 web-1 203.0.113.2 512 1 20 nyc1 Ubuntu LAMP on 16.04 active
使用以下 doctl
命令,我们将 test-1
Droplet 添加到 web-servers
防火墙,其 ID 为 c7b39b43-4fcc-4594-88f2-160a64aaddd4
:
doctl compute firewall add-droplets c7b39b43-4fcc-4594-88f2-160a64aaddd4 \ --droplet-ids 51146959
如果您没有收到任何输出,则该命令成功。 如果您收到错误消息,请按照屏幕上的说明诊断问题。
而且,如果您想一次添加多个 Droplet,请使用逗号将它们分开。 请注意,两个 ID 之间没有空格:
--droplet-ids 51146959,52059458
现在,让我们使用标签来更轻松地管理云防火墙。
第 5 步 — 使用标签
此时,我们已将单独的 Droplet 添加到 Cloud Firewall,但 Cloud Firewalls 还支持标签,以便更轻松地管理多个资源。 要更好地了解标签的工作原理,请参阅 如何标记 DigitalOcean Droplets。
在这一步中,我们将标记 Droplet,将标记添加到云防火墙,然后从防火墙中删除各个 Droplet ID,以通过标记保持 Droplet 的安全。
在我们可以使用 doctl
向 Droplet 添加标签之前,我们需要先使用 tag create
命令创建标签:
doctl compute tag create web-servers
OutputName Droplet Count web-servers 0
创建标签后,使用 droplet tag
命令将其应用于 Droplet。 该命令将 Droplet ID 作为参数,并从 --tag-name
标志中获取标签名称。
doctl compute droplet tag 52059458 \ --tag-name "web-servers"
如果您想使用一个云防火墙保护多个 Droplet,请对每个 Droplet 重复上一个命令。
接下来,使用 add-tags
命令将标签添加到云防火墙,该命令将防火墙 ID 作为参数并从 --tag-names
标志中获取要使用的标签名称列表:
doctl compute firewall add-tags c7b39b43-4fcc-4594-88f2-160a64aaddd4 \ --tag-names web-servers
如果您没有收到任何输出,则该命令成功。 如果您收到错误消息,请按照屏幕上的说明诊断问题。
而且,如果您需要添加多个标签,请将它们作为逗号分隔的列表提供:
--tag-names web-servers,backend-servers
最后,我们可以从防火墙中删除 Droplet 的 ID,因为 Droplet 是 web-servers
标签的一部分,并且整个标签现在都受到保护。
doctl compute firewall remove-droplets c7b39b43-4fcc-4594-88f2-160a64aaddd4 \ --droplet-ids 52059458
对您希望仅通过标签保护的每个 Droplet 重复上一步。
警告: 从云防火墙中删除未标记的 Droplet 会使 Droplet 不受未经授权的流量的保护。
您现在拥有一个完全配置的云防火墙,它将保护您的 Web 服务器免受未经授权的流量。 如果您还想从防火墙中删除规则,请继续执行步骤 6。
(可选)第 6 步 — 从防火墙中删除规则
如果要从云防火墙中删除规则,请使用 remove-rules
命令。
remove-rules
命令将防火墙 ID 作为其参数,并使用 --outbound-rules
和 --inbound-rules
标志指定规则。 请注意,指定的规则必须与创建期间使用的规则完全相同。
doctl compute firewall remove-rules c7b39b43-4fcc-4594-88f2-160a64aaddd4 \ --inbound-rules protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0
如果您没有收到任何输出,则该命令成功。 如果您收到错误消息,请按照屏幕上的说明诊断问题。
结论
在本教程中,我们使用 doctl
创建 DigitalOcean Cloud 防火墙,向这些防火墙添加规则,向防火墙添加额外的 Droplet,使用标签管理防火墙,以及从防火墙中删除规则。
要了解使用云防火墙的其他方法,请参阅 如何组织 DigitalOcean 云防火墙。
并且,要了解云防火墙的故障排除,请访问 如何对 DigitalOcean 防火墙进行故障排除 。