IoT核心:KafkaAction无法将消息发送到指定的引导服务器。SSL握手失败。

0

【以下的问题经过翻译处理】 我正在尝试使用 Basic Ingest 创建一个 IoT 核心规则,该规则触发 Kafka 操作以将我们的设备数据直接发送到我们的 Kafka 集群。我已成功设置此操作所需的 VPC 目标,指定包含 Kafka 代理的子网;但是,当 KafkaAction 失败时,我在 CloudWatch 中收到以下日志:

{
    "ruleName": "testKafkaAction",
    "topic": "",
    "cloudwatchTraceId": "<id>",
    "clientId": "test",
    "base64OriginalPayload": "<payload>",
    "failures": [
        {
            "failedAction": "KafkaAction",
            "failedResource": "iot-core-sensordata-stream",
            "errorMessage": "KafkaAction failed to send a message to the specified bootstrap servers. SSL handshake failed. Message arrived on: , Action: kafka, topic: test-kafka-action, bootstrap.servers: <bootstrap_servers>"
        }
    ]
}

我们的 Kafka 集群是自托管的,并使用自签名 CA。我在 Secrets Manager 中创建了一个二进制机密,其中包含 pkcs12 格式的信任库。信任库包含我们的自签名 CA。我使用 SASL_SSL 作为规则的安全协议,并使用 SCRAM-SHA-512 作为机制。用户名和密码也作为单独的密钥存储在 Secrets Manager 中。我的规则的 IAM 策略已正确设置以访问这些机密。另一件需要注意的事情:我的规则引导服务器列表是我们 VPC 中运行 Kafka 代理的节点的私有 ip:port,我确保这些 IP 在证书的 SAN 列表中。 这是我的规则的 json 模板作为参考:

{
    "sql": "SELECT *",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
        {
            "kafka": {
                "destinationArn": "<VPC_DESTINATION_ARN>",
                "topic": "test-kafka-action",
                "clientProperties": {
                    "bootstrap.servers": "<KAFKA_BOOTSTRAP_SERVERS>",
                    "key.serializer": "org.apache.kafka.common.serialization.StringSerializer",
                    "value.serializer": "org.apache.kafka.common.serialization.ByteBufferSerializer",
                    "security.protocol": "SASL_SSL",
                    "ssl.truststore": "${get_secret('<SECRET_NAME>', 'SecretBinary', '<KAFKA_RULE_ROLE_ARN>')}",
                    "ssl.truststore.password": "{{SSL_TRUSTSTORE_PASSWORD}}",
                    "sasl.mechanism": "SCRAM-SHA-512",
                    "sasl.scram.username": "${get_secret('<SECRET_NAME>', 'SecretString', 'kafkaUser', '<KAFKA_RULE_ROLE_ARN>')}",
                    "sasl.scram.password": "${get_secret('<SECRET_NAME>', 'SecretString', 'kafkaPassword', '<KAFKA_RULE_ROLE_ARN>')}"
                }
            }
        }
    ],
    "errorAction": {
        "cloudwatchLogs": {
            "logGroupName": "AWSIotLogsV2",
            "<KAFKA_RULE_LOGS_ROLE_ARN>"
        }
    }
}


此错误消息未提供有关握手失败原因的任何原因,因此我唯一的猜测是 IoT Core 不允许规则中的 KafkaAction 使用自签名 CA。 这是真的,还是我可能遗漏了其他地方的东西? 在必须将我们服务器的 IP 地址添加到证书上的 SAN 列表后, 我能够使用 python 客户端毫无问题地连接并向我们的 Kafka 集群发布消息, 为其提供相同的凭据和自签名 CA。

profile picture
专家
已提问 5 个月前4 查看次数
1 回答
0

【以下的回答经过翻译处理】 最终我使用略微不同的配置使事情可行,因此回答自己的问题以帮助其他人。 我仍然在我们的Kafka集群中使用自签名CA, 并通过在Secrets Manager中使用PKCS12格式的信任商店将其提供给我的IoT Core规则中的KafkaAction, 存储为二进制秘密(我已确认在信任商店中使用旧的JKS格式也有效)。 我通过为KafkaAction生成一个X.509证书和私钥来使事情可行,并将协议切换为SSL。 我创建了一个同样使用PKCS12格式的密钥库,其中包含此证书和私钥,并同样将其存储为二进制秘密,在Secrets Manager中。 对于不熟悉的人来说,您只能通过CLI或SDK创建二进制秘密,无法通过控制台创建。 在我的规则配置中,我使用文档中显示的get_secret方法来指示IoT Core从Secrets Manager获取二进制文件。 我的此规则的IAM角色还具有允许访问这些秘密的策略。 最后需要注意的一件事是:我的信任商店和密钥库都有密码保护, 因此我还必须在规则的配置中指定此密码(在我的情况下两者相同)。 我从未能够使用SASL和SCRAM-SHA-512使事情可行, 因此我唯一的猜测是,这是不支持使用自签名CA,或者文档在实际支持的区域方面存在混淆。

profile picture
专家
已回答 5 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则