为网关终端节点设置自定义域名
默认情况下,网关终端节点 AWS的格式<gateway-id>.gateway.bedrock-agentcore.<region>.amazonaws.com为托管域名。对于生产环境或为了创建更加用户友好的体验,您可能需要为网关终端节点使用自定义域名。本节将指导您使用亚马逊 CloudFront 作为反向代理来设置自定义域名。
先决条件
在开始之前,请确保您满足以下条件:
-
有效的网关终端节点
-
DNS 委托(如果您的 Route 53 域名需要可供公众访问)
-
AWS 已安装并配置 CDK(如果采用 CDK 方法)
-
创建和管理 CloudFront 分配、Route 53 托管区域和 ACM 证书的相应 IAM 权限
解决方案概述
此解决方案包含以下组件:
-
Route 53 托管区域:管理自定义域名的 DNS 记录
-
ACM 证书:为您的自定义 SSL/TLS 域提供加密
-
CloudFront 分发:充当反向代理,将来自自定义域的请求转发到网关终端节点
-
Route 53 A 记录:将您的自定义域名映射到 CloudFront 分配
以下步骤将指导您使用 AWS CDK 设置这些组件。
实现步骤
步骤 1:创建 Route 53 托管区域
首先,为您的自定义域创建一个 Route 53 托管区域:
import { RemovalPolicy } from 'aws-cdk-lib'; import { PublicHostedZone } from 'aws-cdk-lib/aws-route53'; const domainName = 'my.example.com'; const hostedZone = new PublicHostedZone(this, 'HostedZone', { zoneName: domainName, }); this.hostedZone.applyRemovalPolicy(RemovalPolicy.RETAIN);
注意
我们采用的移除政策是RETAIN为了防止在堆栈更新或删除期间意外删除托管区域。
步骤 2:创建 DNS-validated 证书
接下来,使用带有 DNS 验证功能的 Certifice Manager (ACM) 为您的自定义域创建 AWS 证书: SSL/TLS
import { RemovalPolicy } from 'aws-cdk-lib'; import { Certificate, CertificateValidation } from 'aws-cdk-lib/aws-certificatemanager'; const certificate = new Certificate(this, 'SSLCertificate', { domainName: domainName, // route53 hosted zone domain name from step 1 validation: CertificateValidation.fromDns(hostedZone), // route53 hosted zone from step 1 }); this.certificate.applyRemovalPolicy(RemovalPolicy.RETAIN);
DNS 验证会自动在您的 Route 53 托管区域中创建必要的验证记录。
步骤 3:创建分 CloudFront 配
创建 CloudFront 分配以充当网关终端节点的反向代理:
import { AllowedMethods, CachePolicy, Distribution, OriginProtocolPolicy, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront'; import { HttpOrigin } from 'aws-cdk-lib/aws-cloudfront-origins'; const bedrockAgentCoreGatewayHostName = '<mymcpserver>.gateway.bedrock-agentcore.<region>.amazonaws.com' const bedrockAgentCoreGatewayPath = '/mcp' // can also be left undefined, depending on your requirement const distribution = new Distribution(this, 'Distribution', { defaultBehavior: { origin: new HttpOrigin(bedrockAgentCoreGatewayHostName, { protocolPolicy: OriginProtocolPolicy.HTTPS_ONLY, originPath: bedrockAgentCoreGatewayPath, }), viewerProtocolPolicy: ViewerProtocolPolicy.HTTPS_ONLY, cachePolicy: CachePolicy.CACHING_DISABLED, // important since caching is enabled by default and hence is not suitable for a reverse proxy allowedMethods: AllowedMethods.ALLOW_ALL, }, domainNames: [domainName], // route53 hosted zone domain name from step 1 certificate: certificate, // ssl certificate for the route53 domain from step 2 });
重要
设置cachePolicy: CachePolicy.CACHING_DISABLED为确保 CloudFront 不会缓存来自网关终端节点的响应,这对于动态 API 交互非常重要。
<mymcpserver>替换为您的网关 ID <region> 和您的 AWS 区域(例如us-east-1)。
步骤 4:创建 Route 53 A 记录
创建 Route 53 一条将您的自定义域指向 CloudFront 分布的记录:
import { ARecord, RecordTarget } from 'aws-cdk-lib/aws-route53'; import { CloudFrontTarget } from 'aws-cdk-lib/aws-route53-targets'; const aRecord = new ARecord(this, 'AliasRecord', { zone: hostedZone, // route53 hosted zone from step 1 recordName: domainName, // route53 hosted zone domain name from step 1 target: RecordTarget.fromAlias(new CloudFrontTarget(distribution)), // cloudfront distribution from step 3 });
这将创建将您的自定义域名映射到 CloudFront 分配的别名记录。
步骤 5:部署您的基础架构
部署 CDK 堆栈来创建资源:
cdk deploy
部署过程可能需要一些时间,尤其是在证书验证和 CloudFront 分发创建方面。
测试您的自定义域名
部署基础设施后,请验证您的自定义域名配置是否正确:
验证 DNS 解析度
使用dig命令验证您的自定义域名是否已解析为 CloudFront 分发:
dig my.example.com
输出应显示您的域名解析为 CloudFront的 IP 地址。
验证 SSL 证书
curl用于验证 SSL 证书的配置是否正确:
curl -v https://my.example.com
输出应显示成功的 SSL 握手且没有证书错误。
配置 MCP 客户端
设置并验证自定义域名后,您可以将 MCP 客户端配置为使用它:
游标配置
对于 Cursor,请更新您的配置文件:
{ "mcpServers": { "my-mcp-server": { "url": "https://my.example.com" } } }
其他 MCP 客户
对于原生不支持可流式传输 HTTP 的 MCP 客户端:
{ "mcpServers": { "my-mcp-server": { "command": "/path/to/uvx", "args": [ "mcp-proxy", "--transport", "streamablehttp", "https://my.example.com" ] } } }
其他注意事项
- 所涉费用问题
-
CloudFront 用作反向代理会产生额外的数据传输和请求处理成本。查看定 CloudFront 价模型,了解您的特定用例的成本影响。
- 安全注意事项
-
考虑实施其他安全措施,例如:
-
保护您的终端节点免受常见 Web 漏洞攻击的 WAF 规则
-
Geo-restrictions 限制对特定地理区域的访问
-
自定义标头或请求签名以添加额外的身份验证层
-
- 监控和日志记录
-
启用 CloudFront 访问日志并配置 CloudWatch 警报,以监控自定义域设置的运行状况和性能。
- 证书续订
-
只要 DNS 记录保持不变,通过 DNS 验证颁发的 ACM 证书就会自动续订。确保不要删除验证记录。
- 带有自定义域的 OAuth 保护资源端点
-
默认情况下,
/.well-known/oauth-protected-resource终端节点返回的资源网址包含网关域而不是您的自定义域。这可能会导致 OAuth 客户端在使用自定义域名时无法进行身份验证。要解决此问题,您可以实现一个 Lambda @Edge 函数,该函数可拦截 OAuth 发现响应并生成带有正确自定义域 URL 的新响应。方法如下:
-
将 Lambda @Edge 与 ORIGIN_RESPONSE 事件类型配合使用:创建一个在源响应上触发的函数,以拦截 OAuth 保护的资源端点响应。
-
生成新响应:Lambda @Edge 无法读取源响应正文,因此,与其修改现有响应,不如使用自定义域生成全新的 JSON 响应。
-
与 CloudFront 行为关联:将 Lambda @Edge 函数配置为专门针对
/.well-known/oauth-protected-resource路径模式触发。实施此解决方案后,受 OAuth 保护的资源端点将返回正确的自定义域:
curl https://my-custom-domain.com/.well-known/oauth-protected-resource { "authorization_servers": ["https://my-org.okta.com/oauth2/default"], "resource": "https://my-custom-domain.com/mcp" }注意
虽然 Lambda @Edge 为这个问题提供了解决方案,但在没有内置支持的情况下为 AgentCore Gateway 实现自定义域需要额外的复杂性,这可能不是所有客户的最佳选择。在使用自定义域名对 OAuth 发现提供原生支持之前,可以考虑将此方法作为一种解决方法。
-
问题排查
- DNS 解析问题
-
如果您的自定义域名无法正确解析:
-
验证您的 Route 53 托管区域中是否正确配置了 A 记录
-
在域名注册商处检查您的域名服务器是否设置正确
-
为 DNS 传播留出时间(在某些情况下最长可达 48 小时)
-
- SSL 证书问题
-
如果您遇到 SSL 证书错误:
-
在 ACM 控制台中验证证书是否已颁发并处于活动状态
-
检查证书是否与您的 CloudFront 发行版关联正确
-
确保证书涵盖您正在使用的确切域名
-
- 网关连接问题
-
如果您的自定义域名未连接到您的网关:
-
验证 CloudFront 分配中的源域和路径是否正确
-
检查您的网关终端节点是否可以直接访问
-
查看 CloudFront 分发日志中是否存在任何错误
-
结论
为 Gateway 终端节点设置自定义域名可以增强应用程序的专业外观,并提供管理 API 终端节点的灵活性。按照本指南中概述的步骤,您可以使用 CloudFront 作为反向代理来创建安全可靠的自定义域配置。
有关网关特性和功能的更多信息,请参阅 Amazon Bedrock AgentCore Gateway:将工具和其他资源安全地连接到您的网关。