如何正确设置 AWS 入站规则以接受来自外部 REST API 调用的响应

How to properly set AWS inbound rules to accept response from external REST API call

我的用例
我有一个调用外部 API 的 AWS lambda 托管函数。就我而言,它是 Trello 的了不起的 well-defined API.

我的问题简而言之 - TL;DR 选项:随意跳转到下面的语句
我对 Trello 的外部 API 调用工作正常。现在它不起作用。我怀疑我更改了 AWS 中的网络权限,现在阻止了来自服务提供商的 returned 响应。详情请关注。

我的测试
我已经使用 Postman 测试了对 API 的调用,所以我知道我有一个格式正确的请求和来自服务提供商的有用的 returned 响应。业务逻辑没问题。作为参考,这是我正在使用的 API 调用。出于显而易见的原因,我混淆了我的密钥和令牌:

https://api.trello.com/1/cards?key=<myKey>&token=<myToken&idList=<a_real_list_here>&name=New+cards+are+cool

这应该会在我的 Trello 看板上放一张新卡片,并且在 POSTMAN 中(运行 在我的本地机器上)它成功地做到了。事实上,我在最近部署的 AWS lambda 函数中使用了它。这是电话。 (注意我用的是AWS推荐的urllib3 library

    http.request("POST", "https://api.trello.com/1/cards?key=<myKey>&token=<myToken>&idList=<a_real_list_here>&name="+card_name+"&desc="+card_description)

此外,我已经测试了同一请求的 CURL 版本的相同功能。它的构成是这样的:

    curl --location --request POST 'https://api.trello.com/1/cards?key=338d5b193d43e95712005fd2bcb4cd12&token=d0e3c4cd6281f43e4ec257ae5f05cd902230cbbca7e26b99664cd620f6479f7a&idList=600213811e171376755c7ed5&name=New+cards+are+cool'

我可以这样总结行为

+------------+---------------+----------------------+---------------+
|            | Local Machine | Previously on Lambda | Now on Lambda |
+------------+---------------+----------------------+---------------+
| cURL       |     GOOD      |         GOOD         |      N/A      |
+------------+---------------+----------------------+---------------+
| HTTP POST  |     GOOD      |         GOOD         |    443 Error  |
+------------+---------------+----------------------+---------------+

代码和错误
我没有得到可调试的响应。我得到一个 443,我认为这是错误代码,但即使这样也不清楚。这是代码片段:

#send to trello board 
try: 
    http.request("<post string from above>") 
except: 
    logger.debug("<post string from above>")

代码似乎永远不会进入 logger.debug() 调用。我在 AWS 中得到这个 日志:

[DEBUG] 2021-01-19T21:56:24.757Z 729be341-d2f7-4dc3-9491-42bc3c5d6ebf 
Starting new HTTPS connection (1): api.trello.com:443 

我假设“正在启动新的 HTTPS 连接...”日志条目来自 urllib3 库

问题总结
我从测试中知道我对外部服务的实际 API 调用是正确形成的。在某一时刻,它运行良好,但现在不是了。以前,为了让它正常工作,我必须 fiddle 具有 AWS 权限才能允许响应从服务提供商返回。我做到了,但我并不完全理解我所做的,我认为我只是很幸运。现在坏掉了,想好好的做一下。

我正在寻找的是了解如何设置 AWS 权限结构以启用来自服务提供商的 return 消息。 AWS 提供了有关如何使用 API 网关让其他人访问托管在 AWS 上的服务的综合指南,但对于如何打开其他服务提供商的响应权限的内容则更为粗略。

感谢 Hava 的工作人员,我为我的 AWS 基础设施准备了这张很棒的权限图: Security Structure 红色标记的两个网与本项目无关。第一个绿色检查点指向我的一台 EC2 机器,第二个指向相关的安全组。

我希望社区可以帮助我了解哪些关键权限元素(IAM 角色、安全组等)在起作用,以及我需要在相关的 AWS permissions/networking/security 结构中寻找什么.

由于 lambda 在您的 VPC 中,您需要进行额外的配置以允许它在 VPC 之外进行通信,因为 lambda 运行程序没有 public IP。因此,您需要一个互联网或 NAT 网关,如下所述:https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/

您将需要额外的托管服务或基础设施 运行 NAT 网关。

所以,最后的问题是 none 的网络问题。事实上,问题是 lambda 函数没有分配正确的执行角色。

特别是 Lambda 需要 AWSLambdaVPCAccessExecutionRole 才能调用所有基本的 VPC 内容来完成上面显示的所有花哨的网络基础设施体操。

这是一个 AWS 托管角色,此角色的默认 AWS 描述是 Allows Lambda functions to call AWS services on your behalf.

如果您遇到此问题,请按以下方法检查。

  1. 转到您的 lambda 函数 [Services][Lambda][Functions] 然后 点击你的函数
  2. 转到配置 选项卡。在window的右边, select 编辑.
  3. 如果你像我一样,你已经有一个角色,但它可能已经 错了。如果您更改角色,控制台将采取 而在您点击 保存 之前重置设置,这是 正常。
  4. 在页面的最底部,角色 selection 的正下方, 您会在 IAM 控制面板中看到该角色的 link。点击 检查您的 IAM 政策
  5. 确保 AWSLambdaVPCAccessExecutionRole 在 政策已启用。

红鲱鱼
以下是最初让我误入歧途的两件事:

  1. 我一直看到 443 返回,因为我认为这是来自 urllib3 服务调用的错误代码。它不是。我尝试了一些其他的东西,我最好的猜测是它是一个端口号,而不是一个错误。

  2. 无法访问肯定是网络配置错误,直到我尝试了一个实验向我证明它不是。这是建议的实验:

如果您关注 all of the guidance,您将拥有以下网络设置:

  • 一个 public 子网连接到互联网网关
  • 一个私有子网连接你的五脏六腑
  • 一个将您的私有子网指向 IGW 的 NAT 网关
  • 将您的私有子网连接到 NAT 网关的路由 table
  • 将您的 public 子网连接到 IGW
  • 的路由 table

然后,完成所有这些设置后,在您的私有子网中创建一个一次性 EC2 实例。当你设置它时,它不应该有一个 public IP。您可以通过尝试使用 EC2 页面上的 CONNECT 功能来仔细检查。应该不行。

如果您还没有,请在您的 public 子网中设置一个 EC2。您应该有一个 public IP。

现在通过 SSH 连接到您的 public EC2。进入后,从您的 public EC2 通过 SSH 连接到您的私有 EC2。如果您的所有基础设施都设置正确,您应该能够做到这一点。如果您登录到您的私有 EC2,您应该能够从该私有子网中的 EC2 运行 内部 ping public 网站。

您无法直接连接到您的私有 EC2 这一事实告诉您该子网是安全的。您可以从该私有 EC2 访问互联网这一事实表明 NAT 网关和路由 table 设置正确。

但是,如果您的执行角色不正确,这当然 none 很重要。

最后的想法
我绝对不是这方面的专家,但请专家在这里指正。我会在学习时对其进行编辑。对于这些概念的新手,我强烈建议您花时间用一张纸来绘制您的网络。当我有足够的可信度时,我会post我做的地图来帮助我思考所有这些。

保罗