【问题标题】:How to write to a write-only SQS queue without an access key and secret key如何在没有访问密钥和密钥的情况下写入只写 SQS 队列
【发布时间】:2019-02-20 13:46:55
【问题描述】:

我有一个将消息从客户端写入 Amazon SQS 队列的网站。每个人都可以写入队列。我们有一个服务器端进程,它读取队列消息并对其进行处理。

队列配置了对每个人的写入权限,这是它的策略:

{
  "Version": "2012-10-17",
  "Id": "arn:aws:sqs:.../SQSDefaultPolicy",
  "Statement": [{
      "Sid": "Sid1537097246229",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:..."
  }]
}

但是,如果没有访问密钥和密钥,我们似乎无法写入队列。 AWS 开发工具包返回一个错误,指出尚未提供凭证。我们正在使用AWS SQS documentation 中描述的代码。

【问题讨论】:

    标签: javascript amazon-web-services amazon-sqs


    【解决方案1】:

    我不建议允许未经身份验证的访问 SQS 队列,但如果您必须这样做,那么您应该能够通过 JavaScript SDK 发出未经身份验证的请求,如下所示:

    const AWS = require('aws-sdk');
    
    AWS.config.update({ region: 'us-east-1' });
    
    const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });
    
    const params = {
      DelaySeconds: 10,
      MessageAttributes: {
        Title: {
          DataType: 'String',
          StringValue: 'The Whistler',
        },
        Author: {
          DataType: 'String',
          StringValue: 'John Grisham',
        },
      },
      MessageBody: 'NY Times fiction bestseller 12/11/2016.',
      QueueUrl: 'QUEUE_URL_HERE',
    };
    
    sqs.makeUnauthenticatedRequest('sendMessage', params, (err, data) => {
      if (err) {
        console.log('Error', err);
      } else {
        console.log('Success', data.MessageId);
      }
    });
    

    【讨论】:

    • 谢谢。我实际上不明白为什么未经身份验证的请求在这里是个问题。在一个甚至没有用户注册的系统中,每个人都可以写队列。无论我使用什么其他机制,基本上都可以让每个人都向队列写入消息。
    • 风险可能并不高,但开放的 SQS 队列显然会被任何发现该 URL 的人滥用。这可能会导致您的应用出现问题(读取意外的消息内容)并花费您的钱(SQS 不是免费服务)。
    • 确实如此,但如果我限制对队列的访问,并让每个人都下载写入队列的 JavaScript 代码,则存在完全相同的风险。
    • 正确的硬编码凭据客户端同样存在问题。理想情况下,所有客户端都会进行身份验证(例如通过 Cognito),但我知道在某些情况下这可能看起来很麻烦。无论如何,我只是想强调潜在的风险,以便读者充分了解情况。
    【解决方案2】:

    "Principal": "*" 的默认策略仍要求发件人提供一些 AWS 委托人。如您提供的文件的先决条件所述:

    使用您的用户凭据创建共享配置文件。有关提供共享凭据文件的更多信息,请参阅从共享凭据文件加载 Node.js 中的凭据。

    您是否考虑过使用 API Gateway 作为 SQS 队列的代理?在https://dzone.com/articles/creating-aws-service-proxy-for-amazon-sqs 中定义了这样做的一个示例。我建议为 SQS 设置代理并使用 POST 端点,例如

    POST::/myQueueName/messages
    

    这将改变您的用户与队列交互的方式,但它允许您将队列锁定为只有服务用户才能读取和写入,这遵循最低权限策略。然后,您的 API Gateway 端点可以根据您的偏好使用 API 密钥进行保护,对互联网完全开放,甚至使用 IAM 角色进行保护。

    【讨论】:

    • 好建议,API 网关...感觉比匿名队列访问好多了。另一个(轻量级)示例:stackoverflow.com/a/49566676/1695906
    • 为什么?为什么匿名访问 API 网关比直接匿名访问 SQS 更好?在这两种情况下,每个人都可以写入队列,在这两种情况下,如果我决定关闭公共访问,我只需要更改网关或队列上的权限。
    • 根据您描述的场景,SQS 基本上是您的应用程序的后端数据库。在传统观点中,将这些东西与您认识的用户和您不认识的用户直接交互屏蔽起来感觉更安全。无论是否匿名,APIG 都允许您在有人尝试发出太多请求时定义每个 IP 的限制限制,这与 SQS 不同。有了网关,您可以灵活地切换到后端的不同队列,或者如果您需要在入口端进行更多处理,然后再存储到队列中,则将其替换为 lambda 函数。
    • 每个 IP 的节流和限制!这是使用它的好理由!在这种特殊情况下,不需要切换队列甚至用其他东西替换队列的灵活性。
    猜你喜欢
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 2022-08-05
    • 2014-02-20
    • 2012-03-05
    • 2019-11-16
    相关资源
    最近更新 更多