选择您的 Cookie 首选项

我们使用必要 Cookie 和类似工具提供我们的网站和服务。我们使用性能 Cookie 收集匿名统计数据,以便我们可以了解客户如何使用我们的网站并进行改进。必要 Cookie 无法停用,但您可以单击“自定义”或“拒绝”来拒绝性能 Cookie。

如果您同意,AWS 和经批准的第三方还将使用 Cookie 提供有用的网站功能、记住您的首选项并显示相关内容,包括相关广告。要接受或拒绝所有非必要 Cookie,请单击“接受”或“拒绝”。要做出更详细的选择,请单击“自定义”。

使用 Network Firewall 从服务器名称指示中捕获出站流量的 DNS 域名 - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Network Firewall 从服务器名称指示中捕获出站流量的 DNS 域名

由 Kirankumar Chandrashekar (AWS) 创建

摘要

此模式向您展示如何使用 AWS Network Firewall 收集服务器名称指示 (SNI) 在出站网络流量的 HTTPS 标头中提供的 DNS 域名。Network Firewall 是一项托管服务,可以轻松地为 Amazon Virtual Private Cloud (Amazon VPC) 部署关键网络保护,包括能够使用防火墙来保护出站流量,该防火墙可以阻止不符合某些安全要求的数据包。保护特定 DNS 域名的出站流量称为出口过滤,这是一种监视并可能限制从一个网络到另一个网络的出站信息流的做法。

捕获通过网络防火墙的 SNI 数据后,您可以使用亚马逊 CloudWatch 日志和 AWS Lambda 将数据发布到生成电子邮件通知的亚马逊简单通知服务 (Amazon SNS) Simple Notification Service 主题。电子邮件通知包括服务器名称和其他相关 SNI 信息。此外,您可使用此模式的输出通过防火墙规则在 SNI 中按域名允许或限制 SNI 中的出站流量。有关更多信息,请参阅 Network Firewall 文档中的在 AWS Network Firewall 中使用有状态规则组

先决条件和限制

先决条件

架构

下图显示了如何使用 Network Firewall 从出站网络流量中收集 SNI 数据,然后使用 CloudWatch 日志和 Lambda 将这些数据发布到 SNS 主题。

Network Firewall、 CloudWatch Lambda 和 Amazon SNS 之间的工作流程。

图表显示了以下工作流:

  1. 网络防火墙从出站网络流量的 HTTPS 标头中的 SNI 数据收集域名。

  2. CloudWatch 日志监控 SNI 数据,并在出站网络流量通过 Network Firewall 时调用 Lambda 函数。

  3. Lambda 函数读取 CloudWatch 日志捕获的 SNI 数据,然后将该数据发布到 SNS 主题。

  4. SNS 主题会向您发送包含 SNI 数据的电子邮件通知。

自动化和扩缩

技术堆栈

  • Amazon CloudWatch 日志

  • Amazon SNS

  • Amazon VPC

  • AWS Lambda 

  • AWS Network Firewall

工具

Amazon Web Services

  • 亚马逊 CloudWatch 日志 — 您可以使用亚马逊 CloudWatch 日志来监控、存储和访问来自亚马逊弹性计算云 (Amazon EC2) 实例、AWS CloudTrail、Amazon Route 53 和其他来源的日志文件。

  • Amazon SNS – Amazon Simple Notification Service (Amazon SNS) 是一项托管服务,提供从发布者到订阅用户(也称为创建者和使用者)的消息传输。

  • Amazon Virtual Private Cloud (Amazon VPC) 可预置 Amazon Web Services Cloud 的逻辑隔离部分,您可以在其中启动您定义的虚拟网络中的 AWS 资源。这个虚拟网络与您在数据中心中运行的传统网络极其相似,并会为您提供使用Amazon云科技可扩展基础设施的优势。

  • AWS Lambda — AWS Lambda 是一项计算服务,可帮助您运行代码,无需预置或管理服务器。

  • AWS Networ k Firewall — AWS Network Firewall 是一项托管服务,可让您轻松地为所有亚马逊部署基本的网络保护 VPCs。

操作说明

Task描述所需技能

创建 CloudWatch 日志组。

  1. 登录 AWS 管理控制台并打开CloudWatch 控制台

  2. 在导航窗格中,选择日志组

  3. 选择操作,然后选择创建日志组

  4. 输入日志组的名称,然后选择创建日志组

有关更多信息,请参阅 CloudWatch 文档中的使用日志组和日志流

云管理员

为 Network Firewall 创建 CloudWatch 日志组

Task描述所需技能

创建 CloudWatch 日志组。

  1. 登录 AWS 管理控制台并打开CloudWatch 控制台

  2. 在导航窗格中,选择日志组

  3. 选择操作,然后选择创建日志组

  4. 输入日志组的名称,然后选择创建日志组

有关更多信息,请参阅 CloudWatch 文档中的使用日志组和日志流

云管理员
Task描述所需技能

创建 SNS 主题。

要创建 SNS 主题,请按照 Amazon SNS 文档中的说明进行操作。

云管理员

为端点订阅 SNS 主题。

要订阅电子邮件地址作为您创建的 SNS 主题的端点,请按照 Amazon SNS 文档中的说明进行操作。对于协议,选择电子邮件/电子邮件-JSON

注意

您也可以根据自己的要求选择不同的终端节点。

云管理员

创建 SNS 主题和订阅

Task描述所需技能

创建 SNS 主题。

要创建 SNS 主题,请按照 Amazon SNS 文档中的说明进行操作。

云管理员

为端点订阅 SNS 主题。

要订阅电子邮件地址作为您创建的 SNS 主题的端点,请按照 Amazon SNS 文档中的说明进行操作。对于协议,选择电子邮件/电子邮件-JSON

注意

您也可以根据自己的要求选择不同的终端节点。

云管理员
Task描述所需技能

启用防火墙日志记录。

  1. 登录 AWS 管理控制台,打开 Amazon VPC 控制台

  2. 在导航窗格中的 NETWORK FIREWALL 下,选择防火墙

  3. 防火墙部分,选择要从出站流量的 SNI 中捕获服务器名称的防火墙。

  4. 选择防火墙详细信息选项卡,然后在记录部分中选择编辑。 

  5. 对于 “日志类型”,选择 “警报”。 在警报的日志目标中,选择CloudWatch 日志组。 

  6. 对于CloudWatch 日志组,搜索并选择您之前创建的日志组,然后选择保存

有关使用 CloudWatch 日志作为网络防火墙日志目标的更多信息,请参阅网络防火墙文档中的 Amazon CloudWatch 日志。 

云管理员

在 Network Firewall 中设置登录

Task描述所需技能

启用防火墙日志记录。

  1. 登录 AWS 管理控制台,打开 Amazon VPC 控制台

  2. 在导航窗格中的 NETWORK FIREWALL 下,选择防火墙

  3. 防火墙部分,选择要从出站流量的 SNI 中捕获服务器名称的防火墙。

  4. 选择防火墙详细信息选项卡,然后在记录部分中选择编辑。 

  5. 对于 “日志类型”,选择 “警报”。 在警报的日志目标中,选择CloudWatch 日志组。 

  6. 对于CloudWatch 日志组,搜索并选择您之前创建的日志组,然后选择保存

有关使用 CloudWatch 日志作为网络防火墙日志目标的更多信息,请参阅网络防火墙文档中的 Amazon CloudWatch 日志。 

云管理员
Task描述所需技能

创建有状态规则。

  1. 登录 AWS 管理控制台,打开 Amazon VPC 控制台

  2. 在导航窗格中的网络防火墙下,选择网络防火墙规则组

  3. 选择创建 Network Firewall 规则组

  4. 创建 Network Firewall 规则页面上,对于规则组类型,选择状态规则组注意:有关更多信息,请参阅使用 AWS Network Firewall 中的有状态规则组

  5. 有状态规则组部分,输入规则组的名称和描述。

  6. 容量中,设置要允许有状态规则组的最大容量(最多 30,000)。:创建规则组之后,您无法再更改此设置。有关如何计算容量的信息,请参阅在 AWS Network Firewall 中设置规则组容量。有关最大设置的信息,请参见 AWS Network Firewall 配额

  7. 对于状态规则组选项,请选择 5 元组

  8. 状态规则顺序部分选择默认

  9. 规则变量部分下,请保留默认值。

  10. 添加规则部分,为协议选择 TLS对于来源,选择任意。对于源端口,选择任何端口对于目的地,选择任意对于目标端口,选择任何端口。对于流量方向,请选择向前。对于操作,选择警报。选择添加规则

  11. 选择创建有状态规则组

云管理员

将状态规则与 Network Firewall 关联。

  1. 登录 AWS 管理控制台,打开 Amazon VPC 控制台

  2. 在导航窗格中的 NETWORK FIREWALL 下,选择防火墙

  3. 选择要从 SNI 捕获出站流量的服务器名称的防火墙。

  4. 有状态规则组部分,选择操作,然后选择添加非托管状态规则组。 

  5. 添加非托管有状态规则组页面,选择您之前创建的有状态规则组,然后选择添加有状态规则组

云管理员

在 Network Firewall 中设置状态规则

Task描述所需技能

创建有状态规则。

  1. 登录 AWS 管理控制台,打开 Amazon VPC 控制台

  2. 在导航窗格中的网络防火墙下,选择网络防火墙规则组

  3. 选择创建 Network Firewall 规则组

  4. 创建 Network Firewall 规则页面上,对于规则组类型,选择状态规则组注意:有关更多信息,请参阅使用 AWS Network Firewall 中的有状态规则组

  5. 有状态规则组部分,输入规则组的名称和描述。

  6. 容量中,设置要允许有状态规则组的最大容量(最多 30,000)。:创建规则组之后,您无法再更改此设置。有关如何计算容量的信息,请参阅在 AWS Network Firewall 中设置规则组容量。有关最大设置的信息,请参见 AWS Network Firewall 配额

  7. 对于状态规则组选项,请选择 5 元组

  8. 状态规则顺序部分选择默认

  9. 规则变量部分下,请保留默认值。

  10. 添加规则部分,为协议选择 TLS对于来源,选择任意。对于源端口,选择任何端口对于目的地,选择任意对于目标端口,选择任何端口。对于流量方向,请选择向前。对于操作,选择警报。选择添加规则

  11. 选择创建有状态规则组

云管理员

将状态规则与 Network Firewall 关联。

  1. 登录 AWS 管理控制台,打开 Amazon VPC 控制台

  2. 在导航窗格中的 NETWORK FIREWALL 下,选择防火墙

  3. 选择要从 SNI 捕获出站流量的服务器名称的防火墙。

  4. 有状态规则组部分,选择操作,然后选择添加非托管状态规则组。 

  5. 添加非托管有状态规则组页面,选择您之前创建的有状态规则组,然后选择添加有状态规则组

云管理员
Task描述所需技能

为 Lambda 函数创建代码。

在可以从 Network Firewall 读取出站流量的 CloudWatch 日志事件的集成开发环境 (IDE) 中,粘贴以下 Python 3 代码并<SNS-topic-ARN>替换为你的值:

import json import gzip import base64 import boto3 sns_client = boto3.client('sns') def lambda_handler(event, context): decoded_event = json.loads(gzip.decompress(base64.b64decode(event['awslogs']['data']))) body = ''' {filtermatch} '''.format( loggroup=decoded_event['logGroup'], logstream=decoded_event['logStream'], filtermatch=decoded_event['logEvents'][0]['message'], ) print(body) filterMatch = json.loads(body) data = [] if 'http' in filterMatch['event']: data.append(filterMatch['event']['http']['hostname']) elif 'tls' in filterMatch['event']: data.append(filterMatch['event']['tls']['sni']) result = 'Domain accessed ' + 1*' ' + (data[0]) + 1*' ' 'via AWS Network Firewall ' + 1*' ' + (filterMatch['firewall_name']) print(result) message = {'ServerName': result} send_to_sns = sns_client.publish( TargetArn=<SNS-topic-ARN>, #Replace with the SNS topic ARN Message=json.dumps({'default': json.dumps(message), 'sms': json.dumps(message), 'email': json.dumps(message)}), Subject='Server Name passed through the Network Firewall', MessageStructure='json' )

此代码示例解析 CloudWatch 日志内容并在 HTTPS 标头中捕获 SNI 提供的服务器名称。

应用程序开发人员

创建 Lambda 函数。

若要创建 Lambda 函数,请按Lambda 文档中的说明,然后为选择 Python 3.9 作为运行时系统

云管理员

将代码添加到 Lambda 函数。

要将您的 Python 代码添加到您之前创建的 Lambda 函数中,请按照 Lambda 文档中的说明进行操作。

云管理员

将 CloudWatch 日志作为触发器添加到 Lambda 函数。

  1. 登录 AWS 管理控制台,然后打开 Lambda 控制台

  2. 在导航窗格中,选择函数,然后选择您之前创建的函数。

  3. 函数概述部分中,选择添加触发器

  4. 添加触发器页面的触发器配置部分,选择CloudWatch 日志,然后选择添加

  5. 对于日志组,请选择您之前创建的 CloudWatch 日志组。

  6. 筛选条件名称中,输入筛选条件的名称。

  7. 选择 添加

  8. 在函数页面的配置选项卡上,在触发器部分,选择刚刚添加的触发器,然后选择启用

有关更多信息,请参阅 Lambda 文档中的将 Lambda 与 CloudWatch 日志配合使用

云管理员

添加 SNS 发布权限。

向 Lambda 执行角色添加 sns:Publish 权限,这样 Lambda 就可以调用 API 将消息发布到 SNS。 

  1. 找到您之前创建的 Lambda 函数的执行角色

  2. 将以下策略添加至您的 AWS Identity and Access Management (IAM) 角色:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowSNSPublish", "Effect": "Allow", "Action": [ "sns:GetTopicAttributes", "sns:Subscribe", "sns:Unsubscribe", "sns:Publish" ], "Resource": "*" } ] }
云管理员

创建 Lambda 函数以读取日志记录

Task描述所需技能

为 Lambda 函数创建代码。

在可以从 Network Firewall 读取出站流量的 CloudWatch 日志事件的集成开发环境 (IDE) 中,粘贴以下 Python 3 代码并<SNS-topic-ARN>替换为你的值:

import json import gzip import base64 import boto3 sns_client = boto3.client('sns') def lambda_handler(event, context): decoded_event = json.loads(gzip.decompress(base64.b64decode(event['awslogs']['data']))) body = ''' {filtermatch} '''.format( loggroup=decoded_event['logGroup'], logstream=decoded_event['logStream'], filtermatch=decoded_event['logEvents'][0]['message'], ) print(body) filterMatch = json.loads(body) data = [] if 'http' in filterMatch['event']: data.append(filterMatch['event']['http']['hostname']) elif 'tls' in filterMatch['event']: data.append(filterMatch['event']['tls']['sni']) result = 'Domain accessed ' + 1*' ' + (data[0]) + 1*' ' 'via AWS Network Firewall ' + 1*' ' + (filterMatch['firewall_name']) print(result) message = {'ServerName': result} send_to_sns = sns_client.publish( TargetArn=<SNS-topic-ARN>, #Replace with the SNS topic ARN Message=json.dumps({'default': json.dumps(message), 'sms': json.dumps(message), 'email': json.dumps(message)}), Subject='Server Name passed through the Network Firewall', MessageStructure='json' )

此代码示例解析 CloudWatch 日志内容并在 HTTPS 标头中捕获 SNI 提供的服务器名称。

应用程序开发人员

创建 Lambda 函数。

若要创建 Lambda 函数,请按Lambda 文档中的说明,然后为选择 Python 3.9 作为运行时系统

云管理员

将代码添加到 Lambda 函数。

要将您的 Python 代码添加到您之前创建的 Lambda 函数中,请按照 Lambda 文档中的说明进行操作。

云管理员

将 CloudWatch 日志作为触发器添加到 Lambda 函数。

  1. 登录 AWS 管理控制台,然后打开 Lambda 控制台

  2. 在导航窗格中,选择函数,然后选择您之前创建的函数。

  3. 函数概述部分中,选择添加触发器

  4. 添加触发器页面的触发器配置部分,选择CloudWatch 日志,然后选择添加

  5. 对于日志组,请选择您之前创建的 CloudWatch 日志组。

  6. 筛选条件名称中,输入筛选条件的名称。

  7. 选择 添加

  8. 在函数页面的配置选项卡上,在触发器部分,选择刚刚添加的触发器,然后选择启用

有关更多信息,请参阅 Lambda 文档中的将 Lambda 与 CloudWatch 日志配合使用

云管理员

添加 SNS 发布权限。

向 Lambda 执行角色添加 sns:Publish 权限,这样 Lambda 就可以调用 API 将消息发布到 SNS。 

  1. 找到您之前创建的 Lambda 函数的执行角色

  2. 将以下策略添加至您的 AWS Identity and Access Management (IAM) 角色:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowSNSPublish", "Effect": "Allow", "Action": [ "sns:GetTopicAttributes", "sns:Subscribe", "sns:Unsubscribe", "sns:Publish" ], "Resource": "*" } ] }
云管理员
Task描述所需技能

通过 Network Firewall 发送流量。

  1. 发送或等待 HTTPS 流量通过网络防火墙。

  2. 检查当流量通过网络防火墙时您从 AWS 收到的 SNS 通知电子邮件。该电子邮件中包含出站流量的 SNI 详细信息。例如,如果访问的域名为 EMAIL-JSON https://aws.amazon.com且订阅协议为 EMAIL-JSON,则根据上述 Lambda 代码生成的电子邮件将包含以下内容:

{ "Type": "Notification", "MessageId": "<messageID>", "TopicArn": "arn:aws:sns:us-west-2:123456789:testSNSTopic", "Subject": "Server Name passed through the Network Firewall", "Message": "{\"ServerName\": \"Domain 'aws.amazon.com' accessed via AWS Network Firewall 'AWS-Network-Firewall-Multi-AZ-firewall\"}", "Timestamp": "2022-03-22T04:10:04.217Z", "SignatureVersion": "1", "Signature": "<Signature>", "SigningCertURL": "<SigningCertUrl>", "UnsubscribeURL": "<UnsubscribeURL>" }

然后,按照亚马逊 CloudWatch 文档中的说明查看 Amazon CloudWatch 中的 Network Firewall 警报日志。警报日志显示以下输出:

{ "firewall_name": "AWS-Network-Firewall-Multi-AZ-firewall", "availability_zone": "us-east-2b", "event_timestamp": "<event timestamp>", "event": { "timestamp": "2021-03-22T04:10:04.214222+0000", "flow_id": <flow ID>, "event_type": "alert", "src_ip": "10.1.3.76", "src_port": 22761, "dest_ip": "99.86.59.73", "dest_port": 443, "proto": "TCP", "alert": { "action": "allowed", "signature_id": 2, "rev": 0, "signature": "", "category": "", "severity": 3 }, "tls": { "subject": "CN=aws.amazon.com", "issuerdn": "C=US, O=Amazon, OU=Server CA 1B, CN=Amazon", "serial": "<serial number>", "fingerprint": "<fingerprint ID>", "sni": "aws.amazon.com", "version": "TLS 1.2", "notbefore": "2020-09-30T00:00:00", "notafter": "2021-09-23T12:00:00", "ja3": {}, "ja3s": {} }, "app_proto": "tls" } }
测试工程师

测试您的 SNS 通知功能

Task描述所需技能

通过 Network Firewall 发送流量。

  1. 发送或等待 HTTPS 流量通过网络防火墙。

  2. 检查当流量通过网络防火墙时您从 AWS 收到的 SNS 通知电子邮件。该电子邮件中包含出站流量的 SNI 详细信息。例如,如果访问的域名为 EMAIL-JSON https://aws.amazon.com且订阅协议为 EMAIL-JSON,则根据上述 Lambda 代码生成的电子邮件将包含以下内容:

{ "Type": "Notification", "MessageId": "<messageID>", "TopicArn": "arn:aws:sns:us-west-2:123456789:testSNSTopic", "Subject": "Server Name passed through the Network Firewall", "Message": "{\"ServerName\": \"Domain 'aws.amazon.com' accessed via AWS Network Firewall 'AWS-Network-Firewall-Multi-AZ-firewall\"}", "Timestamp": "2022-03-22T04:10:04.217Z", "SignatureVersion": "1", "Signature": "<Signature>", "SigningCertURL": "<SigningCertUrl>", "UnsubscribeURL": "<UnsubscribeURL>" }

然后,按照亚马逊 CloudWatch 文档中的说明查看 Amazon CloudWatch 中的 Network Firewall 警报日志。警报日志显示以下输出:

{ "firewall_name": "AWS-Network-Firewall-Multi-AZ-firewall", "availability_zone": "us-east-2b", "event_timestamp": "<event timestamp>", "event": { "timestamp": "2021-03-22T04:10:04.214222+0000", "flow_id": <flow ID>, "event_type": "alert", "src_ip": "10.1.3.76", "src_port": 22761, "dest_ip": "99.86.59.73", "dest_port": 443, "proto": "TCP", "alert": { "action": "allowed", "signature_id": 2, "rev": 0, "signature": "", "category": "", "severity": 3 }, "tls": { "subject": "CN=aws.amazon.com", "issuerdn": "C=US, O=Amazon, OU=Server CA 1B, CN=Amazon", "serial": "<serial number>", "fingerprint": "<fingerprint ID>", "sni": "aws.amazon.com", "version": "TLS 1.2", "notbefore": "2020-09-30T00:00:00", "notafter": "2021-09-23T12:00:00", "ja3": {}, "ja3s": {} }, "app_proto": "tls" } }
测试工程师
隐私网站条款Cookie 首选项
© 2025, Amazon Web Services, Inc. 或其附属公司。保留所有权利。