通过systemd运行Python AWS IoT SDK程序时openssl证书验证失败
问题定位步骤
- 先对比两种运行场景的SSL默认证书路径:在交互式终端使用项目虚拟环境的Python执行命令
import ssl; print(ssl.get_default_verify_paths()),记录输出的CA文件、CA目录路径。临时在main.py开头加入相同代码,将输出写入本地日志文件,使用systemd启动服务后查看日志中的路径,确认二者是否存在差异。 - 检查systemd运行时的环境变量缺失:systemd默认不会加载用户目录下的.bashrc、.profile等配置文件中的自定义变量,重点排查
SSL_CERT_FILE、REQUESTS_CA_BUNDLE这两个和证书验证相关的变量,是否是你在终端环境中配置过但systemd运行时未加载。 - 检查证书文件权限与路径:确认代码中引用的AWS根证书、设备证书、私钥文件,要么使用绝对路径,要么相对路径和你直接在终端运行时的工作目录完全匹配,同时确认所有证书文件pi用户拥有可读权限。
解决方案
根据定位到的问题,对应选择以下解决方法:
- 缺失证书环境变量的解决
在你的service配置文件的[Service]段添加对应的环境变量配置,路径填写刚才终端输出的对应证书路径即可,示例如下:
[Service] User=pi Group=pi WorkingDirectory=/home/pi/experiments/GreenRpi/ # 新增证书环境变量配置 Environment="SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt" Environment="REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt" ExecStart=/home/pi/experiments/GreenRpi/.venv/bin/python main.py somearg Restart=always RestartSec=30
- 证书路径不匹配的解决
将代码中所有引用证书文件的路径改为绝对路径,避免相对路径依赖工作目录的问题。如果是使用AWS IoT Python SDK,也可以在初始化MQTT连接时显式指定CA根证书的绝对路径,示例如下:
from awsiot import mqtt_connection_builder # 替换为你实际的CA证书绝对路径 root_ca_path = "/home/pi/experiments/GreenRpi/certs/AmazonRootCA1.pem" mqtt_conn = mqtt_connection_builder.mtls_from_path( endpoint="你的AWS IoT端点地址", cert_filepath="你的设备证书绝对路径", pri_key_filepath="你的设备私钥绝对路径", ca_filepath=root_ca_path, # 显式指定后不再依赖系统默认CA路径 client_id="你的设备客户端ID" )
- 配置生效操作
修改完service文件后,执行以下命令加载配置并重启服务:
sudo systemctl daemon-reload sudo systemctl restart greenrpi.service
内容的提问来源于stack exchange,提问作者aang
相关产品推荐
相关产品推荐

