I'm trying to publish data in a dataframe (originally in a txt file) to AWS IoT Core using paho-mqtt. My publish script is setup as follows:
# paho mqtt
import paho.mqtt.client as mqtt
clientID = "iotconsole-somenumber-0"
broker = "alphanumeric-ats.iot.us-west-1.amazonaws.com"
port = 8883
pub = mqtt.Client(clientID)
pub.tls_set("certs/AmazonRootCA1.pem", certfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_certificate.pem.crt", keyfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_private.pem.key")
pub.connect(broker, port)
pub.publish("awsiot_test", dataframe, qos = 1)
But, when I run this script I get the following error. I think I'm doing something wrong with my thing certs. But can't zero in on it.
File ~\PyProj\projfolder\code.py:9 in <module>
pub.tls_set("certs/AmazonRootCA1.pem", certfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_certificate.pem.crt", keyfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_private.pem.key")
File ~\anaconda3\lib\site-packages\paho\mqtt\client.py:796 in tls_set
context.load_cert_chain(certfile, keyfile, keyfile_password)
FileNotFoundError: [Errno 2] No such file or directory
I thought it was a cert file -/_ issue or an extension issue. But, haven't found a solution yet. How do I fix this? Thanks!
CodePudding user response:
As per the comments the error you are seeing is triggered by a call to context.load_cert_chain(certfile, keyfile, keyfile_password);
and indicates that one of the files (certs/AmazonRootCA1.pem
and/or certs/a0c9496....afd4f67f_certificate.pem.crt
) do not exist (this could possibly be permissions related).
To assist in showing the most likely cause I copied and ran your code with the same result:
python3 app.py
Traceback (most recent call last):
File "/workspaces/test/app.py", line 9, in <module>
pub.tls_set("certs/AmazonRootCA1.pem", certfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_certificate.pem.crt", keyfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_private.pem.key")
File "/usr/local/pip-global/paho/mqtt/client.py", line 796, in tls_set
context.load_cert_chain(certfile, keyfile, keyfile_password)
FileNotFoundError: [Errno 2] No such file or directory
I then created the certificate file:
mkdir certs
touch certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_certificate.pem.crt
and ran the app again (making no other changes):
python3 app.py
Traceback (most recent call last):
File "/workspaces/test/app.py", line 9, in <module>
pub.tls_set("certs/AmazonRootCA1.pem", certfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_certificate.pem.crt", keyfile = "certs/a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_private.pem.key")
File "/usr/local/pip-global/paho/mqtt/client.py", line 796, in tls_set
context.load_cert_chain(certfile, keyfile, keyfile_password)
ssl.SSLError: [SSL] PEM lib (_ssl.c:4044)
You will note that there is now a different error (the certificate now exists but is not a valid certificate). Adding a valid crt
file will result in the No such file or directory
error appearing again (due to an attempt to load the key file).
To complete the example I generated a test certificate and put the certificate into AmazonRootCA1.pem
and a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_certificate.pem.crt
and the key into a0c94969f1e7d914d6fe54425d772e8d4611a4710d460e9f56374ea0afd4f67f_private.pem.key
and ran the app:
python3 app.py
Traceback (most recent call last):
File "/workspaces/test/app.py", line 10, in <module>
pub.connect(broker, port)
File "/usr/local/pip-global/paho/mqtt/client.py", line 914, in connect
return self.reconnect()
File "/usr/local/pip-global/paho/mqtt/client.py", line 1044, in reconnect
sock = self._create_socket_connection()
File "/usr/local/pip-global/paho/mqtt/client.py", line 3685, in _create_socket_connection
return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source)
File "/usr/local/lib/python3.9/socket.py", line 823, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "/usr/local/lib/python3.9/socket.py", line 954, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
This demonstrates that having valid certificates/key can result in the function completing successfully (it's now trying to connect to alphanumeric-ats.iot.us-west-1.amazonaws.com
which will fail).
Your question does not provide sufficient information to do any further investigation; if you are still experiencing the issue try duplicating the process above and this will, most likely, assist in finding the cause.