如何解决AWS Glue Job中的TLSv1协议版本SSL错误?
问题背景
在AWS Glue Shell(Python 3.9)环境下调用API端点时,触发如下SSL错误:
SSLError: HTTPSConnectionPool(host='', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:1129)'))) in AWS Glue Job
完整错误栈:
raise SSLError(e, request=request) requests.exceptions.SSLError: HTTPSConnectionPool(host='<host>', port=443): Max retries exceeded with url: /<suffix> (Caused by SSLError(SSLError(1, '[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:1129)'))) During handling of the above exception, another exception occurred: Traceback (most recent call last):
调用API的核心代码:
class GlueJob: def __init__(self, geo_url, eoae_geo_key): self.geo_url = geo_url self.eoae_geo_key = eoae_geo_key def get_geo_data(self, activity_id: str): payload = json.dumps({ "key": self.eoae_geo_key, "activity": activity_id }) headers = { 'Content-Type': 'application/json' } response = requests.post(self.geo_url, headers=headers, data=payload, verify=False) return response.json()
环境配置:
AWS Glue Shell Python Version: 3.9 Job参数配置: --python-modules-installer-option: "psycopg2-binary,geopandas,apache-sedona,geoalchemy2,sqlalchemy,tqdm,ipython,urllib3==1.26.16,requests==2.26.0" --python-modules-installer-option: "--upgrade"
解决方案
该错误源于当前环境使用的TLS协议版本不被目标API兼容(API要求TLS 1.2/1.3,而默认请求启用了过时的TLSv1),可通过以下方式修复:
1. 升级requests与urllib3版本
你当前指定的requests==2.26.0和urllib3==1.26.16版本较旧,对高版本TLS的支持有限。修改Job参数中的包配置:
--python-modules-installer-option: "psycopg2-binary,geopandas,apache-sedona,geoalchemy2,sqlalchemy,tqdm,ipython,urllib3>=2.0.0,requests>=2.31.0"
确保版本兼容Python 3.9与AWS Glue环境,且支持TLS 1.2及以上协议。
2. 强制请求使用高版本TLS
若升级包后问题仍存在,可在代码中自定义SSL上下文,禁用过时的TLS版本:
import ssl import json import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager class TLSAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): ctx = ssl.create_default_context() ctx.set_ciphers('DEFAULT@SECLEVEL=1') # 禁用TLSv1、TLSv1.1、SSLv3 ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_SSLv3 kwargs['ssl_context'] = ctx return super(TLSAdapter, self).init_poolmanager(*args, **kwargs) class GlueJob: def __init__(self, geo_url, eoae_geo_key): self.geo_url = geo_url self.eoae_geo_key = eoae_geo_key def get_geo_data(self, activity_id: str): payload = json.dumps({ "key": self.eoae_geo_key, "activity": activity_id }) headers = { 'Content-Type': 'application/json' } # 创建会话并挂载自定义适配器 session = requests.Session() session.mount('https://', TLSAdapter()) response = session.post(self.geo_url, headers=headers, data=payload, verify=False) return response.json()
这段代码会强制请求使用TLS 1.2或更高版本,匹配API的安全要求。
3. 确认Glue运行时版本
确保作业使用Glue 4.0运行时(对应Python 3.9),该版本底层OpenSSL版本更高,对新TLS协议的原生支持更完善。
4. 核对API的TLS要求
确认目标API支持的TLS版本(通常为TLS 1.2或1.3),确保上述配置与API要求一致。
内容的提问来源于stack exchange,提问作者watcharapon weeraborirak

