You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS IoT Topic订阅失败:特定IAM策略不生效问题咨询

问题:AWS IoT订阅失败的IAM策略排查

我使用Python的Paho MQTT客户端订阅AWS IoT Topic,所用脚本如下:

import paho.mqtt.client as mqtt
import ssl

MQTT_BROKER = '<endpoint>'  # Public broker for testing
MQTT_TOPIC = 'dcw813/livetracking'  # Topic to subscribe to
MQTT_PORT = 8883  # Secure port for MQTT
CLIENT_ID = "webapp"  # Unique client ID


# MQTT settings
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, CLIENT_ID)
mqttc.tls_set(ca_certs="AmazonRootCA1.pem",
               certfile="certificates/webapp/device-cert.pem.crt",
               keyfile="certificates/webapp/private.pem.key",
               tls_version=ssl.PROTOCOL_TLSv1_2)

# Callback when a message is received
def on_message(client, userdata, message):
    print(f"Received message: {message.payload.decode()} on topic: {message.topic}")


mqttc.on_message = on_message

mqttc.connect(MQTT_BROKER, MQTT_PORT)

# Subscribe to the topic with QoS level 1
mqttc.subscribe(MQTT_TOPIC, qos=1)

print(f"Subscribed to {MQTT_TOPIC}. Waiting for messages...")

# Loop forever to process incoming messages
mqttc.loop_forever()

当我使用以下IAM策略时,无法成功订阅Topic:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/+/livetracking",
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/+/attendance"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/+/livetracking",
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/+/attendance"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:<REGION>:<ACCOUNT>:client/${iot:ClientId}"
    }
  ]
}

但将策略修改为以下内容后,订阅即可正常工作,我无法理解问题所在:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:<REGION>:<ACCOUNT>:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": "arn:aws:iot:<REGION>:<ACCOUNT>:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:<REGION>:<ACCOUNT>:client/${iot:ClientId}"
    }
  ]
}

我还尝试了以下调试策略,但仍然无法成功订阅:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect",
        "iot:Publish",
        "iot:Subscribe",
        "iot:Receive",
        "iot:GetShadow",
        "iot:UpdateShadow",
        "iot:DeleteShadow",
        "iot:CreateKeysAndCertificate",
        "iot:CreateKeysAndCertificate",
        "iot:DescribeEndpoint",
        "iot:ListThings"
      ],
      "Resource": [
        "arn:aws:iot:<REGION>:<ACCOUNT>:client/*",
        "arn:aws:iot:<REGION>:<ACCOUNT>:thing/*",
        "arn:aws:iot:<REGION>:<ACCOUNT>:policy/*",
        "arn:aws:iot:<REGION>:<ACCOUNT>:cert/*",
        "arn:aws:iot:<REGION>:<ACCOUNT>:rule/*",
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/*",
        "arn:aws:iot:<REGION>:<ACCOUNT>:thing/*/shadow",
        "arn:aws:iot:<REGION>:<ACCOUNT>:job/*"
      ]
    }
  ]
}

问题原因与解决方案

核心问题在于AWS IoT的iot:Subscribe动作对应的资源是topicfilter类型的ARN,而非topic类型:

  1. 当客户端发起订阅请求时,AWS会验证订阅过滤器对应的ARN,格式为arn:aws:iot:<REGION>:<ACCOUNT>:topicfilter/[你的订阅路径]。比如你订阅的dcw813/livetracking,对应的权限校验资源是arn:aws:iot:<REGION>:<ACCOUNT>:topicfilter/dcw813/livetracking。
  2. 你最初的策略中,iot:Subscribe的资源用的是topic/+/livetracking,这匹配的是消息发布时的实际Topic资源(对应iot:Receive动作),但不匹配订阅时的topicfilter资源,因此权限校验失败,导致订阅被拒绝。
  3. 第二个策略用:*通配符覆盖了所有资源类型,自然包含了topicfilter,所以能通过权限校验。
  4. 第三个调试策略的资源列表里只有topic/*,同样没有包含topicfilter类型的资源,因此还是无法通过iot:Subscribe的权限校验。

修正后的正确策略

将iot:Subscribe的资源改为topicfilter类型的ARN即可:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:<REGION>:<ACCOUNT>:topicfilter/+/livetracking",
        "arn:aws:iot:<REGION>:<ACCOUNT>:topicfilter/+/attendance"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/+/livetracking",
        "arn:aws:iot:<REGION>:<ACCOUNT>:topic/+/attendance"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:<REGION>:<ACCOUNT>:client/${iot:ClientId}"
    }
  ]
}

这样iot:Subscribe会匹配订阅过滤器的ARN,iot:Receive匹配实际接收消息的Topic ARN,既能满足权限最小化要求,又能正常完成订阅和消息接收。


内容的提问来源于stack exchange,提问作者Hammad Majeed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:07:03