IoT policy to restrict MQTT publish/subscribe by Thing Name

0

Good morning. I want to apply a MQTT policy that grants the IoT thing access to certain topic. For example, assuming that the thing name is 0R281, I would like a policy that allows the thing to publish only in a topic with the following name xgate/0R281/data

I created a policy structured like this

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "iot:Connect",
			"Resource": "arn:aws:iot:eu-west-1:<acc>:client/${iot:Connection.Thing.ThingName}"
		},
		{
			"Effect": "Allow",
			"Action": "iot:Subscribe",
			"Resource": "arn:aws:iot:eu-west-1:<acc>:topicfilter/xgate/${iot:Connection.Thing.ThingName}/data"
		},
		{
			"Effect": "Allow",
			"Action": "iot:Publish",
			"Resource": "arn:aws:iot:eu-west-1:<acc>:topic/xgate/${iot:Connection.Thing.ThingName}/data"
		}
	]
}

but it does not work. Trying with a policy made like this obviously works,

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:", "Resource": "" } ] }

I don't understand where the mistake is

已提问 4 个月前354 查看次数
3 回答
0
已接受的回答

Hi. What MQTT client ID is your device using? For the iot:Connection.Thing.ThingName policy variable to work, the client ID must match the Thing name. And does your device use the same certificate as what's attached to the Thing in the registry?

https://docs.aws.amazon.com/iot/latest/developerguide/thing-policy-variables.html

The thing name is obtained from the client ID in the MQTT Connect message sent when a thing connects to AWS IoT Core.

AWS IoT Core uses the certificate the device presents when it authenticates to determine which thing to use to verify the connection.

UPDATE: The problem is that the client ID you're using in the Python code should just be 0R281 not arn:aws:iot:eu-west-1:<acc>:client/0R281. I also recommend you swap to the V2 SDK (https://github.com/aws/aws-iot-device-sdk-python-v2), although that's not an immediate concern.

profile pictureAWS
专家
Greg_B
已回答 4 个月前
profile picture
专家
已审核 2 个月前
  • Answer updated now that I've seen your code. As suspected, the client ID doesn't match the Thing name.

0

I created the thing and then created and downloaded the certificates Enter image description here I associated the certificate with the policy written before ​Enter image description here Using the Python SDK I instantiated an MQTT client for sending messages with the certificates mentioned above Enter image description here

The client that I instantiate uses the following class defined as follows ​

from AWSIoTPythonSDK import MQTTLib as AWSIoTPyMQTT
class AwsClient:
    def __init__(
        self,
        ca_file_path: str,
        key_path: str,
        certificate_path: str,
        client_id: str,
        endpoint: str,
        port: int = 8883,
    ):
        self.ca_file_path = ca_file_path
        self.key_path = key_path
        self.certificate_path = certificate_path
        self.client_id = client_id
        self.port = port
        self.endpoint = endpoint

    def get_client(self):
        aws_client = AWSIoTPyMQTT.AWSIoTMQTTClient(self.client_id)
        aws_client.configureEndpoint(self.endpoint, self.port)
        aws_client.configureCredentials(
            CAFilePath=self.ca_file_path,
            KeyPath=self.key_path,
            CertificatePath=self.certificate_path,
        )
        return aws_client

when the policy has the first definition that I specified in the first post as its active version, the message is not sent and I get the following error

​AWSIoTPythonSDK.exception.AWSIoTExceptions.connectTimeoutException

If instead I use the second policy mentioned as the active version of the policy (the less restrictive one) the message is sent and I see it received as in the following image

Enter image description here

已回答 4 个月前
  • Hi. The problem is that the client ID you're using in the Python code should just be 0R281 not arn:aws:iot:eu-west-1:<acc>:client/0R281. I also recommend you swap to the V2 SDK (https://github.com/aws/aws-iot-device-sdk-python-v2), although that's not an immediate concern.

0

specifying the client with only OR 281 in the code works, thank you very much

已回答 4 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则