ホストエイリアス機能の活用

fitlet

こちらの Unix & Linux StackExchange の質問 で初めて知ったのですが、 glibc のリゾルバにはホストエイリアスの機能があり、 環境変数 HOSTALIASES で指定したファイルによって、 任意の FQDN に対するエイリアスを設定することができます。

ホストエイリアス機能はマニュアル hostname(7)gethostbyname(3) で説明されています。

たとえば次のような内容のテキストファイル $HOME/.hostaliases を作り、

g www.google.com

このパスを環境変数 HOSTALIASES に設定しておけば、 様々なプログラムで g だけで www.google.com を参照することができます。

$ export HOSTALIASES=$HOME/.hostaliases
$ getent hosts g
216.58.221.4 www.google.com
$ curl -v g
* Rebuilt URL to: g/
* Hostname was NOT found in DNS cache
*   Trying 216.58.221.4...
* Connected to g (216.58.221.4) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.38.0
> Host: g
> Accept: */*
> 
...

Google Chrome のようなデスクトップアプリケーションでも、 セッション開始時に HOSTALIASES 環境変数が正しく設定されていれば同様に使うことができます (設定のしかたについては後述)。

このホストエイリアス機能は /etc/hosts や DNS サーバなどでシステム全体に影響する設定をする必要がなく、 また管理者権限がなくても手軽に使えるので、なかなか便利だと思います。 またプロセス単位で使用の有無を切り替えられるので、 ソフトウェアのテストの場面でも有用でしょう。

注意点

setuid されたプログラムでは使えない

たとえば ping のようなプログラムでは残念ながら使えません。 ping は設定テストのためにうっかり使ってしまうことが多いので気をつけましょう。 なおリゾルバ関係のテストでは getent hosts を使うのが定石です。

$ getent hosts g
216.58.221.4 www.google.com

FQDN はエイリアス文字列に使えない

マニュアルにも書かれていますが エイリアス文字列に使えるのは gwork といった 1 つの単語のみです。 . を含む文字列については HOSTALIASES を参照してくれません。

例えば次のように設定しても www.example.comwww.google.com を参照することはできません。

www.example.com www.google.com

任意の FQDN をエイリアス文字列にできれば、ほとんど完全な /etc/hosts の代替となり非常に便利だったので、なかなか残念です。

IP アドレスはエイリアスできない (ことが多い)

次のような IPv4 アドレスに対するエイリアスは 環境によって動いたり動かなかったりします。

work 10.10.0.1

ホストエイリアスの処理は gethostbyname() の内部で行われており、 上記の例では 10.10.0.1. が FQDN としてそのまま libnss のリゾルバモジュールで処理されます。 たいていの場合これは最終的に DNS のクエリとなりますが、 BIND を含む大抵の DNS サーバではこのような FQDN に対しては NXDOMAIN を返します。

$ host -t a 10.10.0.1. 8.8.8.8 ← Google Public DNS に問い合わせる
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases: 

Host 10.10.0.1. not found: 3(NXDOMAIN)

しかしながら dnsmasq のような一部の DNS サーバは、 クエリ 10.10.0.1. に対しては A レコード 10.10.0.1 を返してくれます。 このような DNS サーバを使えば (NetworkManager では標準で dnsmasq が使われています)、 IPv4 アドレスに対するエイリアスを利用することができます。

$ host -t a 10.10.0.1. 127.0.1.1 ← dnsmasq に問い合わせる
Using domain server:
Name: 127.0.1.1
Address: 127.0.1.1#53
Aliases: 

10.10.0.1 has address 10.10.0.1

この制限は xip.io のようなサービスを利用することでも回避できます。 xip.io ドメインの下に任意の IPv4 アドレスに対応した FQDN が得られるので、 たとえば上記の例は次のように書くことができます。

work 10.10.0.1.xip.io

なお IPv6 アドレスについては、 残念ながらエイリアスを作る方法はありません。

nscd が動いてると使えない (こともある)

nscd が動いていると、リゾルバが HOSTALIASES ファイルを参照せずに結果を返してしまうことがあるそうです。

これはディストリビューションによって違うらしく、 このバグ報告 によれば SuSE Linux で問題になっているようです。 Debian/Ubuntu や RHEL/CentOS の glibc では問題ないそうです。

セッションごとの環境変数の設定

HOSTALIASES 環境変数をセッション開始時に設定するには、通常は $HOME/.bash_profile ないし $HOME/.profile といったシェルのスタートアップファイルに設定を書いておけばよいでしょう。 ディスプレイマネージャからのデスクトップセッションでも セッション開始スクリプトがこれらの設定を反映させてくれますし、 SSH などのリモートログインセッションでも当然使えます。

ただし Debian/Ubuntu においては /bin/sh に dash が使われているといったややこしい事情があるので、 セッションごとの環境変数の設定については pam_env の機能を利用して ~/.pam_environment に書いておくのがおすすめです。 Ubuntu Wiki の説明も参照してください。

LANG=ja_JP.UTF-8
HOSTALIASES=/home/yaegashi/.hostaliases

glibc 以外の場合

実はホストエイリアス機能は Linux の glibc 特有のものではなく BSD のマニュアル にも HOSTALIASES についての言及があります。

OS X のマニュアル にも同様に書かれているので使えそうなものですが、 実際に試してみると残念ながら動きませんでした。 OS X の環境はリゾルバなど libc のコア部分も大きく改変されているのでその影響かもしれません。 このことに気がついて Apple にバグ報告をした人 もいるようです。

OS X 以外の BSD については、 残念ながら自分は動く環境を持っていないので試せていません。

まとめ

glibc で使えるホストエイリアス機能について紹介しました。 いくつかの制約がありますが /etc/hosts の代替として一般ユーザでも便利に使うことができます。

BSD libc 由来の機能なので Linux 以外のシステムでも使える可能性がありますが、 OS X では残念ながら使用できませんでした。

2015/09/06 08:07:32 JST