1
votes

I am trying out the ShadowSample example that comes as part of Java AWS IoT Device SDK - https://github.com/aws/aws-iot-device-sdk-java/blob/master/aws-iot-device-sdk-java-samples/src/main/java/com/amazonaws/services/iot/client/sample/shadow/ShadowSample.java

I am able to run it successfully and it works properly. However, it works properly when I have the following policy attached to the certificate (and certificate in turn to device) -

{
  "Version": "2012-10-17",
  "Statement": [
  {
      "Effect": "Allow",
      "Action": [
        "iot:Subscribe",
        "iot:Receive",
        "iot:Publish",
        "iot:Connect"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

I want to have a generic and strict policy (especially for publish and receive actions) than granting rights to all i.e. "*" resource. So, I update the policy in the below forms and all are not working -

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Subscribe", "iot:Connect" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "iot:Publish" ], "Resource": [ "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/update", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/get", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/delete", ] }, { "Effect": "Allow", "Action": [ "iot:Receive" ], "Resource": [ "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/update/accepted", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/update/rejected", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/update/delta", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/update/documents", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/get/accepted", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/get/rejected", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/delete/accepted", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/delete/rejected", ] } ] }

and

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Subscribe", "iot:Connect" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive" ], "Resource": [ "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/update/*", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/get/*", "arn:aws:iot:us-west-2:64867635xxxx:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/delete/*", ] } ] }

Note - For security purpose, I have put xxxx against account number. In real policies, I have proper values.

I even replace the * in topic with #, but the same result continues. The result is -

Oct 25, 2017 9:32:43 AM com.amazonaws.services.iot.client.mqtt.AwsIotMqttConnectionListener onFailure
WARNING: Connect request failure
Unable to connect to server (32103) - java.net.ConnectException: Connection timed out: connect
    at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:94)
    at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:103)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:701)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:80)
    ... 9 more

Oct 25, 2017 9:32:43 AM com.amazonaws.services.iot.client.core.AwsIotConnection onConnectionFailure
INFO: Connection temporarily lost

On the AWS CloudWatch, under AWS IoT specific logs, I find -

2017-10-25 04:10:22.633 TRACEID:1db8b391-83c7-faf3-5aeb-c0d106787afe PRINCIPALID:e7ac813cdcbecffebecef9647a166882f93f5a2aa214cb6bbd9a1e41f7832f76 [ERROR] EVENT:MQTT Client Connect MESSAGE:Connect Status: AUTHORIZATION_ERROR

What shall be the generic and strict policy for supporting publish and receive actions?

Note that the aforementioned policies which I have tried are working fine when I try out the pub-sub example (also provided in the same SDK). These policies are not working for shadow example because there is an additional step of attaching device to connection client.

Another small query: How will I minimise or restrict topic subscription for subscribe action in generic way as variable replacement like thing type, thing name do not work for subscribe (but work for receive and publish)?

1

1 Answers

2
votes

Is your MQTT Client ID the same as your Thing Name?

I recently had a similar issue while trying to create a policy that uses the Thing attributes. It wasn't picking up the fact that I had attached my Cognito Identity to the Thing as I would have expected it to do. My policy did not work until I changed my MQTT Client ID and then the thing attributes were pulled in correctly. I was hoping to have a Thing per customer, but as MQTT Client ID must be unique and it's also what attaches the connection to a Thing, I'll need to create a Thing per customer per device.

I believe the reasoning, behind attaching an identity principal to a Thing and using the MQTT Client ID to attach the connection to the Thing, is because you can actually attach the same identity principal to multiple Things and on the backend it wouldn't know the exact thing you connection should be. This allows you to reuse the same identity across multiple devices for the same customer, which is more keeping with how Cognito works. It also prevents a certificate or Cognito identity from attaching to a Thing that it doesn't have permissions.

Let me know if this helps.