2013 年 8 月 28 日

MacOS 10.7,10.8でhostsファイルが無効になる

2978-logo

2013年5月ぐらいまでは、hostsファイルでの名前解決ができていたのに、突然利かなくなるという現象にであった。
去年の5月ぐらいに10.7にアップデートしてから、10.7.5になっていたが、特に何かしたわけでもなく、特別なアプリをインストールしたわけでもなかった。

通常使うには不便はないが、Webアプリの開発時に、まだ非公開のホスト名をhostsに登録して、仮想ホストで開発環境を構築しているので、これができないのは痛い。
MacのWebサイトのクリエイターも、概ねこんな環境で作業しているであろうから、困っている方もいるのではないだろうか。

5月から、いくつかのソフトウェアアップデートがあったので、その中のいずれかの影響があったのではないかと疑っている。
これはバグなのか仕様なのか、謎ではあったが、試しに、10.8(2013年秋にMavericksが発表されるのに、今頃ようやく)にアップデートしてみたが、同じだった。結局、DNSサーバをMacbookにインストールし、hostsファイルを有効にすることで解決したが、腑に落ちない現象である。

色々な情報

当然、色々情報をさがしてみたが、10.7,10.8でhostsファイルの編集方法や、hostsファイルの書き方により、hostsファイルが有効にならない、名前解決が遅いという現象があるようだ。

たとえば、hostsファイルの改行にCR+LFがあると認識されないや、IPV6のエントリがないと名前解決が遅いといったもの、一つのIPアドレスに複数のホスト名をつけると認識されないといったものである。
他には、ルートユーザーを有効にすれば、解決したといったものもあった。

DNSサーバを導入

私の現象で一番納得がいったのは、この記事だった。結局、仕様なのかバグなのか解決しないが、今現在(2013年8月末)、解消しないということは仕様なのかもしれない。

macの/etc/resolv.confは自動生成されるので、そもそも、名前解決方法の優先順位も設定できないのである(最初からだっけ?)。私の感触では、一切hostsファイルを見に行っていないような気がする。

確かにちょっとした知識で、他人のMacの名前解決を変更できるとしたら、簡単に悪意のあるサーバへ誘導できてしまう(当然、パスワードが必要だが)。

あきらめて、DNSサーバをインストールすることにして、上記記事のDNSMasqをインストールしてみることにした。
MacPortsでさくっと入るだろうと思ったら、またつまずいた…

とりあえず、MacPortsを最新にしておこうと、以下のコマンドをたたいてみた。

$ sudo port selfupdate
Password:
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.1.1 installed,
MacPorts base version 2.2.0 downloaded.
--->  Updating the ports tree
--->  MacPorts base is outdated, installing new version 2.2.0
Installing new MacPorts release in /opt/local as root:admin; permissions 0755; Tcl-Package in /Library/Tcl

Error: /opt/local/bin/port: port selfupdate failed: Error installing new MacPorts base: command execution failed

なんだこれは…とあきらめかけたが、こんな記事を発見した。

私のところとは現象は違うのだが、試しにやってみたら、あっさり動いた。

そして、あっさりDNSMasqもインストールできた。

sudo port install dnsmasq

さて、さきほどの記事には、この後どうすればいいのかまで、詳しく書かれていなかったので、追記しておく。

macのDNSサーバをローカルホストに変更したら、記事にもあるように、/etc/resolv.confを/etc/resolv.dnsmasq.confへコピーして、/etc/dnsmasq.confの中から/etc/resolv.dnsmasq.confを参照するように変更し、/etc/resolv.dnsmasq.confには以下のように名前解決の順序を設定しておく。

order file, bind
nameserver xxx.xxx.xxx.xxx (今までのDNSサーバ)

この後、設定を有効にするには、dnsmasqを再起動する必要がある。記事には、DNSMasqを再起動する方法がわからないとあったので、signalを送ってみた。signalを送ってやると再起動、設定の再読み込みしているようだ。

再起動

$ sudo kill -9 dnsmasqのプロセスID

設定の再読み込み

$ sudo kill -HUP dnsmasqのプロセスID

プロセスIDの取得

$ ps -e | grep dnsmasq

これで、今まで通り、hostsファイルをつかってホスト名を解決することができるようになった。

参考にさせていただいた記事の著者の方に感謝いたします。