View a markdown version of this page

为网关终端节点设置自定义域名 - 亚马逊基岩 AgentCore

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

为网关终端节点设置自定义域名

默认情况下,网关终端节点以以下格式<gateway-id>.gateway.bedrock-agentcore.<region>.amazonaws.com提供 AWS-managed 域名。对于生产环境或创建更加用户友好的体验,您可能需要为网关终端节点使用自定义域名。本节指导您使用亚马逊 CloudFront 作为反向代理设置自定义域名。

先决条件

在开始之前,请确保您满足以下条件:

  • 有效的网关终端节点

  • DNS 委托(如果您的 Route 53 域需要可公开访问)

  • AWS 已安装并配置 CDK(如果遵循 CDK 方法)

  • 创建和管理 CloudFront 分配、Route 53 托管区域和 ACM 证书的适当 IAM 权限

解决方案概述

此解决方案包含以下组件:

  • Route 53 托管区域:管理您的自定义域的 DNS 记录

  • ACM 证书:为您的自定义域提供 SSL/TLS 加密

  • CloudFront 分发:充当反向代理,将请求从您的自定义域转发到网关终端节点

  • Route 53 A Record:将您的自定义域映射到 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 验证的 SSL/TLS AWS 证书管理器 (ACM) 为您的自定义域创建证书:

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 A 记录,将您的自定义域指向 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终端节点返回包含网关域的资源 URL,而不是您的自定义域。这可能会导致 OAuth 客户端在使用自定义域时身份验证失败。

要解决此问题,您可以实现 Lambda @Edge 函数,该函数会拦截 OAuth 发现响应并使用正确的自定义域 URL 生成新的响应。以下是方法:

  • 使用带有 ORIGIN_RESPONSE 事件类型的 Lambda @Edge:创建一个触发源响应的函数,以拦截受保护的 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:将工具和其他资源安全地连接到您的网关。