Authoriztion failure when publishing to IoT Core MQTT topic

0

Hello,

I'm currently running into some trouble setting up an IoT Core MQTT broker. I am able to connect to my broker using my terminal and mosquitto, but when I try to publish a message to any topic, the mosquitto client disconnects and reconnects without being able to publish.

I have validated this connect/disconnect behaviour through the $aws/events/presence/# topic and the mosquitto client in debug mode for which I can provide a sample output :

Client william_terminal sending CONNECT
Client william_terminal received CONNACK (0)
HELLO
Client william_terminal sending PUBLISH (d0, q0, r0, m1, 'test', ... (5 bytes))
Client william_terminal sending CONNECT
Client william_terminal received CONNACK (0)

Using the AWSIotLogs set at debug level, I was able to find out that this behaviour is caused by an authorization problem happening at publish time. Here are consecutively sampled logs for the stream :

{
    "timestamp": "2022-09-29 15:16:55.406",
    "logLevel": "INFO",
    "traceId": "5697ba84-38f7-eefc-08e9-b6dd00096727",
    "accountId": "673559919736",
    "status": "Success",
    "eventType": "Connect",
    "protocol": "MQTT",
    "clientId": "$GEN/af403525-5e3b-4f81-9888-a31f16e300f0",
    "principalId": "49964471e92f354742f5394e648c97d9ac3aa940081cccf0962918bf97fcdf09",
    "sourceIp": "10.240.100.18",
    "sourcePort": 46898
}
{
    "timestamp": "2022-09-29 15:16:59.554",
    "logLevel": "ERROR",
    "traceId": "067b15e5-9bcb-5c6d-2061-9bbefbccb3d0",
    "accountId": "673559919736",
    "status": "Failure",
    "eventType": "Publish-In",
    "protocol": "MQTT",
    "topicName": "sim/2",
    "clientId": "$GEN/af403525-5e3b-4f81-9888-a31f16e300f0",
    "principalId": "49964471e92f354742f5394e648c97d9ac3aa940081cccf0962918bf97fcdf09",
    "sourceIp": "10.240.100.18",
    "sourcePort": 46898,
    "reason": "AUTHORIZATION_FAILURE",
    "details": "Authorization Failure"
}

The certificates I use to authenticate to my account have the following policy attached :

{
  "Statement": [
    {
      "Action": [
        "iot:Connect"
      ],
      "Condition": {
        "Bool": {
          "iot:Connection.Thing.IsAttached": [
            "true"
          ]
        }
      },
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Action": [
        "iot:Publish"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Action": [
        "iot:Subscribe"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Action": [
        "iot:Receive"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ],
  "Version": "2012-10-17"
}

The only restrictive part of this permissions being set on the connection action, I don't understand how it is possible to have a publication authorization failure.

I will deeply appreciate any help on this topic. Cheers, William Didier

3개 답변
2
수락된 답변

In AWS IoT, IoT policies are attached to the device certificate and optionally can be inherited from IoT policies attached to the Thing Group. To validate the effective applied IoT policy , best is to work backwards from the device certificate:

Specify the device certificate file name to test, confirm the AWS region and AWS Account

export DEVICE_CRT=dd001.crt
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
export AWS_REGION=eu-west-1

Compute the sha256 fingerprint using the device certificate file name

export CERTIFICATE_ID=$(openssl x509 -noout -fingerprint -sha256 -inform pem -in $DEVICE_CRT | cut -c 20- | tr -d : | tr A-F a-f)
export PRINCIPAL_ID=arn:aws:iot:${AWS_REGION}:${ACCOUNT_ID}:cert/${CERTIFICATE_ID}

Check if the certificate is registered in AWS IoT

aws iot describe-certificate --certificate-id $CERTIFICATE_ID

Find the Thing attached to this certificate in AWS IoT. The command below takes the first Thing attached to the certificate, if you have more than one Thing attached to your certificate you need to adapt the command below.

export THING_NAME=$(aws iot list-principal-things --principal $PRINCIPAL_ID --query 'things[0]' --output text)

Retrieve the effective IoT policy for this Thing, so the IoT policies attached to the certificate and the inherited policies from Thing Groups.

aws iot get-effective-policies --thing-name $THING_NAME --principal $PRINCIPAL_ID 

{
  "effectivePolicies": [
    {
      "policyName": "E81FC...",
      "policyArn": "arn:aws:iot:eu-west-1:299807768844:policy/E81FCE....",
      "policyDocument": "{ \"Version\": \"2012-10-17\", \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:*\"], \"Resource\": [\"*\"] }] }"
    }
  ]
}

Verify that you don't have any policies inherited from Thing Groups that deny publishing.

profile pictureAWS
전문가
Jan_B
답변함 2년 전
profile pictureAWS
전문가
Greg_B
검토됨 2년 전
0

Hello Jan,

Thank you so much for your answer. Indeed, it appears that the policy I gave you did not correspond to the effectivePolicies policy document I retrieved using your method. I can indeed publish to the topics indicated by the policies attached to my certificate.

답변함 2년 전
0

If you don't mind, Please you share a document guide to connect AWS IoT Core MQTT by Mosquitto. I have some problem that it maybe like as your problem but my problem is occurred when Mosquitto try to connect to AWS IoT Core. I'm find some way to connect to it and that document may help me for this situation.

Thank You

답변함 일 년 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인