MariaDB(MySQL)に外部接続する必要がありました。
色々失敗と得られる事があったので記載します。
目次
イントロダクション
この記事で得られる事
- MariaDBの外部接続方法がわかる。
環境
種類 | バージョン |
---|---|
OS | CentOS 6.5 |
apache | 2.4.29 |
MariaDB | 10.1.30 |
php | 7.2.2 |
ポート解放
MariaDBのポートを確認する
MariaDBが接続するときに使うポート番号を確認します。
デフォルトのままであれば、3306
ですので、飛ばしても構いません
mysql > show variables like 'port' +---------------+-------+ | Variable_name | Value | +---------------+-------+ | port | 3306 | +---------------+-------+
ファイアウォールにMariaDBポート用の設定を追加する
次に、ファイアウォール側の設定をします。
現状のままだと、MariaDBポートへのアクセスは許可されていません。
$ iptables -L --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination #省略 7 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh 8 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited #省略 Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
そのため、ファイアウォール側で接続を許可できるように設定を行います。
MariaDBポートの設定方法
他の記事でも書いたように、CentOSの場合はiptables
を使います。
設定の追加はiptables
で次ように実行します。
$ iptables -I INPUT 7 -m state --state NEW -p tcp --dport 3306 -j ACCEPT
デフォルトでは、全てのIPを許可しています。
特定のIPのみを制限する場合は、-s
オプションを使用して制限するIPを指定します。
尚、INPUT 7
は、Chain INPUTの7行目に差し込むと言う意味ですので、環境によって異なります。
必ず、REJECTの前に入れるのを忘れないでください。
理由はTipsに書きます。
iptablesの設定を更新
修正が終わったら、iptables
の設定を更新します。
$ service iptables save
$ service iptables restart
通信状態を確認
上記までで、MariaDBポートへの接続が可能になりました。
試しに、通信状態を確認します。
外部からの接続確認
外部から、ポートに接続するにはtelnet
を使用します。
次のコマンドで対象のアドレスとポートを指定すると、Connected to <接続したアドレス>
と言うメッセージが表示され接続された事を確認できます。
$ telnet <ipアドレス> 3306 Trying <ipアドレス>... Connected to <接続したアドレス>
サーバー側の通信状態
CentOSの場合、サーバー側で通信状態を確認するにはss
(7以降)、netstat
(6以前)の2種類あります。
今回対応するサーバーはCentOS6ですので、netstate
を使用します。
次のコマンド実行すると、MariaDBが通信出来ているか確認することが出来ます。
次のように、出力されていれば接続出来ています。
$ sudo netstat -tlpn | grep mysql tcp 0 0 :::3306 :::* LISTEN 7217/mysqld
もし、IPで制限している場合はその設定が反映されているかと思います。
MariaDB側の設定
ポートを解放しただけでは、MariaDBへの接続は出来ません。
次に、MariaDB側の設定について触れます。
MariaDBの環境設定
MariaDBのコンフファイルに、設定を追加します。
MariaDBで、外部からの接続を許可するには、bind-address
を指定します。
MySQL :: MySQL 8.0 Reference Manual :: 5.1.7 Server Command Options
cnfファイルに、bing-address
の指定箇所がありますので、コメントアウトするか次のように0.0.0.0
を指定してください。
[mysqld] #省略 bind-address = 0.0.0.0
指定後、MariaDBを再起動します。
ユーザー追加
次に、外部接続用のユーザーを追加します。
今回は、testuser
と言う名前にします。
mysql > grant all privileges on *.* to testuser@"%" identified by <password> with grant option;
追加すると次のようにユーザーが追加されます。
mysql > select user, host, password from mysql.user; +--------------+-----------+-------------------------------------------+ | user | host | password | +--------------+-----------+-------------------------------------------+ | testuser | % | <password> | +--------------+-----------+-------------------------------------------+
これで、外部から接続できるようになります。
接続確認
各種設定が正常に行われているか、試しにローカルPCから接続します。
私はローカルPCにMariaDBをインストールしていないのでクライアントツールから実施しました。
もし、コマンドから実行する場合は次のコマンドで実行します。
$ mysql -u testuser -p -h <ipアドレス>
Tips
作業自体は大した事なかったのですが、実はかなり手こずっています。
今回は、そのポイントを重点的に記載していきます。
クライアントツールで接続出来るのに外部接続出来ていない??
私は、MariaDBのクライアントツールにSequel Proを使っているのですが、外部接続対応する前から接続できていました。
そのため、最初は何が問題なのかさっぱりわかりませんでした。
原因
クライアントツールから接続する方法は、大きく2種類あります。
- 直接サーバのMariaDBポートに接続する。
- SSH等でサーバーに入り、localhostでMariaDBに接続する。
今までは、後者で接続していたのでサーバに入った状態で、localhost接続していたんですね…。
(今考えると、何のために<ユーザー名>@%
を指定していたのか?と言う話です。)
MariaDBのPortが開かない
MariaDBのポートを解放して、telnet
で接続して見たのですが繋がりませんでした。
次のコマンド、MariaDBのポート追加までは実施しました。
ファイヤウォール側も開いているようですが、どこに誤りがあったのかわかりませんでした。
$ iptables -I INPUT -m state --state NEW -p tcp --dport 3306 -j ACCEPT $ sudo netstat -tlpn | grep mysql tcp 0 0 :::3306 :::* LISTEN 30149/mysqld
原因
実は、この指定方法だとChain INPUT
の最後の行に追加されてしまいます。
そのため、実際にファイアウォールの状態を見ると次のようになります。
$ iptables -L --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination #省略 8 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited #省略 14 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECTは、ここまで指定してきたチェーンの設定は有効のままですが、以降に追加した設定は無効にする事ができます。
そのため、14番目に追加された設定は無効になっていたため接続できなかった事になります。
http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/rejecttarget.html