MySQLと名前解決
MySQLにおいて名前解決は、コネクションの確立・認証のフェーズで利用されます。デフォルト(名前解決が有効)な場合のシーケンスはざっくりと以下のようになります。
- IPアドレスがMySQL内の名前解決キャッシュに載っているかどうかを確認する
- (載っていない場合) IPアドレスからホスト名に逆引きをかける(getnameinfo)
- 得られたホスト名を正引きし、IPアドレスを得る(getaddrinfo)
- IPアドレスとホスト名の両方を使って、接続元ホストの検証をする(第17回 MySQLのユーザー管理について[その1]の2ページ目を参照)
- 検証に成功した場合、これ以降の「接続元ホスト」はIPアドレスまたはホスト名の「検証に成功したどちらか一方」を利用する
- ユーザー名、パスワードなどの認証に進む
名前解決が無効(skip-name-resolveオプションが有効)な場合、上記1、2、3のフェーズがスキップされ、4で検証される対象はIPアドレスのみとなります。
--skip-name-resolve
オプションはよく「DNSによる名前解決を無効化する」と説明されますが、実際に利用しているのはgetnameinfo
とgetaddrinfo
であるため、設定によって/etc/hosts
などDNS以外の名前解決も試みます(しかし、大半はやはりDNSによる名前解決になるでしょう)。
DNSの逆引き、正引き設定が適切にされていない場合、「MySQLに接続する際に時間がかかる、--skip-name-resolve
を設定したら速くなった」というのはこのためです。なお、このオプションはクライアントの名前解決の動作には影響を及ぼしません。サーバに--skip-name-resolve
が設定されていようといまいと、mysql -hmysql-hostname
とコマンドラインから名前を指定することは可能です(もちろん、クライアント側のOSでその名前が解決できる必要があります)。
名前解決を利用するメリット
MySQLの名前解決を有効にしておくメリットが享受できるのは、DNSの設定(あるいは、/etc/hosts
などその他の名前解決手段)が適切にされている場合のみです。そうでない場合はメリットを受けられないだけでなく、デメリットばかりが現れてくるため、おとなしく--skip-name-resolve
の設定をした方が良いでしょう。
名前解決が適切に設定されている場合、以下の2点のメリットを得ることができます。
ホスト名ワイルドカードの運用がしやすくなる
第21回 MySQLのユーザー管理について[その3] で説明した通り、MySQLのアカウント認証においてはホスト名に "%" ワイルドカードを利用することができます。
たとえばIPアドレス172.17.0.2、172.17.0.3、172.17.1.2からのアクセスのみを許可したい場合、mysql.user
テーブルに記録されている情報は以下の通りであるべきです。
172.17.0.2、172.17.0.3をまとめて"172.17.0.%"(さらには、3アカウントをまとめて"172.17.%")と設定することもできますが、その場合、意図しない172.17.0.11からのアクセスを認証で遮断することはできません。別途ファイアウォールの用意や、「172.17.0.0/24 セグメントにその他のサーバは存在しない」ことを保証する必要があります。
かといって、おそらく同じ権限を割り当てるであろうユーザーを、接続元を増やすたびに作成するのは、非効率なこともあるでしょう(特に、負荷に応じて動的にアプリケーションサーバを増減させている場合など)。そのような場合にDNSや/etc/hosts
を利用して名前解決をさせることで、ユーザー管理をシンプルにすることができる場合があります。
この設定をしたMySQLサーバに対して172.17.0.2からアクセスすると、以下のようになります。
名前解決を設定していない172.17.0.11からは当然アクセスできません。
/etc/hosts
などで172.17.0.11を"myapp10.localdomain"に紐づけてやることで、"myapp%.localdomain"にマッチするようになるため、172.17.0.11からもアクセスが可能になります。
ただし、名前解決のための/etc/hosts
の読み込みはMySQLの起動時にしか行われないため、/etc/hosts
の運用では毎回再起動が必要になってしまいます。名前解決を利用したアカウント運用は、既に逆引き用DNSが設置されていて自由に変更ができる環境でなければメリットを得ることは難しいでしょう。
名前解決の手段が適切にされていないアクセス元からの接続試行をエラーログに出力することができる
--skip-name-resolve
が有効になっていない環境では、エラーログに以下のようなワーニングが出力されることがあります。
これは冒頭で説明したステップの2. 「(載っていない場合)IPアドレスからホスト名に逆引きをかける(getnameinfo)」 に失敗した場合に出力されるワーニングです。実際にそのホストからの接続が認証されたのかされていないのかは関係ありません(mysql.user
テーブルにIPアドレス形式でアカウントが登録してあれば、このワーニングの有無に関わらず認証が行われます)。逆引きがきちんとメンテナンスされている環境であれば、このワーニングの多発から不正なアクセスを発見できるかも知れませんが、そうでない場合はあっという間にこのワーニングがエラーログを埋め尽くしてしまうでしょう。
まとめ
skip-name-resolveオプションはMySQLサーバ内の名前解決を無効化します。たまに聞く誤解ですが、このオプションはクライアントの名前解決動作には影響を及ぼしません。
名前解決を有効にしておくことで得られるメリットも多少ありますが、そのためにはあらかじめ名前解決のための基盤を整備しておく必要があります。このあたりに自信がない場合は、--skip-name-resolve
で名前解決を無効化しておく方が定石です。