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
EXPERTE
gefragt vor 6 Monaten4 Aufrufe
1 Antwort
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
EXPERTE
beantwortet vor 6 Monaten

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen