MySQL 5.7でSSL接続が有効になる条件

MySQL 5.7から、SSL接続が有効になっている場合、クライアントからSSL接続を行うと明示しなくても自動でSSL接続になる。

MySQLサーバがSSL接続が有効になるのは二通り。

  • my.cnfでSSL証明書読み込んだ場合
  • data directoryに規定の名前の有効なSSL証明書がある場合

my.cnfによる設定

https://dev.mysql.com/doc/refman/5.7/en/using-encrypted-connections.htmlによると、以下に引用する通り3つのオプションがあり、my.cnfでも[mysqld]セクションにssl-ca, ssl-cert, ssl-keyを設定できる。

On the server side, the --ssl option specifies that the server permits but does not require encrypted connections. This option is enabled by default.

These options on the server side identify the certificate and key files the server uses when permitting clients to establish encrypted connections:

  • --ssl-ca: The path name of the Certificate Authority (CA) certificate file. (--ssl-capath is similar but specifies the path name of a directory of CA certificate files.)
  • --ssl-cert: The path name of the server public key certificate file. This can be sent to the client and authenticated against the CA certificate that it has.
  • --ssl-key: The path name of the server private key file.

自動読み込み

data directoryに規定の名前の有効なSSL証明書がある場合は、MySQLが起動時に自動で読み込んでくれる。

If the server discovers valid certificate and key files named ca.pem, server-cert.pem, and server-key.pem in the data directory, it enables support for encrypted connections by clients.

ca.pem, server-cert.pem, server-key.pemmysql_ssl_rsa_setupというツールが自動で生成してくれる。

https://dev.mysql.com/doc/refman/5.7/en/mysql-ssl-rsa-setup.html

SSL接続が有効かどうかの確認

SSLが有効になっているかどうかはshow variablesで確認できる。

mysql> show variables like '%ssl%';
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| have_openssl  | YES                       |
| have_ssl      | YES                       |
略

またstatusで現在の自身の接続がSSLになっているかが確認できる。

$ read -sp password? MYSQL_PWD

# unix domain socket経由だと当然SSLは使えない
MYSQL_PWD=$MYSQL_PWD mysql -uroot -e 'status' | grep SSL
SSL:                    Not in use

# TCP経由だとSSLが使える
$ MYSQL_PWD=$MYSQL_PWD mysql -uroot --protocol tcp -e 'status' | grep SSL
SSL:                    Cipher in use is DHE-RSA-AES256-SHA

コネクションプーリングを利用しない場合はMySQLのSSL無効化したほうがいい

本題に入る。

SSL接続は接続コストが高く、CPU使用率が簡単に上がってしまう。

コネクションプーリングをしている場合、都度接続をするわけではないのでSSL接続時のCPU負荷は無視できる。SQL実行時にはSSLによる暗号化が行われるが、接続開始時ほどCPU負荷にはつながらない。

従来、PostgreSQLやOracleと違ってMySQLは接続コストが低いためフェイルオーバー時などに考慮すべき点が増えるくらいならコネクションプーリングを使用しないでいいという考えもあったので、その考えのままSSL接続してしまうと、DBサーバと接続元のAPサーバともにCPU負荷が上がってしまう。

CPU負荷の上昇をどうやって確認したか

SSL接続でどれくらいCPU負荷が上がるかについて一例をあげると、Fluentd(td-agent)でMySQLに大量のアプリケーションログを送ったとき、DBサーバのCPU負荷は4倍になっていた。 これを確認した方法を記載する。

perf recordでFluentdの負荷状況を取得した。

perf record -g -p td-agentのPID sleep 120

perf report -g -G --stdioで情報を表示する。そうすると負荷の上位にMySQLへのコネクションに関する処理があることがわかった。

5.87%     0.00%  thread.rb:70    mysql2.so                     [.] nogvl_connect
       |
       ---nogvl_connect
          |          
           --5.84%--mysql_real_connect
                     |          
                      --5.67%--sslconnect
                                |          
                                 --5.05%--yaSSL_connect
                                           |          
                                            --4.68%--yaSSL::sendClientKeyExchange
                                                      |          
                                                       --4.54%--yaSSL::ClientKeyExchange::build
                                                                 yaSSL::ClientDiffieHellmanPublic::build
                                                                 |          
                                                                 |--2.26%--TaoCrypt::DH::GeneratePublic
                                                                 |          |          
                                                                 |           --2.26%--TaoCrypt::a_exp_b_mod_c
                                                                 |                     |          
                                                                 |                      --2.26%--TaoCrypt::AbstractRing::Exponentiate
                                                                 |                                TaoCrypt::ModularArithmetic::SimultaneousExponentiate
                                                                 |                                |          
                                                                 |                                 --2.24%--TaoCrypt::AbstractGroup::SimultaneousMultiply
                                                                 |                                           |          
                                                                 |                                           |--1.69%--TaoCrypt::MontgomeryRepresentation::Square
                                                                 |                                           |          |          
                                                                 |                                           |          |--1.06%--TaoCrypt::MontgomeryReduce
                                                                 |                                           |          |          |          
                                                                 |                                           |          |           --0.53%--TaoCrypt::RecursiveMultiplyTop
                                                                 |                                           |          |          
                                                                 |                                           |           --0.63%--TaoCrypt::RecursiveSquare
                                                                 |                                           |          
                                                                 |                                            --0.52%--TaoCrypt::AbstractRing::MultiplicativeGroupT::Accumulate
                                                                 |                                                      TaoCrypt::MontgomeryRepresentation::Multiply
                                                                 |          
                                                                  --2.25%--TaoCrypt::DH::Agree
                                                                            |          
                                                                             --2.24%--TaoCrypt::a_exp_b_mod_c
                                                                                       TaoCrypt::AbstractRing::Exponentiate
                                                                                       |          
                                                                                        --2.24%--TaoCrypt::ModularArithmetic::SimultaneousExponentiate
                                                                                                  |          
                                                                                                   --2.21%--TaoCrypt::AbstractGroup::SimultaneousMultiply
                                                                                                             |          
                                                                                                             |--1.66%--TaoCrypt::MontgomeryRepresentation::Square
                                                                                                             |          |          
                                                                                                             |          |--1.08%--TaoCrypt::MontgomeryReduce
                                                                                                             |          |          |          
                                                                                                             |          |           --0.52%--TaoCrypt::RecursiveMultiplyTop
                                                                                                             |          |          
                                                                                                             |           --0.57%--TaoCrypt::RecursiveSquare
                                                                                                             |          
                                                                                                              --0.51%--TaoCrypt::AbstractRing::MultiplicativeGroupT::Accumulate
                                                                                                                        |          
                                                                                                                         --0.50%--TaoCrypt::MontgomeryRepresentation::Multiply

td-agent.confでSSL接続に関する設定を一つもしていないのでSSL接続をしている認識がなかったが、sslconnectという文字列が見えたため、MySQL 5.7以降の「SSL接続が有効になっている場合、クライアントからSSL接続を行うと明示しなくても自動でSSL接続になる」という仕様に気付いた。

MySQLのSSLを無効にした後、再度Fluentdに対してperf record, perf reportを実行したところ、SSL接続に関する処理はなくなり、Load AverageやMySQLのqps, tpsにも改善が見られた。