Repository navigation
ssl.SSLError: [SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled (_ssl.c:1131) #2653
Copy link
Copy link
Closed
Description
Subject
Error on SSL Connection
Environment
OS Windows-10-10.0.19044-SP0
Python 3.8.12
urllib3 1.26.8
Steps to Reproduce
import os
import shutil
import datetime
import urllib3
# Different tools to download NOAA datas
class NOAA_Tools:
def __init__(self, race_name='TEST', north_coord=52, west_coord=-75, south_coord=10, east_coord=0):
self.race_name = race_name
# Convention: [N(positif), W(negatif), S(negatif), E(positif)]
self.north_coord = north_coord
self.west_coord = west_coord
self.east_coord = east_coord
self.south_coord = south_coord
self.area = [north_coord, west_coord, south_coord, east_coord]
# Download forecast wave moment from today 000 hour to +384 hour (+16 jours), 6 days before are available
def WW3_Wave_Moment(self, day, month, year, hour, archive_path='F:\\GRIBS\\NOAA\\WAVE_MOMENT\\'):
if os.path.isdir(archive_path) is False:
os.mkdir(archive_path)
now = datetime.datetime.now()
now_date = now.strftime('%d/%m/%Y')
if month < 10:
month = str(month)
month = month.zfill(2)
if day < 10:
day = str(day)
day = day.zfill(2)
forecast_date = str(day) + '/' + str(month) + '/' + str(year)
forecast_date_hour = str(day) + '/' + str(month) + '/' + str(year) + ' - ' + str(hour) + ':00:00'
if forecast_date == now_date:
now_date_hour = now_date + ' - ' + '00:00:00'
now_date_hour_timestamp = datetime.datetime.timestamp(datetime.datetime.strptime(now_date_hour, "%d/%m/%Y - %H:%M:%S"))
forecast_date_hour_timestamp = datetime.datetime.timestamp(datetime.datetime.strptime(forecast_date_hour, "%d/%m/%Y - %H:%M:%S"))
forecast_hour = forecast_date_hour_timestamp - now_date_hour_timestamp
else:
now_date_hour = now_date + ' - ' + '00:00:00'
now_date_obj = datetime.datetime.strptime(now_date_hour, "%d/%m/%Y - %H:%M:%S")
forecast_date_obj = datetime.datetime.strptime(forecast_date_hour, "%d/%m/%Y - %H:%M:%S")
if forecast_date_obj > now_date_obj:
forecast_date_hour_timestamp = datetime.datetime.timestamp(forecast_date_obj)
now_date_hour_timestamp = datetime.datetime.timestamp(now_date_obj)
forecast_hour = forecast_date_hour_timestamp - now_date_hour_timestamp
day = now_date_obj.day
if day < 10:
day = str(day)
day = day.zfill(2)
elif forecast_date_obj < now_date_obj:
start_date_hour = forecast_date+ ' - ' + '00:00:00'
start_date_hour_timestamp = datetime.datetime.timestamp(
datetime.datetime.strptime(start_date_hour, "%d/%m/%Y - %H:%M:%S"))
forecast_date_hour_timestamp = datetime.datetime.timestamp(
datetime.datetime.strptime(forecast_date_hour, "%d/%m/%Y - %H:%M:%S"))
forecast_hour = forecast_date_hour_timestamp - start_date_hour_timestamp
timer_tmp = int(forecast_hour / 3600)
if timer_tmp < 10:
timer = str(timer_tmp)
timer = timer.zfill(3)
elif timer_tmp > 10 & timer_tmp < 100:
timer = str(timer_tmp)
timer = timer.zfill(3)
url_base = 'https://nomads.ncep.noaa.gov/cgi-bin/filter_gfswave.pl?file=gfswave.t00z.global.0p16.'
url_time = 'f' + str(timer) + '.grib2&all_lev=on&all_var=on'
url_sub = '&subregion=&leftlon=' + str(self.west_coord) + '&rightlon=' + str(
self.east_coord) + '&toplat=' + str(self.north_coord) + '&bottomlat=' + str(self.south_coord)
url_end = '&dir=%2Fgfs.' + str(year) + str(month) + str(day) + '%2F00%2Fwave%2Fgridded'
url = url_base + url_time + url_sub + url_end
print('URL : ', url)
#filename = url.split('=')[1].split('&')[0]
outfile = url.split('=')[1].split('&')[0].split('.grib2')[0] + '_' + str(day) + str(month) + str(year) + '_' + str(hour) + '.grib2'
c = urllib3.PoolManager()
with c.request('GET', url, preload_content=False) as resp, open(outfile, 'wb') as out_file:
shutil.copyfileobj(resp, out_file)
resp.release_conn()
TEST = NOAA_Tools(race_name='WW3_Forecast', north_coord=52, west_coord=-75, south_coord=10, east_coord=0)
TEST.WW3_Wave_Moment(22, 6, 2022, 12, archive_path='./TMP/') # Download wave spectrum for 14 June 2022 at 12:00:00Expected Behavior
Actual Behavior
Traceback (most recent call last):
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 386, in _make_request
self._validate_conn(conn)
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 1040, in _validate_conn
conn.connect()
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connection.py", line 416, in connect
self.sock = ssl_wrap_socket(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\util\ssl_.py", line 449, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\util\ssl_.py", line 493, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Users\Seb\anaconda3\envs\routing\lib\ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "C:\Users\Seb\anaconda3\envs\routing\lib\ssl.py", line 1040, in _create
self.do_handshake()
File "C:\Users\Seb\anaconda3\envs\routing\lib\ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled (_ssl.c:1131)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/Seb/PycharmProjects/RTools/tmp.py", line 110, in <module>
TEST.WW3_Wave_Moment(22, 6, 2022, 12, archive_path='./TMP/') # Download wave spectrum for 14 June 2022 at 12:00:00
File "C:/Users/Seb/PycharmProjects/RTools/tmp.py", line 104, in WW3_Wave_Moment
with c.request('GET', url, preload_content=False) as resp, open(outfile, 'wb') as out_file:
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\request.py", line 74, in request
return self.request_encode_url(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\request.py", line 96, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\poolmanager.py", line 375, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 813, in urlopen
return self.urlopen(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 813, in urlopen
return self.urlopen(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 813, in urlopen
return self.urlopen(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\connectionpool.py", line 785, in urlopen
retries = retries.increment(
File "C:\Users\Seb\anaconda3\envs\routing\lib\site-packages\urllib3\util\retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='nomads.ncep.noaa.gov', port=443): Max retries exceeded with url: /cgi-bin/filter_gfswave.pl?file=gfswave.t00z.global.0p16.f012.grib2&all_lev=on&all_var=on&subregion=&leftlon=-75&rightlon=0&toplat=52&bottomlat=10&dir=%2Fgfs.20220622%2F00%2Fwave%2Fgridded (Caused by SSLError(SSLError(1, '[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled (_ssl.c:1131)')))
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
graingert commentedon Jun 23, 2022
see also python/cpython#93927
pquentin commentedon Jun 24, 2022
What is the output of
python -c 'import ssl; print(ssl.OPENSSL_VERSION)'? https://stackoverflow.com/a/71646353 suggests that this happens with OpenSSL 3.0 when connecting to legacy US government websites that disable renegotiation without signalling it correctly.To solve the issue, you need a custom SSL context (again the StackOverflow answers explains how to do it). Thanks to @graingert's in Python 3.12 you will be able to switch from
0x4tossl.OP_LEGACY_SERVER_CONNECT.sebfournier95 commentedon Jun 24, 2022
Thank you
python -c 'import ssl; print(ssl.OPENSSL_VERSION) = OpenSSL 3.0.3 3 May 2022
Do I need to pass in Python 3.12, I am under Python 3.9 ?
pquentin commentedon Jun 24, 2022
Python 3.12 will be released in October 2023, I just mentioned it for future readers. You can downgrade to OpenSSL 1.1.1 or use the following code:
sebfournier95 commentedon Jun 24, 2022
Thank you that works well.
Add support for legacy SSL negotiation
Add support for legacy SSL negotiation
Add support for legacy SSL negotiation
Fix UNSAFE_LEGACY_RENEGOTIATION_DISABLED, see urllib3/urllib3#2653
Fix UNSAFE_LEGACY_RENEGOTIATION_DISABLED, see urllib3/urllib3#2653
Fix UNSAFE_LEGACY_RENEGOTIATION_DISABLED, see urllib3/urllib3#2653
Update custom_ibge.py
Dhruv97Sharma commentedon Sep 25, 2023
Really worked wonders for my case where I modified the given approach to cater to my case where I needed this with the requests library:
This gave me required results! Thanks! Hope this helps someone!
Add support for legacy SSL negotiation
Add support for legacy SSL negotiation
Add support for legacy SSL negotiation
Add support for legacy SSL negotiation
AndreikaTallinn commentedon Oct 29, 2024
Thanks all! Both solutions (with pure urllib3 and with requests) work correctly with straight connection.
Unfortunately it does not work with proxied connection. None of the solutions work:
The non-working solution with pure urllib3:
` ctx = create_urllib3_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
ctx.options |= ssl.OP_LEGACY_SERVER_CONNECT
`
The non-working solution with requests:
`def get_legacy_ssl_session(self):
if self.ssl_session is None:
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
ctx.options |= ssl.OP_LEGACY_SERVER_CONNECT
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
session = requests.session()
session.mount('http://', CustomHttpAdapter(ctx))
session.mount('https://', CustomHttpAdapter(ctx))
self.ssl_session = session
self.ssl_session.proxies.update(self.proxies)
return self.ssl_session
both variants return SSL error: SSLError(SSLError(1, '[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled (_ssl.c:1000)')
If somebody has a solution, that is working with proxy, I will be very grateful!
Thanks in advance!
AndreikaTallinn commentedon Oct 29, 2024
sorry for the formatting. do not know why Github consider half of the code fragment as a plain text