harumaki.net

インフラ屋の覚書や、ラーメン食べある記とか。

mysql sshトンネリングでの暗号化接続をさくっと試す

   


リモートホストのMySQLサーバーへアクセスする際に、クライアント – サーバー間の通信を暗号化する方法をかるく検証。
(MySQLのDBスキーマやテーブルの暗号化ではない)

方法としてはベタな感じだけど、手っ取り早く以下の2パターンで。

  1. sshでトンネリングした状態でmysqlへ接続
  2. SSLでmysqlへのセッションから暗号化する

【1.ssh】

sshでのポートフォワーディングによるmysqlのコネクション暗号化

ポイント

  • おもにssh接続の設定作業なるので、接続先のDBサーバー側は原則として設定変更しなくてもOK
  • ローカル側でトンネリング用のsshを立ち上げることになるので、バックグラウンドで実行する
    オプション("-f")をつけること。

テストで使用した設定

  • 接続元ホスト
     IP 192.168.254.32
     sshポート 22
     DBサーバーへの接続用sshポート 23306(→DBサーバーの3306番へアクセスする)
  • 接続先DBサーバー
    IP		192.168.254.64
    ログインユーザー	user
    sshポート	22
    mysqlポート	3306

1)トンネリング設定

接続元ホスト側で接続先DBサーバーのポートフォワーディングを設定

$ ssh -f -N -L 23306:localhost:3306 user@192.168.254.64 -p 22
  • [オプション解説]
     -f バックグラウンドで実行
     -N リモート・ホストでのコマンドを許可しない。※ポート転送をするときに指定すること。
     -L ローカル側のポート転送機能を利用する
  • [ポート解説]
    ローカルホスト(接続元)の23306へアクセス→DBサーバーの3306番へアクセス
    トンネリング先となるDBサーバーのsshのポートとして、22番を指定

実行後、プロセスとポートを確認。

$ ps -aef | grep "ssh -f" | grep -v grep
user    8650     1  0 13:14 ?        00:00:00 ssh -f -N -C -L 23306:localhost:3306 user@192.168.254.64 -p 22
$
$ netstat -ln | grep 23306
tcp        0      0 127.0.0.1:23306             0.0.0.0:*                   LISTEN
tcp        0      0 ::1:23306                   :::*                        LISTEN

2)接続確認

ローカルホストの23306番を指定し、DBサーバーへ接続。

$ mysql -u testschema_user -p testschema -h 127.0.0.1 --port=23306
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.1.69-log Source distribution

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
	
mysql> show tables;
+----------------------+
| Tables_in_testschema |
+----------------------+
| tbl_testschema       |
+----------------------+
1 row in set (0.03 sec)

→接続成功。

【2.ssl】

sslの鍵交換による暗号化をささっと。

ポイント

  • SSLの認証が発生するので、クライアント側に秘密鍵、DBサーバー側に証明書が必要。
    またピアノード間で使用するCAが必要。

テストで使用した設定

CA		ca-cert.pem
秘密鍵		server-key.pem
証明書		server-cert.pem

1)mysqlの状態を確認

mysql> SHOW VARIABLES LIKE '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |	←ここ
| have_ssl      | DISABLED |	←ここ
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+
7 rows in set (0.00 sec)

SSL接続が有効になっていないことを確認。

2)SSL環境設定

  1. SSL証明書関連の保管先ディレクトリを作成。
    ひとまずmysql.dというディレクトリを作成。

    # mkdir /etc/mysql.d
  2. CA のキーを生成
    # openssl req -new -x509 -nodes -days 365 -key ca-key.pem -out ca-cert.pem
    	---
    	Country Name (2 letter code) [XX]:JP
    	State or Province Name (full name) []:Tokyo
    	Locality Name (eg, city) [Default City]:dokokano-Ku
    	Organization Name (eg, company) [Default Company Ltd]:hogehoge
    	Organizational Unit Name (eg, section) []:system
    	Common Name (eg, your name or your server's hostname) []:localhost.localdomain
    	Email Address []:webmaster@example.com
  3. MySQL サーバーの秘密鍵と CSR の作成
    # openssl req -newkey rsa:2048 -days 365 -nodes -keyout server-key.pem -out server-req.pem
    	-----
    	Country Name (2 letter code) [XX]:JP
    	State or Province Name (full name) []:Tokyo
    	Locality Name (eg, city) [Default City]:dokokano-Ku
    	Organization Name (eg, company) [Default Company Ltd]:hogehoge
    	Organizational Unit Name (eg, section) []:system
    	Common Name (eg, your name or your server's hostname) []:localhost.localdomain
    	Email Address []:webmaster@example.com
    	
    	Please enter the following 'extra' attributes
    	to be sent with your certificate request
    	A challenge password []:
    	An optional company name []:
  4. MySQL サーバーの証明書作成
    	# openssl x509 -req -in server-req.pem -days 365 -CA ca-cert.pem -CAkey ca-key.pem -out server-cert.pem -set_serial 01
    	Signature ok
    	subject=/C=JP/ST=Tokyo/L=dokokano-Ku/O=hogehoge/OU=system/CN=localhost.localdomain/emailAddress=webmaster@example.com
    	Getting CA Private Key
  5. my.cnf へ設定追加
    # cp -p my.cnf my.cnf.20130927
    # vi my.cnf
    • 設定内容
      	[mysqld]
      	# SSL configuration
      	ssl-ca=/etc/mysql.d/ca-cert.pem
      	ssl-cert=/etc/mysql.d/server-cert.pem
      	ssl-key=/etc/mysql.d/server-key.pem
  6. MySQL の再起動を行う
    # /etc/init.d/mysqld restart
  7. SSL設定の適用を確認
    mysql> SHOW VARIABLES LIKE ‘%ssl%’;

    	+---------------+------------------------------+
    	| Variable_name | Value                        |
    	+---------------+------------------------------+
    	| have_openssl  | YES                          |
    	| have_ssl      | YES                          |
    	| ssl_ca        | /etc/mysql.d/ca-cert.pem     |
    	| ssl_capath    |                              |
    	| ssl_cert      | /etc/mysql.d/server-cert.pem |
    	| ssl_cipher    |                              |
    	| ssl_key       | /etc/mysql.d/server-key.pem  |
    	+---------------+------------------------------+
    	7 rows in set (0.01 sec)

3)クライアント側からの設定(ローカル)

GRANT実行時にオプション"REQUIRE SSL"をつける。

	mysql> GRANT ALL PRIVILEGES ON testschema.* TO testuser@localhost IDENTIFIED BY 'PASSWORD' REQUIRE SSL;
	mysql> flush privileges;

接続テスト

	# mysql -h localhost -u testuser --ssl-ca=/etc/mysql.d/server-cert.pem -p testschema
	Enter password:
	Welcome to the MySQL monitor.  Commands end with ; or \g.
	
	mysql>

→ログインは成功。

SSLの接続状態を確認
 mysql> show status like’Ssl_cipher’;

	+---------------+--------------------+
	| Variable_name | Value              |
	+---------------+--------------------+
	| Ssl_cipher    | DHE-RSA-AES256-SHA |
	+---------------+--------------------+
	1 row in set (0.00 sec)
	

mysql>

4)クライアント側からの設定(リモート)

サーバー証明書をリモートホストに転送してから、同様に接続を行うこと。

  1. DBサーバー側にリモートホスト(クライアント)からの接続用アカウントを作成
    クライアントのIPは192.168.254.32。

    	mysql> GRANT ALL PRIVILEGES ON *.* TO testuser@192.168.254.32 IDENTIFIED BY 'PASSWORD' REQUIRE SSL;
    	mysql> flush privileges;
  2. クライアント側に証明書を作成
    ※SCPで転送してもOK。

    	$ mkdir mysql.d
    	$ cd mysql.d/
    	$ touch server-cert.pem
    	$ vi server-cert.pem
  3. 接続テスト
    	$ mysql -h 192.168.254.64 -u testuser --ssl-ca=server-cert.pem -p testschema
    	Enter password:
    	Welcome to the MySQL monitor.  Commands end with ; or \g.
    	
    	mysql> 

    →ログインは成功。

  4. SSLの接続状態を確認
    	mysql> show status like'Ssl_cipher';
    	+---------------+--------------------+
    	| Variable_name | Value              |
    	+---------------+--------------------+
    	| Ssl_cipher    | DHE-RSA-AES256-SHA |
    	+---------------+--------------------+
    	1 row in set (0.03 sec)
    	
    	mysql>

あとはローカル、リモートでそれぞれ暗号化通信を確認できればOK。
今回はこんな感じで。

 

OpenSSH[実践]入門 Software Design plus
技術評論社 (2014-11-05)
売り上げランキング: 42,575

 

実用SSH 第2版―セキュアシェル徹底活用ガイド
Daniel J. Barrett Richard E. Silverman Robert G. Byrnes
オライリー・ジャパン
売り上げランキング: 198,635

 

 - GNU/Linux, MySQL, ssh, メモ ,