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 Answers
2
Accepted Answer

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
EXPERT
Jan_B
answered 2 years ago
profile pictureAWS
EXPERT
Greg_B
reviewed 2 years ago
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.

answered 2 years ago
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

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions