ビジネスとIT活用に役立つブログBlog


SSL/TLSを使用してMySQLサーバへ暗号化接続する方法を検証してみた

この記事をシェアする:

ブラウザでSSLで暗号化されていないサイトへアクセスすると警告がでるようになるなど、ネットワーク通信の通信データにおけるセキュリティ意識が年々高まっていると感じます。

データベースにおいてもグローバルネットワークを通して通信する場合には十分な注意を払う必要があります。
今回はMySQLサーバへの接続にSSL/TLSを使用して暗号化接続を行う方法について検証した内容をご紹介したいと思います。

検証前の確認(暗号化された接続の有効化

検証前にMySQLサーバ側で暗号化された接続が有効化されている必要があります。 有効化の確認は以下のSQLで確認できます。

ValueがYESになっていれば有効です。

検証に使用した各種バージョンは以下の通りです。

  • MySQLサーバ MySQL 8.0.16
  • MySQLクライアント MariaDB 5.5 (CentOS7系のデフォルト)
  • MySQLクライアント MySQL 8.0.18
  • PHP 7.2

MySQLクライアントのTLS接続オプション

SSL/TLS接続を有効にするMySQLのオプションを確認していきましょう。

–ssl, –skip-ssl

SSL/TLSを使用してサーバに接続できるようになります。
MySQL5.6以下では–ssl-modeオプションがないので、代わりに–sslオプションを使用します。

Note
MySQL 8.0では、クライアント側オプション–sslは削除されました。クライアントプログラムの場合は、–ssl-modeを代わりに使用します。

注意しなければならないのは、この指定だけでは暗号化されていない接続が使用されるケースがあるという事です。 MySQL公式のドキュメントによると推奨されるオプションセットとして、サーバ側で少なくとも–ssl-certと–ssl-keyを、クライアント側では–ssl-caを使用するように記載されています。
詳細については公式のドキュメントを参照してください。

–ssl-mode

MySQL5.7で追加されたオプションです。
MySQLクライアントのバージョン5.7からはデフォルトのモードがPREFERREDでMySQLサーバでTLS接続が有効化されている場合は自動的に暗号化された接続になるようです。

mode 説明
DISABLED 暗号化されていない接続を確立します。
PREFERRED サーバが暗号化された接続をサポートしている場合は暗号化された接続を確立し、 暗号化された接続を確立できない場合は暗号化されていない接続にフォールバックします。 default
REQUIRED サーバーが暗号化された接続をサポートしている場合、暗号化された接続を確立します。 暗号化された接続を確立できない場合、接続の試行は失敗します。
VERIFY_CA REQUIREDに似ていますが、構成されたCA証明書に対してサーバー認証局(CA)証明書をさらに検証します。 有効な一致するCA証明書が見つからない場合、接続の試行は失敗します。
VERIFY_IDENTITY VERIFY_CAに似ていますが、クライアントがサーバーへの接続に使用するホスト名を、 サーバーがクライアントに送信する証明書のIDと照合してホスト名のID検証を追加で実行します。

–ssl-ca

PEM形式の認証局(CA)証明書ファイルのパス名。サーバー側では、このオプションは–sslを意味します。

–ssl-capath

PEM形式の信頼できるSSL認証局(CA)証明書ファイルを含むディレクトリのパス名。サーバー側では、このオプションは–sslを意味します。

–ssl-cipher

TLSv1.2までのTLSプロトコルを使用する接続の許容暗号化暗号リスト。
コロン区切りで複数指定する事が可能です。

e.g.

MySQL 8.0 リファレンスマニュアル

MySQLでTLS接続

2つのバージョンのMySQLクライアントでMySQLサーバに接続してみます。

接続が暗号化されているかは以下のSQLコマンドで確認できます。

Valueが空の場合は暗号化されていません。

他にもSTATUS又は\sコマンドでも確認が可能です。

SSLが Not in use の場合は暗号化されていません。

TLSオプションを明示的に指定しない場合(MariaDB 5.5)

Valueの中身が空なので暗号化されていません。

TLSオプションを明示的に指定する場合(MariaDB 5.5)

MariaDB 5.5では–ssl-modeがないので、–sslオプションを使用して接続します。

接続の暗号化が確認できました。

TLSオプションを明示的に指定しない場合(MySQL 8.0)

MySQLクライアントが8.0の場合は–ssl-modeのデフォルトがPREFERREDのため、明示的に指定しなくても接続が暗号化されています。

TLSオプションを明示的にDISABLEDで指定する場合(MySQL 8.0)

–ssl-modeオプションにDISABLEDを指定した場合も確認してみます。

暗号化せずに接続していることが分かります。

MySQLユーザに接続の暗号化を強制する場合にはCREATE USER句のSSL/TLSオプションを使用することで設定が可能です。 詳細については公式のドキュメントを参照してください。

MySQL 8.0 リファレンスマニュアル

TLSプロトコルと暗号の構成

サーバがサポートする暗号化アルゴリズム(Cipher)の確認は以下のSQLで確認ができます。

Ssl_cipher_listのValueの左から順にクライアントとサーバの両方で対応しているものが使用されます。

MySQL 8.0のクライアントでTLS接続した際にはSsl_cipherの値はDHE-RSA-AES128-SHAでした。試しに別の暗号化アルゴリズムに変えてみましょう。

現在のセッションTLSプロトコルと暗号を確認するには以下のSQLで確認します。

暗号化アルゴリズムが変わっている事が確認できます。

PHPアプリケーション(PDO)を使ったSSL/TLS接続

ここまでMySQLクライアントを使用して確認してきましたが、PHPアプリケーションからMySQLサーバへの接続を暗号する方法についても確認していきます。

PHP マニュアル

PDOのSSLサポート(オプション)にはMySQLクライアントでいう–ssl-mode(–ssl)がありません。PEM形式の認証局(CA)証明書ファイルが必要になりますので予め手元に用意しておきます。

MySQLサーバにDBaaSを使用されている場合は以下のURLより証明書を入手可能です。

PDOのコンストラクタにSSLオプションを明示的に有効化していないケース

実行結果

暗号化せずに接続していることが分かります。

PDOのコンストラクタにPDO::MYSQL_ATTR_SSL_CAを指定

PDOのコンストラクタ第四引数のオプションに \PDO::MYSQL_ATTR_SSL_CAを追加します。

実行結果

接続の暗号化が確認できました。

PDOのコンストラクタにPDO::MYSQL_ATTR_SSL_CIPHERを指定

PDOのコンストラクタ第四引数のオプションに\PDO::MYSQL_ATTR_SSL_CIPHERを追加します。

実行結果

暗号化アルゴリズムが変わっている事が確認できました。

まとめ

簡易的な検証ですがMySQLサーバへの暗号化接続方法について確認しました。

暗号化しない接続と比べると暗号化する処理が追加になる分MySQLサーバへの接続コストが高くなります。実際の運用に適応する場合は事前に動作検証を行ってからご検討ください。

The following two tabs change content below.
アーティス

アーティス

創造性を最大限に発揮するとともに、インターネットに代表されるITを活用し、みんなの生活が便利で、豊かで、楽しいものになるようなサービスやコンテンツを考え、創り出し提供しています。
この記事のカテゴリ:

SNSで最新の情報を
受け取ることができます!