AWS物联网:在端口443上使用MQTT

AWS物联网:在端口443上使用MQTT,mqtt,raspberry-pi3,iot,paho,aws-iot,Mqtt,Raspberry Pi3,Iot,Paho,Aws Iot,我正在尝试使用Paho MQTT在端口443的Pi中设置AWS IoT 正如AWS文件()提到的 希望使用MQTT与端口443上的X.509客户端证书身份验证进行连接的客户端必须实现应用层协议协商(ALPN)TLS扩展,并将X-amzn-MQTT-ca作为ProtocolName列表中的ProtocolName传递 我实际上不知道如何在Paho MQTT()中正确地实现它 我试图做什么(mqtt_apln.py) 在Pi中,我安装了python 2.7.14和paho mqtt 但当我运行pyt

我正在尝试使用Paho MQTT在端口443的Pi中设置AWS IoT

正如AWS文件()提到的

希望使用MQTT与端口443上的X.509客户端证书身份验证进行连接的客户端必须实现应用层协议协商(ALPN)TLS扩展,并将X-amzn-MQTT-ca作为ProtocolName列表中的ProtocolName传递

我实际上不知道如何在Paho MQTT()中正确地实现它

我试图做什么(mqtt_apln.py)

在Pi中,我安装了python 2.7.14和paho mqtt

但当我运行python mqtt_apln.py时,它显示错误:ImportError:没有名为paho.mqtt.client的模块


欢迎提出任何建议

我认为这里有两件事。首先,pip install paho mqtt应使当前引用的python的包处于活动状态。例如,在3.6.2虚拟环境下,应返回:

$ pip list
DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your 
pip.conf under the [list] section) to disable this warning.

paho-mqtt (1.3.1)
pip (9.0.1)
setuptools (28.8.0)
您是如何通过
apt
软件包或直接使用pip安装paho mqtt软件包的?就我个人而言,我通过
pip install package\u name-t.
将所有内容虚拟化或包含在应用程序目录中,以引用当前的工作目录

从那里开始,它与ALPN配置一起工作。我将您的代码简化为仅发布到我的端点上的
test
主题,并使用AWS物联网控制台-->test订阅
test
主题。对于Python2.7.12和3.6.2,我都成功地收到了消息

主要更改是删除回调,放置一个
mqttc.publish
,然后放置一个
time.sleep(3)
,给线程发布时间,然后关闭连接

以下是仅用于发布的成对代码:

import sys
import ssl
import time
import datetime
import logging, traceback
import paho.mqtt.client as mqtt

MQTT_TOPIC = "topictest"
MQTT_MSG = "hello MQTT"

IoT_protocol_name = "x-amzn-mqtt-ca"
aws_iot_endpoint = "xxxxxx.iot.us-east-1.amazonaws.com"

ca = "ca.pem"
cert = "xxxx-certificate.pem.crt"
private = "xxxx-private.pem.key"

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(log_format)
logger.addHandler(handler)

def ssl_alpn():
    try:
        #debug print opnessl version
        logger.info("open ssl version:{}".format(ssl.OPENSSL_VERSION))
        ssl_context = ssl.create_default_context()
        ssl_context.set_alpn_protocols([IoT_protocol_name])
        ssl_context.load_verify_locations(cafile=ca)
        ssl_context.load_cert_chain(certfile=cert, keyfile=private)
        return  ssl_context
    except Exception as e:
        print("exception ssl_alpn()")
        raise e


mqttc = mqtt.Client()

ssl_context= ssl_alpn()
mqttc.tls_set_context(context=ssl_context)
logger.info("start connect")
mqttc.connect(aws_iot_endpoint, port=443)
logger.info("connect success")
mqttc.loop_start()

# After loop start publish and wait for message to be sent.
# Hard coded delay but would normally tie into event loop
# or on_publish() CB

# JSON payload because, pretty
mqttc.publish('test', '{"foo": "bar"}')
time.sleep(3)
mqttc.loop_stop()

请让我知道这对你有用吗?AWS现在支持端口443上的MQTT连接,而不必使用WebSocket(以及对SigV4凭据的需要),这真是太棒了。

关于使用paho MQTT和AWS IoT core,我遇到了同样的问题。

本教程不使用clientID。根据您的安全规则,您必须提供客户端ID才能正确连接。这里是一个SDK示例规则集,其中仅允许客户端“SDK java”、“basicPubSub”和“SDK nodejs-*”进行连接

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:eu-central-1:036954049003:topic/sdk/test/java",
        "arn:aws:iot:eu-central-1:036954049003:topic/sdk/test/Python",
        "arn:aws:iot:eu-central-1:036954049003:topic/topic_1",
        "arn:aws:iot:eu-central-1:036954049003:topic/topic_2"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Subscribe"
      ],
      "Resource": [
        "arn:aws:iot:eu-central-1:036954049003:topicfilter/sdk/test/java",
        "arn:aws:iot:eu-central-1:036954049003:topicfilter/sdk/test/Python",
        "arn:aws:iot:eu-central-1:036954049003:topicfilter/topic_1",
        "arn:aws:iot:eu-central-1:036954049003:topicfilter/topic_2"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:eu-central-1:036954049003:client/sdk-java",
        "arn:aws:iot:eu-central-1:036954049003:client/basicPubSub",
        "arn:aws:iot:eu-central-1:036954049003:client/sdk-nodejs-*"
      ]
    }
  ]
}
如果您拥有基于clientid的许可证,则要允许连接,请更改此行:

mqttc = mqtt.Client(client_id=MYCLIENTID)

MYCLIENTID是本例中三个“sdk java”、“BasicPubsubSub”或“sdk nodejs-*”之一。

我会尝试一下,但现在,在与it团队长期协商后,他们打开了8883端口
mqttc = mqtt.Client(client_id=MYCLIENTID)