【MariaDB/MySQL】外部接続の設定方法

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.6 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