如何通过使用Doctl的DigitalOcean云防火墙来保护Web服务器基础设施

了解如何使用官方的DigitalOcean Command-Line Client来创建和管理Web服务器的Cloud Firewall。

介绍

DigitalOcean Cloud防火墙在网络级别提供强大的防火墙服务,可以保护您的资源免遭未经授权的流量。

虽然您可以通过DigitalOcean控制面板配置云端防火墙,但是当您有许多需要管理的Droplet时,需要对流程进行脚本编写,或者更喜欢从终端工作,所以命令行界面可以是更好的选择。

在本教程中,我们将学习如何使用官方的DigitalOcean Command-Line Client来创建和管理Web服务器的Cloud Firewall。

先决条件

对于本教程,您将需要:

我们将在nyc1区域中创建一个运行Ubuntu 16.04的一键式LAMP(Linux,Apache,MySQL,PHP)映像,我们将把它放在一个512MB的Droplet上。 在开始本教程之前,我们建议您通过阅读如何使用Doctl,官方DigitalOcean命令行客户端DigitalOcean Cloud Firewall简介来熟悉doctlCloud Firewall

第1步 - 设置Web服务器

首先,我们将为我们的Droplet选择一个地区。 我们将在本教程中使用nyc1 ,但您可以使用以下命令查看所有区域及其lug::

doctl compute region list
Slug    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
ID         Name                  FingerPrint
9763174    sammy_rsa             your_ssh_key_fingerprint

复制要用于您的Droplet的SSH密钥的指纹。

现在,让我们将所有东西放在一起,命令将在nyc1区域中创建一个名为web-1的512MB Droplet命令,使用我们的SSH密钥运行Ubuntu 16.04的一键式LAMP映像。

doctl compute droplet create web-1 \
    --region nyc1 \
    --image lamp-16-04 \
    --ssh-keys your_ssh_key_fingerprint \
    --size 512mb

输出结果给出了我们刚刚创建的Droplet的概述,包括Droplet的ID,名称,IPv4地址,内存等等:

ID          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的状态,如果已完全配置,请在第2步中将防火墙分配给Droplet时注意ID。不要移动此步骤,直到Droplet的状态读取active

doctl compute droplet list web-1
ID          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
...
-------------------------------------------------------------------------------
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

最后,将Web浏览器指向Droplet的IP地址,以确保LAMP正常工作。 您应该看到默认的DigitalOcean一键式LAMP着陆页,其中包含以下消息:“请通过SSH登录您的Droplet以配置您的LAMP安装。 如果没有,请重新查看以前的步骤,以确保已启用LAMP,并且您已将Droplet的IP地址正确复制到浏览器中。

因为我们已经完成了本教程所需的LAMP配置,我们已经准备好继续保护Droplet免遭未经授权的流量。

第2步 - 创建Web服务器的防火墙

首先,我们将使用第1步中从doctl compute droplet list命令获得的Droplet ID,创建一个名为web-firewall的云web-firewall ,该web-firewall允许端口22上的入站SSH连接和所有出站TCP,UDP和ICMP连接。 这将让我们从命令行管理服务器,同时仍然使许多基础服务能够正常运行。

protocol字段是必需的,并且必须设置为tcpudpicmp ,并且必须包括除icmp之外的所有协议的ports值,该规范根据其规范不需要。

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步中使用它来向防火墙添加其他规则。

ID                                      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地址,确认Cloud Firewall正常工作。 您应该会看到一条消息,指出该站点不再可访问。 如果没有,请仔细检查以前的create命令的输出,以确保没有错过任何错误消息。

最后,即使我们的入站规则已经允许SSH,我们将使用doctl验证。

doctl compute ssh web-1

如果您无法连接到Droplet,则如何解决SSH教程系列将帮助您诊断问题。

成功连接到Droplet后,退出SSH会话:

[environment]
exit

我们现在已经验证了Cloud Firewall是否正常工作,我们将添加一条额外的规则来允许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,您可以对其中的每一个应用相同的Cloud Firewall。

使用add-droplets命令将额外的滴滴添加到云端防火墙。 此命令需要一个Cloud Firewall ID作为参数,并使用“ droplet-ids标记来确定应用防火墙的哪个Droplet。

如果您不知道Cloud Firewall的ID,请使用list命令:

doctl compute firewall list
ID                                      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命令获取Droplets的ID:

doctl compute droplet list
ID          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步 - 使用标签

此时,我们已经将云滴添加到云端防火墙,但云端防火墙还支持标签,以便更轻松地管理多种资源。 要更好地了解标签的工作原理,请参阅如何标记DigitalOcean Droplet

在此步骤中,我们将标记Droplet,将标签添加到Cloud Firewall,然后通过标签从“防火墙”中删除各个Droplet ID,从而保护Droplets的安全。

在使用doctl添加标签到Droplet doctl ,我们需要先使用tag create命令创建Tag:

doctl compute tag create web-servers
Name           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命令add-tags到云防火墙,该命令将Firewall 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标签的一部分,整个Tag现在都受到保护。

doctl compute firewall remove-droplets c7b39b43-4fcc-4594-88f2-160a64aaddd4 \
    --droplet-ids 52059458

对您想要通过标签保护的每个滴液重复上一步。

警告:从云端防火墙中删除未标记的Droplet会使得Droplet不受保护,防止未经授权的流量。

您现在有一个完全配置的云防火墙,它将保护您的Web服务器免受未经授权的流量。 如果您还想从防火墙删除规则,请继续执行第6步。

(可选)第6步 - 从防火墙中删除规则

如果要从Cloud Firewall中remove-rules ,请使用remove-rules命令。

remove-rules命令采用防火墙ID作为参数,并使用--outbound-rules--inbound-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 Firewalls,向这些防火墙添加规则,向防火墙添加附加的数据流,使用标签管理防火墙,并从防火墙中删除规则。

要了解使用Cloud Firewall的其他方法,请参阅如何组织DigitalOcean Cloud Firewalls

另外,要了解云防火墙的故障排除 ,请访问如何解决DigitalOcean防火墙问题