“SSL: CERTIFICATE_VERIFY_FAILED” Error when publish MQTT, AWS IoT
Asked Answered
S

3

8

I am getting the following error:

[ERROR] SSLError: SSL validation failed for https://data.iot.ap-northeast-2.amazonaws.com/topics/app%2Ftest%2Fresponse?qos=1 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1124)
Traceback (most recent call last):
  File "/var/task/app.py", line 197, in lambda_handler
    mqttcli.test('test', '11111', {}, 1, 200)
  File "/opt/python/lib/python3.8/site-packages/connectors/MQTTClient.py", line 40, in test
    response = self._iot_client.publish(
  File "/var/task/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/task/botocore/client.py", line 662, in _make_api_call
    http, parsed_response = self._make_request(
  File "/var/task/botocore/client.py", line 682, in _make_request
    return self._endpoint.make_request(operation_model, request_dict)
  File "/var/task/botocore/endpoint.py", line 102, in make_request
    return self._send_request(request_dict, operation_model)
  File "/var/task/botocore/endpoint.py", line 136, in _send_request
    while self._needs_retry(attempts, operation_model, request_dict,
  File "/var/task/botocore/endpoint.py", line 253, in _needs_retry
    responses = self._event_emitter.emit(
  File "/var/task/botocore/hooks.py", line 356, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
  File "/var/task/botocore/hooks.py", line 228, in emit
    return self._emit(event_name, kwargs)
  File "/var/task/botocore/hooks.py", line 211, in _emit
    response = handler(**kwargs)
  File "/var/task/botocore/retryhandler.py", line 183, in __call__
    if self._checker(attempts, response, caught_exception):
  File "/var/task/botocore/retryhandler.py", line 250, in __call__
    should_retry = self._should_retry(attempt_number, response,
  File "/var/task/botocore/retryhandler.py", line 277, in _should_retry
    return self._checker(attempt_number, response, caught_exception)
  File "/var/task/botocore/retryhandler.py", line 316, in __call__
    checker_response = checker(attempt_number, response,
  File "/var/task/botocore/retryhandler.py", line 222, in __call__
    return self._check_caught_exception(
  File "/var/task/botocore/retryhandler.py", line 359, in _check_caught_exception
    raise caught_exception
  File "/var/task/botocore/endpoint.py", line 200, in _do_get_response
    http_response = self._send(request)
  File "/var/task/botocore/endpoint.py", line 269, in _send
    return self.http_session.send(request)
  File "/var/task/botocore/httpsession.py", line 281, in send
    raise SSLError(endpoint_url=request.url, error=e)

This is the code that is causing this error:

_iot_client = boto3.client('iot-data',
                                aws_access_key_id=AWS_ACCESS_KEY_ID,
                                aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
                                region_name= REGION_NAME)
    response = _iot_client.publish(
        topic = "app/test/response",
        qos = 1,
        payload = json.dumps(
            {
                'msgid': msgid,
                'status': status,
                'data': payload
            }
        )
    )

There is no error in S3 or other services through boto3. only iot-data.

It works without any problems when i run the .py.

but an error occurs when running after deploy to lambda.

There was no error until recently.

Spotted answered 14/12, 2020 at 8:7 Comment(5)
Does this answer your question? botocore.exceptions.SSLError: SSL validation failed on WIndowsRennold
I'd contact Amazon about this. The certificate tied to data.iot.ap-northeast-2.amazonaws.com is issued by Symantec and there are multiple sites that indicate that these are no longer accepted though the information is a bit confusing. Neither Firefox or Chrome will accept the certificate.Lindley
@L. Lauenburg, an error occurs only iot-data. and my pc is macSpotted
I solved this error. AWS IoT uses Symantec certificates. I set up ATS Endpoint that reflects the Amazon Trust Services certificate. boto3.amazonaws.com/v1/documentation/api/latest/reference/core/…Spotted
@Spotted how do you manage to do that? your solution seems more elegant than pinpointing an old version of certifiGooseneck
H
13

We also are experiencing this issue, in our case, an update in the "certifi" library (requests dependency) was causing some conflict with boto3 iot publish, rolling back the version solved the problem, although we are not entirely sure what exactly was failing.

Hemialgia answered 16/12, 2020 at 18:55 Comment(2)
Could you please specify the versions that do not conflict?Weatherboard
@LucasVentura This just saved my day, thanks!! (Though as it's months later I'm surprised this is still an issue, but this fixed me for the time being in every case).Gman
A
2

You need to get the "Data-ATS" endpoint instead of the untrusted "Symantec" endpoint that's built-in. Try this:

import boto3


def get_aws_iot_ats_endpoint():
    """
    Get the "Data-ATS" endpoint instead of the
    untrusted "Symantec" endpoint that's built-in.
    """
    iot_client = boto3.client(
        "iot",
        aws_access_key_id=AWS_ACCESS_KEY_ID,
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
        region_name= REGION_NAME,
        verify=True
    )
    details = iot_client.describe_endpoint(endpointType="iot:Data-ATS")
    host = details.get("endpointAddress")
    return f"https://{host}"


IOT_DATA_ENDPOINT = get_aws_iot_ats_endpoint()

client_iot = boto3.client(
    "iot-data",
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    region_name= REGION_NAME,
    verify=True,
    endpoint_url=IOT_DATA_ENDPOINT
)

response = client_iot.publish(
        topic = "app/test/response",
        qos = 1,
        payload = json.dumps(
            {
                'msgid': msgid,
                'status': status,
                'data': payload
            }
        )
    )
Abel answered 1/2, 2022 at 23:18 Comment(0)
H
-5

I had the same error.

Simply insert this at the beginning of your code:`

from botocore.exceptions import ClientError

It should work.

Best.

Hiller answered 7/1, 2021 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.