无法让Greengrass与TPM私钥及证书配合使用的问题
问题详情
尝试将AWS Greengrass V2与SLB9670 TPM配合使用,但无论在TPM内生成密钥/证书还是外部生成后导入,均无法成功建立连接。网上相关文档大多失效或不准确。
操作脚本
/home/usr/tpm2-pkcs11/tools/tpm2_ptool.py init --path=/opt/tpm2-pkcs11/ chmod 777 /opt/tpm2-pkcs11 /home/usr/tpm2-pkcs11/tools/tpm2_ptool.py addtoken --pid=1 --sopin=123456 --userpin=123456 --label=greengrass --path=/opt/tpm2-pkcs11/ /home/usr/tpm2-pkcs11/tools/tpm2_ptool.py addkey --algorithm=rsa2048 --label=greengrass --key-label=iotkey --userpin=123456 --path=/opt/tpm2-pkcs11/ rsa_auth=$(/home/usr/tpm2-pkcs11/tools/tpm2_ptool.py export --label=greengrass --path=/opt/tpm2-pkcs11/ --userpin=123456 --key-label=iotkey | grep "object-auth" | cut -d ' ' -f2-) openssl req -new -provider tpm2 -provider base -key=iotkey.pem -subj="/C=US/O=Company" --passin="pass:$rsa_auth" -out=csr.req certArn=$(aws iot create-certificate-from-csr --certificate-pem-outfile /home/usr/cert.pem --certificate-signing-request file://csr.req | grep certificateArn | awk '{ print $NF }' | tr -d '"' | tr -d ',' | xargs) certId=$(echo $certArn | sed 's@.*/@@' | xargs) aws iot update-certificate --certificate-id $certId --new-status ACTIVE /home/usr/tpm2-pkcs11/tools/tpm2_ptool.py addcert --label=greengrass --key-label=iotkey --path=/opt/tpm2-pkcs11/ cert.pem aws iot create-thing --thing-name myThing aws iot add-thing-to-thing-group --thing-name myThing --thing-group-name thingGroup aws iot attach-thing-principal --thing-name myThing --principal "$certArn" aws iot attach-policy --policy-name GreengrassV2IoTThingPolicy --target "$certArn" aws iot attach-policy --policy-name Assume-Role-Policy --target "$certArn" aws iot attach-policy --policy-name GreengrassTESCertificatePolicyGreengrassV2TokenExchangeRoleAlias --target "$certArn" sudo mkdir -p /greengrass/v2 chmod 777 /greengrass/v2 sudo curl -o /greengrass/v2/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE -jar ./GreengrassInstaller/lib/Greengrass.jar --trusted-plugin ./GreengrassInstaller/aws.greengrass.crypto.Pkcs11Provider.jar --init-config ./GreengrassInstaller/config.yaml --component-default-user root:root --setup-system-service true
config.yaml 配置
--- system: certificateFilePath: "pkcs11:object=iotkey;type=cert" privateKeyPath: "pkcs11:object=iotkey;type=private" rootCaPath: "/greengrass/v2/AmazonRootCA1.pem" rootpath: "/greengrass/v2" thingName: "myThing" services: aws.greengrass.Nucleus: componentType: "NUCLEUS" version: "2.11.2" configuration: awsRegion: "us-east-2" iotRoleAlias: "GreengrassV2TokenExchangeRoleAlias" iotDataEndpoint: "myPrefix.iot.us-west-2.amazonaws.com" iotCredEndpoint: "myPrefix.credentials.iot.us-west-2.amazonaws.com" aws.greengrass.crypto.Pkcs11Provider: configuration: name: "tpm2_pkcs11" library: "/home/usr/tpm2-tss/tpm2-pkcs11/src/.libs/tpm2_pkcs11.so" slot: 1 userPin: "123456"
验证结果
已通过以下命令确认TPM内的密钥和证书生成正常:
p11tool --list-all --login "{{URL}}"
错误信息
Greengrass Nucleus启动后抛出连接错误:
Failed to connect to AWS IoT Core. {clientId=myThing, error=The connection was closed unexpectedly}.
排查与修复方案
1. 统一区域配置
你的config.yaml中awsRegion设置为us-east-2,但iotDataEndpoint和iotCredEndpoint属于us-west-2区域,区域不匹配会直接导致连接失败。将awsRegion修改为us-west-2,确保所有配置使用同一区域。
2. 修正PKCS#11证书路径
当前certificateFilePath使用object=iotkey,但该标签属于私钥,证书的标签可能不同。执行以下命令查看TPM内的所有对象详情:
tpm2_ptool.py listobjects --label=greengrass --path=/opt/tpm2-pkcs11/ --userpin=123456
找到证书对应的object label,将certificateFilePath更新为正确路径,例如:
certificateFilePath: "pkcs11:object=iotcert;type=cert"
3. 确保PKCS#11库权限正确
Greengrass以root用户运行,需确保TPM PKCS#11库文件有足够权限:
sudo chmod 755 /home/usr/tpm2-tss/tpm2-pkcs11/src/.libs/tpm2_pkcs11.so sudo chown root:root /home/usr/tpm2-tss/tpm2-pkcs11/src/.libs/tpm2_pkcs11.so
4. 校验IoT策略权限
确认GreengrassV2IoTThingPolicy包含必要的MQTT连接权限,至少添加以下语句(替换<区域>和<账户ID>):
{ "Effect": "Allow", "Action": [ "iot:Connect", "iot:Publish", "iot:Subscribe", "iot:Receive" ], "Resource": [ "arn:aws:iot:<区域>:<账户ID>:client/${iot:Connection.Thing.ThingName}", "arn:aws:iot:<区域>:<账户ID>:topic/$aws/things/${iot:Connection.Thing.ThingName}/greengrass/#", "arn:aws:iot:<区域>:<账户ID>:topicfilter/$aws/things/${iot:Connection.Thing.ThingName}/greengrass/#" ] }
5. 启用详细日志定位问题
修改Greengrass启动命令,添加DEBUG日志级别:
sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE -Dlogging.level.com.aws.greengrass=DEBUG -jar ./GreengrassInstaller/lib/Greengrass.jar --trusted-plugin ./GreengrassInstaller/aws.greengrass.crypto.Pkcs11Provider.jar --init-config ./GreengrassInstaller/config.yaml --component-default-user root:root --setup-system-service true
查看/greengrass/v2/logs/greengrass.log,查找PKCS#11初始化或TLS握手的具体错误信息。
6. 验证TPM密钥可用性
使用openssl测试TPM内的密钥能否正常签名:
# 创建测试文件 echo "test content" > test.txt # 用TPM密钥签名 openssl dgst -sha256 -sign "pkcs11:object=iotkey;type=private" -provider tpm2 -provider base test.txt > test.sig # 用证书验证签名 openssl dgst -sha256 -verify cert.pem -signature test.sig test.txt
如果验证失败,说明密钥或证书存在问题,需重新生成并导入TPM。
内容的提问来源于stack exchange,提问作者Joshua S

