简体   繁体   中英

Cannot connect to aws-iot using paho-mqtt java client code

I created thing on AWS core. Then downloaded cert, private key and rootCa certificate too. My main goal is to publish and subscribe to AWS . I tried to connect to aws iot using paho mqtt java client code, using following code.

public class App{
public static void main(String args[]){

        try{

            String caFilePath = "/home/sanju/Documents/Windows Shared/Leron/runningProjects/dcuFirmwareUpload/certificates/MINI/rootca.crt";
            String clientCrtFilePath = "/home/sanju/Documents/Windows Shared/Leron/runningProjects/dcuFirmwareUpload/certificates/MINI/7d6238abc3-certificate.pem.crt";
            String clientKeyFilePath = "/home/sanju/Documents/Windows Shared/Leron/runningProjects/dcuFirmwareUpload/certificates/MINI/7d6238abc3-private.pem.key";

            String topic = "ThingName/firmwareupdate";
            String content = "Message from MqttPublishSample";
            int qos = 2;
            String broker = "ssl://xxxxxxxxxxxxxxxxx.iot.us-east-2.amazonaws.com:8883";
            String clientId = "ThingName";
            MemoryPersistence persistence = new MemoryPersistence();
            MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();

            /*connOpts.setCleanSession(true);*/

            connOpts.setConnectionTimeout(60);
            connOpts.setKeepAliveInterval(60);

            SSLSocketFactory socketFactory = getSocketFactory(caFilePath,
                    clientCrtFilePath, clientKeyFilePath, "");
            connOpts.setSocketFactory(socketFactory);

            System.out.println("Connecting to broker: " + broker);
            sampleClient.connect(connOpts);
            sampleClient.subscribe("subscribeTopic", 1);
            System.out.println("Connected");
            System.out.println("Publish message: " + content);
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            sampleClient.setCallback(new SimpleCallback());
            sampleClient.publish(topic, message);
            System.out.println("Message published");
            try {
                Thread.sleep(5000);
                sampleClient.disconnect();
            } catch(Exception e) {
                e.printStackTrace();
            }
            System.out.println("Disconnected");
            System.exit(0);
        }catch(MqttException me){
             System.out.println("reason " + me.getReasonCode());
                System.out.println("msg " + me.getMessage());
                System.out.println("loc " + me.getLocalizedMessage());
                System.out.println("cause " + me.getCause());
                System.out.println("except " + me);
                me.printStackTrace();

        }catch(Exception e){
            System.out.println("running: "+e);
        }
    }

    private static SSLSocketFactory getSocketFactory(final String caCrtFile,
            final String crtFile, final String keyFile, final String password)
            throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        // load CA certificate
        PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
        X509Certificate caCert = (X509Certificate)reader.readObject();
        reader.close();

        // load client certificate
        reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
        X509Certificate cert = (X509Certificate)reader.readObject();
        reader.close();

        // load client private key
        reader = new PEMReader(
                new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
                new PasswordFinder() {
                    @Override
                    public char[] getPassword() {
                        return password.toCharArray();
                    }
                }
        );
        KeyPair key = (KeyPair)reader.readObject();
        reader.close();

        // CA certificate is used to authenticate server
        KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
        caKs.load(null, null);
        caKs.setCertificateEntry("ca-certificate", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(caKs);

        // client key and certificates are sent to server so it can authenticate us
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", cert);
        ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());

        // finally, create SSL socket factory
        /*SSLContext context = SSLContext.getInstance("TLSv1");*/
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
    }

I am getting the following log and error

Connecting to broker: ssl://aclugxc4jtbld-ats.iot.us-east-2.amazonaws.com:8883 reason 0 msg MqttException loc MqttException cause java.net.SocketTimeoutException: connect timed out except MqttException (0) - java.net.SocketTimeoutException: connect timed out MqttException (0) - java.net.SocketTimeoutException: connect timed out at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38) at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:715) 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.concurren t.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.net.SocketTimeoutException: connect timed out at java.net.PlainSocketImpl.socketConnect(Native Method) 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.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) 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) ... 7 more

want connect to aws IOT so that i can publish/subscribe to topics.


I haven't used Java client, but when I see 'connect timed out' with MQTT, I would check the policy attached to the device's certificate. Does the MQTT client's name in your code match the client's name in the policy? What about the Thing name? Also, check for the correct region and account in the policy.

For example, 'RaspberryPi' below should match in the policy in the cloud and your device's code:

  "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": "iot:Connect",
        "Resource": "arn:aws:iot:REGION:ACCOUNT:client/RaspberryPi"      
      },

If things still don't work, try an overly permissive policy to sanity check it. After you find the issue, restrict the policy to least privilege to make it more secure:

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

Another good example from AWS IoT docs: Check the "iot:Connect" in the policy here: https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-policy.html

and how the '--clientId RaspberryPi' (MQTT client) and '--thingName RaspberryPi' used in the code match the respective names used the policy: https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-raspi-setup.html .

"Resource": "arn:aws:iot:REGION:ACCOUNT:client/RaspberryPi"      
"Resource": "arn:aws:iot:REGION:ACCOUNT:thing/RaspberryPi"

Note that the MQTT client's name and Thing's name can have different names, but have to match the names in the policy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM