Я застрял с ошибкой ssl!?
Обновился с 19.10 до 20.04 и получил следующую ошибку:
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1108)
Она вызывается скриптом python, вызывающим API отдыха на oanda.com.
Подключение к службе с помощью Postman или Java-приложения OANDA работает без сбоев. Кроме того, пусть скрипт python работает на RPi в порядке, после одного изменения, см. Ниже!
20.04 - OpenSSL 1.1.1f 31 марта 2020 г.
RPi - OpenSSL 1.1.1d 10 сен 2019 г.
Проблема была также в RPi, и в ходе исследования было обнаружено несколько предложений по изменению параметра CipherString = ПО УМОЛЧАНИЮ @ SECLEVEL = 2
до CipherString = DEFAULT @ SECLEVEL = 1
в файле /etc/ssl/openssl.cnf
. Это работало на RPi, но не работало на Ubuntu 20.04.
Есть идеи, как решить эту проблему?
Отчет об ошибке:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 665, in urlopen
httplib_response = self._make_request(
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 376, in _make_request
self._validate_conn(conn)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 996, in _validate_conn
conn.connect()
File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 352, in connect
self.sock = ssl_wrap_socket(
File "/usr/lib/python3/dist-packages/urllib3/util/ssl_.py", line 370, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "/usr/lib/python3.8/ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "/usr/lib/python3.8/ssl.py", line 1040, in _create
self.do_handshake()
File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1108)
Я столкнулся с этой ошибкой после обновления с 18.04 LTS до 20.04 LTS при попытке подключения к серверу Exchange. Причина в том, что настройки Debian OpenSSL восходящей ветки по умолчанию стали более безопасными. В OpenSSL для CipherString
теперь установлено значение DEFAULT@SECLEVEL=2
. Предпосылки/обоснование этого изменения подробно описаны здесь: https://weakdh.org/
В идеале следует повысить безопасность сервера, а не реализовывать этот обходной путь на клиенте. Однако во многих случаях это будет невозможно.
Мне удалось обойти это, настроив шифры, используемые для соединения, создав SSLContext. Вот пример кода (для соединения SMTPS - отправка электронной почты):
connection = smtplib.SMTP(
config['Email']['host'] + ':' + config['Email']['port'])
context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# Either of the following context settings worked for me - choose one
# context.set_ciphers('HIGH:!DH:!aNULL')
context.set_ciphers('DEFAULT@SECLEVEL=1')
connection.starttls(context=context)
connection.login(config['Email']['user'], config['Email']['pw'])
connection.sendmail(config['Email']['sender'], recipients, msg.as_string())
connection.close()
Важные строки следующие - выберите одну из этих настроек CipherString
:
context.set_ciphers('HIGH:!DH:!aNULL')
context.set_ciphers('DEFAULT@SECLEVEL=1')
НО предпочитаю исправление сервера, если вообще возможно!
Чтобы адаптировать приведенное выше для urllib3, см. этот ответ:
Как выбрать конкретный шифр при отправке запроса через модуль запроса Python
Мне удалось заставить мой проект работать после того, как я понизил уровень безопасности SSL, как указано в этом посте.
Ubuntu 20.04 - как установить более низкий уровень безопасности SSL?