WebサーバーがSSL接続を介してMySQLデータベースサーバーと通信できるようにしたい。 WebサーバーはCentOS5を実行し、データベースサーバーはFreeBSDを実行します。証明書は、中間CA DigiCertによって提供されます。
my.cnf
によると、MySQLはsslを使用する必要があります:
# The MySQL server
[mysqld]
port = 3306
socket = /tmp/mysql.sock
ssl
ssl-capath = /opt/mysql/pki/CA
ssl-cert = /opt/mysql/pki/server-cert.pem
ssl-key = /opt/mysql/pki/server-key.pem
MySQLを起動すると、エラーなしでデーモンが起動します。これは、証明書ファイルがすべて読み取り可能であることを示しています。
しかし、Webサーバーからデータベースサーバーに接続しようとすると、エラーが発生します。
[root@webserver ~]# mysql -h mysql.example.org -u user -p
ERROR 2026 (HY000): SSL connection error
そして、opensslでさらにデバッグしようとすると:
[root@webserver ~]# openssl s_client -connect mysql.example.org:3306 0>/dev/null
CONNECTED(00000003)
15706:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:588:
これは、MySQLデータベースサーバーへのSSL接続をテストする有効な方法ですか? SSL23_GET_SERVER_HELLO:unknown protocol
メッセージは奇妙です。これは、通常、非SSLトラフィック用のポートでSSLを話している場合に表示されるものだからです。
これと同じopensslコマンドは、LDAPサーバーとHTTPサーバーで正常に機能するようです。
$ openssl s_client -connect ldap.example.org:636 0>/dev/null
CONNECTED(00000003)
depth=2 /C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...
$ openssl s_client -connect www.example.org:443 0>/dev/null
CONNECTED(00000003)
depth=0 /DC=org/DC=example/OU=Services/CN=www.example.org
OpenSSLバージョン1.1.1(2018年9月11日にリリース)は、-starttls mysql
のサポートを commit a2d9cfbac5d87b03496d62079aef01c601193b58 に追加しました。残念ながら、OpenSSLの変更ログでこの新機能への参照を見つけることができません。
ディストリビューションにまだこのバージョンがない場合、静的にコンパイルされたopensslバイナリが https://testssl.sh/openssl-1.0.2k-dev-chacha.pm.ipv6.Linux+FreeBSD.tarにあります。 gz は-starttls mysql
をサポートしています。 http://www.danneman.org/presentations/Automating_TLS_Configuration_Verification.pdf で参照を見つけました。
Windowsの場合、OpenSSL 1.1.1バイナリは https://wiki.openssl.org/index.php/Binaries にあります。
https://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html の説明に従ってSSL証明書を生成し、試してみましたが、機能しました:
$ echo | bin/openssl.Linux.x86_64.static s_client -starttls mysql -connect spx-bionic.censored.com:3306 -CAfile /tmp/ca.pem
CONNECTED(00000003)
depth=1 C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = mysql test CA
verify return:1
depth=0 C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = spx-bionic.censored.com
verify return:1
---
Certificate chain
0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=spx-bionic.censored.com
i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
---
Server certificate
-----BEGIN CERTIFICATE-----
CENSORED
-----END CERTIFICATE-----
subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=spx-bionic.censored.com
issuer=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-521, 521 bits
---
SSL handshake has read 2599 bytes and written 632 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: AD25B7C3018E4715F262188D982AAE141A232712316E0A3292B0C14178E0F505
Session-ID-ctx:
Master-Key: C121967E8FAEC4D0E0157419000660434D415251B0281CCBFC6D7A2AE8B0CC63AEFE22B332E91D31424C1BF03E5AF319
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 82 db 03 0f c0 ce f2 26-62 bd 1b 18 71 03 88 db .......&b...q...
0010 - a6 66 7c 71 94 0c d5 ec-96 30 46 53 4a e6 cd 76 .f|q.....0FSJ..v
0020 - 66 b3 22 86 7d 9f 7e 2c-14 1d 66 f2 46 8f d2 d3 f.".}.~,..f.F...
0030 - f7 0a 0b f5 9e 05 97 e1-2b b3 ba 79 78 16 b8 59 ........+..yx..Y
0040 - dc c5 0d a8 de 0b 3a df-4b ec f9 73 3f 4c c3 f1 ......:.K..s?L..
0050 - 86 b6 f7 aa a7 92 84 77-9f 09 b2 cc 5d dd 35 41 .......w....].5A
0060 - 23 5d 77 74 e1 96 91 ac-28 81 aa 83 fe fc d2 3c #]wt....(......<
0070 - f9 23 09 6d 00 e0 da ef-48 69 92 48 54 61 69 e8 .#.m....Hi.HTai.
0080 - 30 0e 1f 49 7d 08 63 9e-91 70 fc 00 9f cd fe 51 0..I}.c..p.....Q
0090 - 66 33 61 24 42 8f c2 16-57 54 48 ec 6a 87 dc 50 f3a$B...WTH.j..P
Start Time: 1537350458
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
DONE
OpenSSL 1.1.1ではpostgresとldapも-starttls
サポートされています。完全なリストについては、 https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_client.c#L815-L831 を参照してください。
私自身の質問に答えます。良い信頼できる情報源でより良い回答がある場合は、回答を投稿してください。
短い答え;いいえ、MySQL SSL接続のデバッグにOpenSSLを使用することはできません。これは、MySQLがプレーンテキストを使用してセッションを開始し、後でSSLに切り替えるためです。
https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase.html を読み取ると、MySQLはプレーンテキスト接続で開始し、その後実際のSSLが開始されます。これは、MySQLがプレーンテキスト接続と暗号化接続の両方を1つのポート(ポート3306)でリッスンする方法を説明しています。これをHTTPまたはLDAPサーバーと比較してください。1つのポートはプレーンテキスト接続に使用され、2つ目のポートは暗号化接続に使用されます。
これは、ERRパケットを送信してハンドシェイクを終了するか、クライアントがハンドシェイク応答パケットで応答する初期ハンドシェイクパケットを送信するサーバーに接続するクライアントから始まります。この段階で、クライアントはSSL接続を要求できます。この場合、クライアントが認証応答を送信する前にSSL通信チャネルが確立されます。
この問題の一般的な原因は、CA証明書の共通名(CN)がサーバーまたはクライアント証明書、あるいはその両方と同じであることです。
ここを参照してください: https://dev.mysql.com/doc/refman/5.6/en/creating-ssl-certs.html
CAと証明書を再作成して、すべてのケースで一意のCNを使用するようにしてください。
Ubuntuサーバーと通信するMacOS Xクライアントで同様の問題が発生しています。
クライアント側の証明書とクライアントキーを省略して、サーバー証明書のCAがあるだけで接続が機能するかどうかを確認できますか?暗号化された接続を確立できますか?これには通常、関連するユーザーのssl_type列にANY設定が必要です。
MySQLとクライアントの間でロードバランサー(F5やHAProxyなど)を使用する場合は、SSL証明書をロードバランサーからMySQLサーバーにインポートする必要があることを後世に伝えたいだけです。これは、STARTTLSに似た接続の起動によるものです。