亚马逊AWS官方博客

Network Firewall 部署小指南(三)安装指南

Network Firewall(以下简称 NFW)为您的 VPC 和子网提供了全面的网络流量检查与防护功能。本文将基于出站流量检查分布式部署模型,详细阐述如何通过 AWS Console 完成 NFW 的安装过程。安装和配置完成后,NFW 的安全策略能够对私有子网中的主机进行所有对外 Internet 访问的控制,并将这些访问活动记录在 NFW 日志中。

架构说明

根据出站流量检查分布式部署模型的推荐,我们为 VPC 设计了两个可用区和三个子网的架构:应用私有子网(App subnet)、防火墙子网(Firewall subnet)、NAT 网关子网(NATGW subnet)。将 NFW 部署在 NAT 网关和业务子网之间,这样的设计使得 NFW 的日志记录中包含源 IP 地址信息,这对于在发生安全事件时进行有效的溯源调查至关重要。

NFW 是由 AWS 提供的一项托管防火墙服务,它能够自动扩展,为您的工作负载提供安全而可靠的保障。在每个可用区中,NFW 呈现为一个特定的 endpoint(例如:vpce-xxxxxxxxxxxxxxxxx),您无需关注 NFW 背后的基础设施。

步骤一:创建两个有状态规则组

我们将介绍两种创建防火墙规则组的方法:一种是基于 Suricata 规则来记录日志,另一种是利用域名列表(domain list)来创建域名白名单。在第二步的策略配置中,我们将添加一条默认的 drop established 规则。这几条规则的共同作用是,只允许业务子网中的主机访问特定的域名,同时拒绝所有其他类型的访问请求,并确保所有第三至第七层的流量都被记录下来。

基于 Suricata 规则记录日志

在 VPC 界面下,找到 Network Firewall 菜单中的 Network Firewall rule groups,点击 Create rule group。选择 Stateful rule group,在 Rule group format 下拉菜单中选择 Suricata compatible rule string,选择 Strict order 后,点击 Next。

使用 Strict order 时,如果在 NFW 策略中添加了多个规则组,规则组将根据优先级顺序进行评估,从最低编号开始。每个规则组中的规则将按照它们定义的顺序自上而下进行处理。Action order 按照如下顺序进行处理:pass, drop, reject, alert。我们建议 NFW 的有状态规则组的规则评估顺序使用 Strict order。

输入规则组名称 RuleGroup-Suricata-AlertLog,Capacity 里填写 1000。请注意,Capacity 指的是规则组中的条目数量。一旦这个容量被确定,它将无法更改。因此,在规划时,您应该考虑到规则条目可能增加的情况,并预留出足够的扩展空间。

在 Suricata compatible rule string 输入框中,您可以粘贴预先制定好的规则。以下是一个示例,展示了如何创建一个自定义的 Suricata 规则来记录出站流量日志。您可以根据企业自身的安全需求对规则进行调整和定制。

# 放行icmp和ntp,不记录日志
pass ntp $HOME_NET any -> $EXTERNAL_NET 123 (msg:"pass rules do not alert/log"; flow:to_server; sid:100011;)
pass icmp $HOME_NET any -> $EXTERNAL_NET any (msg:"pass rules do not alert/log"; sid:100012;)

# 放行aws域名,不记录日志
pass tls $HOME_NET any -> $EXTERNAL_NET any (msg:"pass rules do not alert/log"; tls.sni; content:".amazonaws.com"; nocase; endswith; flow:to_server; sid:100021;)

# 记录所有http和https访问日志
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"http allowed"; flow:to_server; sid:100031;)
alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"tls allowed"; flow:to_server; sid:100032;)

# 记录所有tcp和udp连接
alert tcp $HOME_NET any -> $EXTERNAL_NET ![80,443] (msg:"tcp allowed"; flow:to_server; sid:100041;)
alert udp $HOME_NET any -> $EXTERNAL_NET any (msg:"udp allowed"; sid:100042;)

Suricata 规则中的关键词解释如下:

  • pass 表示允许通过,并中断匹配数据包的检查,退出规则组。
  • drop 表示拒绝通过,并向防火墙的警告日志(alert logs)发送消息,继续匹配余下规则。
  • alert 表示对于每条匹配的规则,都会向防火墙的 alert logs 发送消息,继续匹配余下规则。
  • HOME_NET 变量表示 NFW 所在 VPC 的 CIDR 范围。EXTERNAL_NET 为 HOME_NET 取反。
  • flow:to_server 表示从客户端 HOME_NET 到服务端 EXTERNAL_NET 发起请求,并能将 TCP(四层)和 HTTP (七层)规则在同一层级上执行。如果没有这一关键词,NFW 的有状态引擎会先处理低层级(四层)的 TCP 协议。
  • msg 里的描述会体现在 alert logs 中的 event.alert.signature 字段。
  • sid 为规则的唯一编号,赋值在 alert logs 中的 event.alert.signature_id 字段。

利用 Domain List 创建域名白名单

点击 Create rule group,继续创建一个域名白名单规则。在 Rule group format 下拉菜单中选择 Domain list。

规则组名称为 RuleGroup-DomainList-AllowList,Capacity 里填写 2000。

输入需要允许的域名,这里以 google 和 github 两个域名举例。您可以通过一个初始的“.”来表示域名通配符。

保留以下默认选项,点击 Next。

步骤二:创建 NFW 策略

点击 Create firewall policy 创建一个名称为 nfw-policy-lab 的策略,保留 Stream exception policy 默认值设置。

保留无状态默认规则的默认值。

当流量抵达 NFW,首先会经过无状态引擎,该引擎会根据配置的无状态规则来处理数据包。无状态引擎可能会丢弃一个数据包,将其传递到目的地,或者将其转发到有状态规则引擎。我们建议 NFW 使用有状态引擎处理数据包。

在配置有状态默认规则时,选择 Drop established。这意味着,如果 NFW 在步骤一中定义的两个规则组中都没有找到匹配的条目,流量将会受到这条默认规则的影响。Drop established 表示仅丢弃那些已经处于已建立连接状态的数据包,但对于建立七层连接所需的三层和四层的握手数据包,则允许它们通过。被 drop established 规则所丢弃的流量不会生成 alert log。我们推荐在 NFW 有状态默认规则中采用 drop established。

点击 Add stateful rule groups,将之前在步骤一中创建的两个规则组导入。务必确保规则组 RuleGroup-Suricata-AlertLog 的优先级高于 RuleGroup-DomainList-AllowList。这是因为,如果优先级设置不当,一旦流量匹配到 domain list 中的 allow 域名规则,它将直接退出防火墙检查而不会触发任何日志记录。

连续点击下一步后,创建防火墙策略。

步骤三:创建 NFW

点击 Create firewall 创建 NFW,名称为 nfw-lab。

选择 VPC 和子网。如果您的工作负载部署在两个可用区,NFW 应当部署在这两个可用区。

Firewall policy 选择 Associate an existing firewall policy,关联步骤二中创建的 nfw-policy-lab 策略。

待 NFW 创建完成后,在 Firewalls 界面中的 Firewall endpoints status 显示为 Ready,然后进行下一步操作。

步骤四:修改 VPC 路由表

App subnet,Firewall subnet 和 NATGW subnet 各自关联一张路由表,这三张路由表需要做如下修改。由于修改 VPC 的路由表可能会导致现有的连接中断,因此在上线 NFW 时应当预留一个割接窗口。

  • App subnet 路由表中,添加 0.0.0.0/0,指向同 AZ 的 NFW endpoint。
  • Firewall subnet 路由表中,添加 0.0.0.0/0,指向同 AZ 的 NAT 网关。
  • NATGW subnet 路由表中,把 0.0.0.0/16 的 local 路由更换成同 AZ 的 NFW endpoint。

步骤五:验证和日志查看

您可以运行 curl 测试命令来验证防火墙策略是否配置正确。在以下示例中,允许域名 https://www.google.com,客户端收到的响应是 200 OK。

curl -v --silent https://www.google.com --stderr - | grep 200
< HTTP/2 200

在以下示例中,域名 https://www.baidu.com 被阻止。

curl -v https://www.baidu.com
* Host www.baidu.com:443 was resolved.
* IPv6: (none)
* IPv4: 103.235.46.96, 103.235.47.188
*   Trying 103.235.46.96:443...
* Connected to www.baidu.com (103.235.46.96) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/pki/tls/certs/ca-bundle.crt
*  CApath: none

由于没有在规则组 RuleGroup-DomainList-AllowList 中放行 baidu,访问 baidu 的请求匹配到了默认规则 drop established。

在 NFW 的 Logging 选项中点击 Edit。

在配置日志记录时,Logging configuration 中勾选 Alert。alert logs 记录了匹配到 alert 或 drop 的有状态规则的流量日志。而 flow logs 则记录了无状态引擎转发给有状态规则引擎处理的所有网络流量日志。为了有效降低日志数据量,我们推荐仅启用 alert logs。

这里,我们把 alert logs 存放在 CloudWatch log group 中。

进入 CloudWatch Logs 查看访问 google 的日志。

总结

本文详细介绍了如何在一个 VPC 网络环境中逐步部署出站流量检查的分布式模型。通过结合 Suricata、域名列表及默认规则,我们实现了仅允许特定域名进行访问,同时阻止所有其他访问请求,并记录了所有三至七层的流量日志。经过测试,我们成功验证了配置的有效性。

参考文档

[1] AWS 网络防火墙入门

[2] 如何配置我的网络防火墙规则以阻止或允许特定的域名?

[3] 在 AWS 网络防火墙中定义规则操作

本篇作者

刘一白

亚马逊云科技解决方案架构师,负责亚马逊云科技网络相关的服务和产品。在企业网、数据中心和云网络有着丰富的实践经验,拥有 AWS Certified Advanced Networking Specialty 和 Cisco Certified Internetwork Expert 等网络技术相关认证。