SSLError on GET request from Chalice to IoT Core

0

Hello,

I am receiving an SSLError when trying to send a GET request from my Chalice backend (which runs as a lambda) to Iot Core Device Shadow service, via Boto3 client for IoT Core. Here is the workflow I am looking to achieve:

GET --> Chalice Backend (Lambda) --> Helper Module (Boto3) --> GET --> IoT Core Device Shadow REST API

More details: this Helper Module uses a boto3 iot-data client to make requests to the Device Shadow REST API. Using this module alone, if I provide AWS_SECRET_KEY and AWS_ACCESS_ID as env variables, as advised in the boto3 configuration docs, I can successfully make the requests. The trouble starts when I try introducing the Chalice Backend into this workflow. More details about the boto3 module: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iot-data.html.

I import the Helper Module to the backend, and when I call something like Helper.get_thing_shadow(...), it no longer works and I get an SSLError, with the following logs:

...
1666806563116 	Traceback (most recent call last):
1666806563116 	File "/var/task/urllib3/connectionpool.py", line 703, in urlopen
1666806563116 	httplib_response = self._make_request(
1666806563116 	File "/var/task/urllib3/connectionpool.py", line 386, in _make_request
1666806563116 	self._validate_conn(conn)
1666806563116 	File "/var/task/urllib3/connectionpool.py", line 1042, in _validate_conn
1666806563116 	conn.connect()
1666806563116 	File "/var/task/urllib3/connection.py", line 414, in connect
1666806563116 	self.sock = ssl_wrap_socket(
1666806563116 	File "/var/task/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
1666806563116 	ssl_sock = _ssl_wrap_socket_impl(
1666806563116 	File "/var/task/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
1666806563116 	return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
1666806563116 	File "/var/lang/lib/python3.9/ssl.py", line 501, in wrap_socket
1666806563116 	return self.sslsocket_class._create(
1666806563116 	File "/var/lang/lib/python3.9/ssl.py", line 1041, in _create
1666806563116 	self.do_handshake()
1666806563116 	File "/var/lang/lib/python3.9/ssl.py", line 1310, in do_handshake
1666806563116 	self._sslobj.do_handshake()
1666806563116 	ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)
...
1666806621896 	botocore.exceptions.SSLError: SSL validation failed for https://data.iot.<my-region>.amazonaws.com/things/<thing-name>/shadow [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

What is going wrong with the authentication here, and how can I complete this workflow? I would like to avoid having to provide my personal aws access tokens to provide authentication, the backend authenticates the initial request and I just want to post a request to the IoT Core service from the backend after that.

Thank you

1回答
1
承認された回答

Hi! The validation error is due to the data endpoint FQDN using the deprecated Symantec certificate. To resolve, you can provide the endpoint to use for the IoT Core data endpoint to your account specific one.

client = boto3.client('iot-data', region_name='eu-central-1', endpoint_url='https://xxxxxxxxxxxxxx-ats.iot.eu-central-1.amazonaws.com')

To remove the need for hard-coding the endpoint, you can use this snippet:

iot_client = boto3.client('iot', region_name=os.environ['AWS_REGION'])
endpoint_response = iot_client.describe_endpoint(endpointType='iot:Data-ATS')
endpoint_url = f"https://{endpoint_response['endpointAddress']}"
client = boto3.client('iot-data', region_name=os.environ['AWS_REGION'], endpoint_url=endpoint_url)

Credit to this Stack Overflow post.

Please let us know if this works!

AWS
Gavin_A
回答済み 2年前
profile pictureAWS
エキスパート
レビュー済み 2年前

ログインしていません。 ログイン 回答を投稿する。

優れた回答とは、質問に明確に答え、建設的なフィードバックを提供し、質問者の専門分野におけるスキルの向上を促すものです。

質問に答えるためのガイドライン