harumaki.net

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

GNU/Linux MySQL ssh メモ

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

投稿日:2013年9月27日

Last Updated on 2021年7月4日 by かんりにん

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

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

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

【1.ssh】

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

-参考:お世話になっております!
OpenSSH FAQ 2.11 – How do I use port forwarding?

ポイント

  • おもに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:

mysql> show tables;
+----------------------+
| Tables_in_testschema |
+----------------------+
| tbl_testschema       |
+----------------------+
1 row in set (0.03 sec)

→接続成功。

【2.ssl】

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

-参考:お世話になっております!
MySQL 5.1 リファレンスマニュアル 4.8.7.2. SSL接続
suz-lab – blog: MySQLに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環境設定

SSL証明書関連の保管先ディレクトリを作成。

mysql.dというディレクトリを作成。
# mkdir /etc/mysql.d
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

 

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 []:

 

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

 

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
MySQL の再起動を行う
# /etc/init.d/mysqld restart
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)

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

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

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;
クライアント側に証明書を作成

※SCPで転送してもOK。

$ mkdir mysql.d
$ cd mysql.d/
$ touch server-cert.pem
$ vi server-cert.pem
接続テスト
$ 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>

→ログインは成功。

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

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

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

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

no image

script​/標準入力の判定(case文)

[pukiwiki] ホスト名を標準入力にて引数として追加し、ホストグループを判定する勉強用スクリプト。 ホスト名の先頭にweb、db、app、mailがあった場合はホストグループとサーバールートを出 …

[MySQL]db接続エラーのメモ(max_connectionsメモ)

  割と初歩的なメモ。環境としては、OSはCentOS6.5、MySQLはRPM版5.5(Remi)です。 開発中のPHPのAppサーバーからdbサーバーへアクセスする際、コネクションエラーでアクセス …

[DB]FireBirdをインストールしてみた(RPM編)

[pukiwiki] FireBird2.5をVPSを利用して、CentOS6環境でささっといじってみました。 epelリポジトリで提供されているパッケージを使えたので、セットアップは楽でした (yu …

[メモ][juniper] SRX(JunOS) FTPS設定追加

  社内から外部のFTPサービスへ接続する際、通常のFTPでは問題ないものの、FTPS(FTP Over SSL/TLS)で接続しようとしたところ、認証が通ったところで応答がなくなり、そのままタイムア …

no image

ssh 公開鍵認証と公開鍵の登録

[pukiwiki]   **▼ssh 公開鍵認証と公開鍵の登録 [#q473bc7b] 作業自体は簡単なんですが ユーザー名やらいろいろこんがらがるので、メモを作成します。 ”【ローカル …

宅麺