【问题标题】:How to properly set AWS inbound rules to accept response from external REST API call如何正确设置 AWS 入站规则以接受来自外部 REST API 调用的响应
【发布时间】:2021-04-24 05:33:49
【问题描述】:

我的用例
我有一个调用外部 API 的 AWS lambda 托管函数。就我而言,这是 Trello 的绝妙之处,well-defined API

简而言之我的问题 - TL;DR 选项:随意跳到下面的陈述
我对 Trello 的外部 API 调用正常工作。现在它不工作了。我怀疑我更改了 AWS 中的网络权限,现在阻止了服务提供商返回的响应。详细信息如下。

我的测试
我已经使用Postman 测试了我对 API 的调用,所以我知道我有一个格式正确的请求和来自服务提供商的有用的返回响应。业务逻辑没问题。作为参考,这是我正在使用的 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,我认为这是错误代码,但即使这样也不清楚。这是代码sn-p:

#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 调用是正确形成的。在某一时刻,它运行良好,但现在却不行。以前,为了让它正常工作,我不得不摆弄 AWS 权限以允许服务提供商返回响应。我做到了,但我并不完全理解我做了什么,我认为我只是幸运。现在它坏了,我想以一种深思熟虑的方式来做。

我正在寻找的是了解如何设置 AWS 权限结构以启用来自服务提供商的返回消息。 AWS 提供了关于如何使用 API Gateway 让其他人访问 AWS 上托管的服务的综合指南,但它更粗略地介绍了如何为其他服务提供商的响应开放权限。

感谢Hava 的人们,我有一张很棒的 AWS 基础设施权限图表: Security Structure红色标注的两个网与本项目无关。第一个绿色检查点指向我的一台 EC2 机器,第二个指向相关安全组。

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

【问题讨论】:

  • 原始错误信息是什么?
  • 我没有得到可调试的响应。我得到一个 443,我认为这是错误代码,但即使这样也不清楚。这是代码 sn-p: #send to trello board try: http.request("
  • 哇...没有意识到我无法在响应中添加任何文本格式。很抱歉造成混乱。
  • 您是否将 lambda 放入您的 VPC 中?
  • 是的,但感谢您的检查。我能够在亚马逊网站上和使用 Hava 基础设施图表工具验证这一点。

标签: amazon-web-services rest aws-lambda amazon-iam aws-security-group


【解决方案1】:

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

您需要额外的托管服务或运行 NAT 网关的基础架构。

【讨论】:

  • 确实如此。让我感到困惑的一个领域是 NAT 的作用。它是一种单向阀,允许从子网流出到 IGW。什么是允许回流的等价物,可能来自一组有限的响应服务。
  • 建立了从您的私有实例到网关的连接,它与 Internet 建立另一个连接,并将所有内容通过原始连接中继回私有实例。它不处理从 Internet 到您的私有实例的连接。怎么可能?没有办法从 Internet 上的任何地方寻址您的私有网络中的实例,这有点像是私有网络的整体理念。
  • 对,我 100% 同意你的理论。我仍然收到 403 错误,并且 lambda 超时,就好像响应没有返回到 lambda 函数一样。仍在故障排除。目前,我将 lambda 放在公共子网中(当然不打算将它留在那里),但我仍然收到错误。
【解决方案2】:

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

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

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

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

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

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

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

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

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

  • 一个连接到互联网网关的公共子网
  • 一个私有子网连接你所有的内脏
  • 一个 NAT 网关,将您的私有子网指向 IGW
  • 将您的私有子网连接到 NAT 网关的路由表
  • 将公有子网连接到 IGW 的路由表

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

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

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

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

当然,如果你的执行角色不正确,这些都不重要。

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

保罗

【讨论】:

    猜你喜欢
    • 2014-06-03
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多