本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
访问 AWS Transform 来自 VPC 的 Web 应用程序
当您使用 AWS PrivateLink 从 VPC 私下访问 AWS Transform API 时,Web 应用程序需要额外的网络配置。它通过提供静态内容(HTML JavaScript、、CSS) CloudFront,这需要互联网连接。来自 Web 应用程序的 API 调用将通过您的 VPC 终端节点进行并保持完全私密状态。
本指南向您介绍如何配置来自您的 VPC 的受控互联网出口,这样 Web 应用程序就可以加载,同时将 VPC 锁定到所需的域。
工作原理
AWS Transform Web 应用程序使用两条网络路径:
-
API 调用 — 当您与 Web 应用程序交互(启动作业、查看工作区等)时,浏览器会向发送 API 请求。
api.transform.启用region.on.awscom.amazonaws.VPC 终端节点和私有 DNS 后,这些请求将解析到您的 VPC 中的私有 IP 地址,并且永远不会离开 AWS 网络。region.api.transform -
静态内容 — CloudFront 通过提供 Web 应用程序的 HTML 和 CSS 文件
。 JavaScript加载这些文件需要互联网连接,因为 CloudFront 内容交付只能通过公共互联网进行。tenant-id.transform.region.on.aws -
身份验证 — AWS IAM Identity Center 登录流程使用
,这也需要互联网连接。region.signin.aws
要在维护安全的同时启用 Web 应用程序,您可以使用带有基于域的筛选的 Network Fire AWS wall 创建受控的出口路径。这允许您的 VPC 仅访问 Web 应用程序所需的特定域,同时阻止所有其他互联网流量。
架构
下图显示了 Web 应用程序流量的网络路径:
EC2 Instance / Workspace (Private Subnet) | | Route: 0.0.0.0/0 → Network Firewall Endpoint v AWS Network Firewall (Firewall Subnet) | Allows: *.cloudfront.net, *.transform.<region>.on.aws, | <region>.signin.aws, SSO domains, S3 presigned URLs | Blocks: everything else (TLS SNI inspection) | | Route: 0.0.0.0/0 → NAT Gateway v NAT Gateway (Public Subnet) | | Route: 0.0.0.0/0 → Internet Gateway v Internet Gateway → CloudFront Edge Locations
重要
Network Firewall 必须看到流量的两个方向(对称路由)才能执行 TLS SNI 检查。您必须在 NAT Gateway 子网中配置一条返回路由,以便通过防火墙将发往私有子网的流量发送回去。否则,基于域的过滤规则将无法运行。
先决条件
在开始之前,请确保您满足以下条件:
-
有权创建 VPC 资源、Network Firewall 和 NAT 网关的 AWS 账户。
-
带有私有子网的 VPC,您的实例或工作负载可以在其中运行。
-
连接到 VPC 的互联网网关(或创建网关的权限)。
-
启用了 AWS Transform 私有 DNS 的
com.amazonaws.VPC 终端节点。这是 Web 应用程序浏览器客户端使用的端点。有关创建端点的说明,请参阅AWS Transform 和接口端点 (AWS PrivateLink)。region.api.transform
配置 VPC 终端节点策略
如果您的 com.amazonaws. VPC 终端节点具有自定义终端节点策略,则必须添加允许 AWS Transform 操作的声明。否则,Web 应用程序将无法通过端点进行 API 调用。region.api.transform
将以下声明添加到您的 VPC 终端节点策略中。AWS_TRANSFORM_PROFILE_ARN替换为您的 AWS Transform 服务配置文件 ARN,您可以在 AWS Transform 控制台的 “设置” 页面上找到该配置文件。
{ "Statement": [ { "Sid": "AllowAWSTransform", "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": "*", "Condition": { "StringEquals": { "aws:PrincipalArn": [ "AWS_TRANSFORM_PROFILE_ARN" ] } } } ] }
注意
如果您的 VPC 终端节点使用默认策略(完全访问权限),则无需进行任何更改,您可以跳过此步骤。
设置受控的互联网出口
完成以下步骤,为 AWS Transform Web 应用程序配置 Network Firewall 使用基于域的筛选。
步骤 1:创建防火墙子网
创建一个专用 Network Firewall 端点的小型 /28 子网。该子网必须与您的私有子网位于同一个可用区。
aws ec2 create-subnet \ --vpc-idyour-vpc-id\ --cidr-blockfirewall-subnet-cidr\ --availability-zoneyour-az\ --regionregion
步骤 2:为 NAT 网关创建公有子网
aws ec2 create-subnet \ --vpc-idyour-vpc-id\ --cidr-blockpublic-subnet-cidr\ --availability-zoneyour-az\ --regionregion
步骤 3:配置公有子网路由表
为将互联网流量路由到互联网网关的公有子网创建路由表。
# Create route table PUB_RTB=$(aws ec2 create-route-table \ --vpc-idyour-vpc-id\ --regionregion\ --query 'RouteTable.RouteTableId' --output text) # Add default route to internet gateway aws ec2 create-route \ --route-table-id $PUB_RTB \ --destination-cidr-block 0.0.0.0/0 \ --gateway-idyour-igw-id\ --regionregion# Associate with public subnet aws ec2 associate-route-table \ --route-table-id $PUB_RTB \ --subnet-idpublic-subnet-id\ --regionregion
步骤 4:创建 NAT 网关
# Allocate an Elastic IP EIP=$(aws ec2 allocate-address --domain vpc \ --regionregion--query 'AllocationId' --output text) # Create NAT Gateway in the public subnet NAT_ID=$(aws ec2 create-nat-gateway \ --subnet-idpublic-subnet-id\ --allocation-id $EIP \ --regionregion\ --query 'NatGateway.NatGatewayId' --output text) # Wait for NAT Gateway to become available (~2 minutes) aws ec2 wait nat-gateway-available \ --nat-gateway-ids $NAT_ID --regionregion
步骤 5:创建 Network Firewall 规则组
创建一个状态规则组,该组仅允许流向 AWS Transform Web 应用程序所需的域的流量。
aws network-firewall create-rule-group \ --rule-group-name transform-webapp-domains \ --type STATEFUL \ --capacity 100 \ --rule-group '{ "StatefulRuleOptions": { "RuleOrder": "STRICT_ORDER" }, "RulesSource": { "RulesSourceList": { "Targets": [ ".cloudfront.net", ".transform.region.on.aws", "region.signin.aws", ".s3.region.amazonaws.com", "oidc.region.amazonaws.com", "portal.sso.region.amazonaws.com", "assets.sso-portal.region.amazonaws.com", "directory-id.awsapps.com" ], "TargetTypes": ["TLS_SNI", "HTTP_HOST"], "GeneratedRulesType": "ALLOWLIST" } } }' \ --regionregion
region替换为安装您的 AWS Transform
配置文件的地 AWS 区(例如,us-east-1)。directory-id替换为您的 IAM 身份中心目录 ID(例如,d-1234567890)。您可以在 IAM 身份中心控制台中找到您的目录 ID。
下表说明了允许的域。
| 域: | 用途 |
|---|---|
.cloudfront.net |
CloudFront CDN — 提供 Web 应用程序静态资产(JavaScript、CSS、图像) |
.transform. |
Web 应用程序租户 URL — 浏览器通过以下方式从该域加载初始页面 CloudFront |
|
SSO 登录重定向页面 |
.s3. |
S3 预签名 URL-工件上传和下载 |
oidc. |
用于 SSO 身份验证的 OIDC 令牌交换 |
portal.sso. |
SSO 门户登录页面 |
assets.sso-portal. |
SSO 门户网站静态资产 (CSS、 JavaScript) |
|
适用于您的组织的 IAM 身份中心门户 |
注意
.cloudfront.net通配符允许任何 CloudFront分发的流量,而不仅仅是 AWS Transform Web 应用程序的流量。不可能使用更窄的域过滤器,因为 CloudFront 边缘 IP 是跨分布共享的,而且 TLS SNI 检查无法区分同一域下的各个分布。
注意
API 调用api.transform.可以通过 AWS PrivateLink ,不需要互联网出口。它们不受防火墙的影响。region.on.aws
步骤 6:创建防火墙策略
策略必须使用STRICT_ORDER规则评估drop_established作为默认操作。这样可以确保丢弃所有与许可名单不匹配的流量。
# Get the rule group ARN RG_ARN=$(aws network-firewall describe-rule-group \ --rule-group-name transform-webapp-domains \ --type STATEFUL --regionregion\ --query 'RuleGroupResponse.RuleGroupArn' --output text) # Create the firewall policy aws network-firewall create-firewall-policy \ --firewall-policy-name transform-webapp-policy \ --firewall-policy "{ \"StatelessDefaultActions\": [\"aws:forward_to_sfe\"], \"StatelessFragmentDefaultActions\": [\"aws:forward_to_sfe\"], \"StatefulRuleGroupReferences\": [ { \"ResourceArn\": \"$RG_ARN\", \"Priority\": 1 } ], \"StatefulEngineOptions\": { \"RuleOrder\": \"STRICT_ORDER\" }, \"StatefulDefaultActions\": [\"aws:drop_established\", \"aws:alert_established\"] }" \ --regionregion
步骤 7:创建 Network Firewall
# Get the policy ARN FW_POLICY_ARN=$(aws network-firewall describe-firewall-policy \ --firewall-policy-name transform-webapp-policy \ --regionregion\ --query 'FirewallPolicyResponse.FirewallPolicyArn' --output text) # Create the firewall aws network-firewall create-firewall \ --firewall-name transform-webapp-firewall \ --firewall-policy-arn $FW_POLICY_ARN \ --vpc-idyour-vpc-id\ --subnet-mappings SubnetId=firewall-subnet-id\ --regionregion# Wait for the firewall to become READY (3-5 minutes) while true; do STATUS=$(aws network-firewall describe-firewall \ --firewall-name transform-webapp-firewall \ --regionregion\ --query 'FirewallStatus.Status' --output text) echo "Status: $STATUS" if [ "$STATUS" = "READY" ]; then break; fi sleep 15 done
步骤 8:获取防火墙端点 ID
FW_ENDPOINT=$(aws network-firewall describe-firewall \ --firewall-name transform-webapp-firewall \ --regionregion\ --query "FirewallStatus.SyncStates.\"your-az\".Attachment.EndpointId" \ --output text) echo "Firewall endpoint: $FW_ENDPOINT"
步骤 9:配置防火墙子网路由表
将互联网流量从防火墙子网路由到 NAT 网关。
FW_RTB=$(aws ec2 create-route-table \ --vpc-idyour-vpc-id\ --regionregion\ --query 'RouteTable.RouteTableId' --output text) aws ec2 create-route \ --route-table-id $FW_RTB \ --destination-cidr-block 0.0.0.0/0 \ --nat-gateway-id $NAT_ID \ --regionregionaws ec2 associate-route-table \ --route-table-id $FW_RTB \ --subnet-idfirewall-subnet-id\ --regionregion
步骤 10:更新私有子网路由表
将来自私有子网的所有互联网流量路由到防火墙。
aws ec2 create-route \ --route-table-idprivate-subnet-route-table-id\ --destination-cidr-block 0.0.0.0/0 \ --vpc-endpoint-id $FW_ENDPOINT \ --regionregion
如果已存在默认路由,请使用replace-route而不是create-route。
步骤 11:添加对称回程路由(必填)
重要
这一步至关重要。Network Firewall 使用 TLS SNI 检查,并且必须看到 TCP 连接的两个方向。在 NAT Gateway 子网的路由表中添加一条路由,该路由将发往私有子网的返回流量通过防火墙发送回去。
aws ec2 create-route \ --route-table-id $PUB_RTB \ --destination-cidr-blockprivate-subnet-cidr\ --vpc-endpoint-id $FW_ENDPOINT \ --regionregion
private-subnet-cidr替换为私有子网的 CIDR 块(例如10.0.144.0/20)。
如果没有对称路由,防火墙只能看到一个方向的流量。TLS 检查引擎无法从 TLS 握手中提取服务器名称指示 (SNI),并且所有基于域的规则都将静默失败。
步骤 12:删除 IPv6 默认路由(如果存在)
如果私有子网路由表有直接指向互联网网关的 IPv6 默认路由 (::/0),它将绕过防火墙 IPv6-capable 前往目的地。将其删除:
aws ec2 delete-route \ --route-table-idprivate-subnet-route-table-id\ --destination-ipv6-cidr-block ::/0 \ --regionregion
验证
在私有子网中的实例中,验证配置:
# Should SUCCEED - web application content via CloudFront (allowed) curl -vL --connect-timeout 15 \ 'https://tenant-id.transform.region.on.aws' # Should SUCCEED - API via PrivateLink (does not use firewall) curl -v --connect-timeout 15 \ 'https://api.transform.region.on.aws/' # Should FAIL - non-allowlisted domain (blocked by firewall) curl -v --connect-timeout 15 'https://www.example.com' # Expected: TLS connection error (firewall drops after SNI inspection)
问题排查
- 你的防火墙阻止了对 api.transform 的 API 调用
-
该域
api.transform.应通过 VPC 终端节点解析为私有 IP 地址,并且不应到达您的互联网防火墙。region.on.aws-
确认您已创建
com.amazonaws.终端节点。region.api.transform -
验证终端节点上是否启用了私有 DNS:
aws ec2 describe-vpc-endpoints \ --filters "Name=service-name,Values=com.amazonaws.region.api.transform" \ --query 'VpcEndpoints[*].[State,PrivateDnsEnabled]' \ --output table预期输出:
available | True
-
- Web 应用程序无法加载(连接超时)
-
-
验证私有子网路由表中是否有指向防火墙端点的
0.0.0.0/0路由。 -
验证防火墙子网路由表中是否有指向 NAT 网关的
0.0.0.0/0路由。 -
验证 NAT 网关是否处于
available状态。
-
- Non-allowlisted 域名未被屏蔽
-
-
检查是否有指向互联网网关的 IPv6
::/0路由。这会绕过防火墙。将其删除(步骤 12)。 -
验证是否配置了对称路由。NAT 网关子网路由表必须有穿过防火墙的私有子网 CIDR 的返回路由(步骤 11)。
-
验证防火墙策略是否
STRICT_ORDER使用drop_established和alert_established作为默认操作。
-
成本注意事项
| 资源 | 大概成本 |
|---|---|
| Network Firewall | ~0 美元。 395/hr 每个可用区 (~$288/month) |
| NAT 网关 | ~0 美元。 045/hr (~$33/month) + 数据处理费 |
| 弹性 IP(公有 IPv4) | ~0 美元。 005/hr (大约 3 美元。 60/month) |
| Network Firewall 数据处理 | 0 美元。 065/GB |
| NAT 网关数据处理 | 0 美元。 045/GB |
单个可用区部署325/month 的估计基本成本约为 $。对于生产部署,请在存在私有子网的每个可用区中部署防火墙、NAT 网关和关联子网。
资源清理
要删除本指南创建的所有资源,请按相反顺序运行以下命令。将占位符替换为部署中的资源 ID。您可以在 AWS 管理控制台中找到这些值,也可以使用设置步骤中的describe命令来找到。
# Remove return route from NAT Gateway subnet aws ec2 delete-route --route-table-idpub-rtb-id\ --destination-cidr-blockprivate-subnet-cidr\ --regionregion# Remove route from private subnet aws ec2 delete-route \ --route-table-idprivate-subnet-route-table-id\ --destination-cidr-block 0.0.0.0/0 --regionregion# Delete Network Firewall (takes ~5 minutes) aws network-firewall delete-firewall \ --firewall-name transform-webapp-firewall \ --regionregion# Delete firewall policy and rule group aws network-firewall delete-firewall-policy \ --firewall-policy-name transform-webapp-policy \ --regionregionaws network-firewall delete-rule-group \ --rule-group-name transform-webapp-domains \ --type STATEFUL --regionregion# Delete NAT Gateway (wait ~5 minutes for full deletion) aws ec2 delete-nat-gateway --nat-gateway-idnat-gateway-id\ --regionregion# Release Elastic IP aws ec2 release-address --allocation-ideip-allocation-id\ --regionregion# Delete subnets aws ec2 delete-subnet --subnet-idfirewall-subnet-id\ --regionregionaws ec2 delete-subnet --subnet-idpublic-subnet-id\ --regionregion