本記事の対象読者
- 下記のエラーに悩んでいる人
2026 (HY000): SSL connection error: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
問題
アプリをDocker環境で立ち上げ、その中から外部のMySQL(今回の場合、Amazon Aurora)に接続しようとしたときに上記のエラーが発生しました。
ベースとなるDockerイメージによってエラーが出たり出なかったりするのです。。
今回、python環境をDockerで作成する必要があったため、python3.7.4の公式イメージから作成しました。
アプリケーションの内容に深くは言及しませんが、pandasを使用した処理を行うものです。
mysql.connectorを使用して接続を試みています。
エラーが発生するDocker(Debianベース)↓
FROM python:3.7.4-slim
RUN apt-get -y update && apt-get install -y --no-install-recommends \
apt-utils \
python-dev \
build-essential \
libpq-dev
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
エラーが発生しないDocker(Alpineベース)↓
FROM python:3.7.4-alpine3.10
RUN apk --update-cache add \
bash \
gcc \
g++ \
gfortran \
postgresql-dev \
openblas-dev \
freetype-dev
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
接続部分のpythonコード↓
# 一部抜粋
import mysql.connector as my
myconfig = {
'user': 'user',
'password': 'your_password',
'host': 'your_host',
'database' : 'your_db',
}
conn = my.connect(**myconfig)
目的
Alpineベースだと、build時にnumpy, pandas等のC系のbuildでかなりの時間がかかるので、DebianベースのDockerイメージにしたかった。
原因と解決策
MySQL 5.6/5.7の場合、対応しているTLSバージョンはTLSv1.1までなようです。
[2] Changes in MySQL Connector/Python 8.0.18 (2019-10-14, General Availability)
Debianでは、opensslのデフォルト設定がTLSv1.2となっており、接続時にエラーが発生していました。
解決策は二パターンあります。
- MySQLのバージョンを変更
こちらの方が根本的に解決しそうですが、事情があり実施できませんでした。 - Debianのデフォルト設定を変更
Dockerfileに以下の記述を加えてbuildすると、設定値を変更することができます。
ただし、バージョンを下げることは、将来的なセキュリティ観点であまり望ましくはないでしょう。
FROM python:3.7.4-slim
RUN apt-get -y update && apt-get install -y --no-install-recommends \
apt-utils \
python-dev \
build-essential \
libpq-dev
# 変更点
RUN apt-get update -yqq \
&& apt-get install -y --no-install-recommends openssl \
&& sed -i 's,^\(MinProtocol[ ]*=\).*,\1'TLSv1.0',g' /etc/ssl/openssl.cnf \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
調査内容
DebianのTLSデフォルト設定について
[1] Debian openssl-1.1.1
PythonのMySQL Connectorのアップデート情報
[2] Changes in MySQL Connector/Python 8.0.18 (2019-10-14, General Availability)
エラー内容の調査・設定値の変更方法
[3] SSL routines:ssl_choose_client_version:unsupported protocol
Alpineでなぜエラーが発生しないのかはわかりませんでした。
etc/ssl/openssl.cnfの中にTLSのデフォルト設定のような記載は見当たらず。。。
プロトコルの勉強をしろ、と言われそうですが、デフォルト設定がなければ良しなにTLSバージョンを選定して接続してくれる、ということ、、、、、?
もし原因がわかる方がいらっしゃれば、ご教授いただきたいです。