名前解決の診断
目標
名前解決がどんな経路を通るのかを確認し、「digはできるのにアプリはできない」状況を自分で作ってみます。
なぜ重要なのか
アプリケーションはglibcのgetaddrinfo()を呼び出し、glibcは/etc/nsswitch.confのhosts:行の順序どおりに尋ねます(通常はfiles dnsで、つまり/etc/hostsが先です)。一方、digは、これらをすべて飛ばして、/etc/resolv.confのネームサーバーに直接尋ねます。2つのツールの答えが違えば、問題はDNSサーバーではなく、スタブリゾルバーの区間です。この事実1つが、「digはできるのに、なぜアプリはできないのか」という疑問を、数時間から数分に縮めてくれます。
ステップ
/root/dnsディレクトリで作業します。
/etc/resolv.confの最初のnameserverのアドレスを、/root/dns/nameserver.txtに書いてください。/etc/hostsに、10.99.0.10をapp.labhub.localと短い名前appの2つで登録してください。/etc/nsswitch.confのhosts:項目の値(コロンの後ろ全体)を、/root/dns/order.txtに書いてください。ファイルがなければunavailableです。- 同じ名前
app.labhub.localを、getentとdig +shortでそれぞれ尋ねた結果を、/root/dns/compare.txtに、次の2行で書いてください。digが何も答えなければnoneと書きます(プレースホルダーは結果です)。getent=<결과>dig=<결과 또는 none>
/etc/resolv.confの検索ドメインの一覧を、/root/dns/search.txtに、空白で区切って書いてください。なければnoneです。10.99.0.10を逆引きした結果の名前を、/root/dns/reverse.txtに書いてください。/etc/hostsにapi.labhub.localを2行で登録してください。10.99.0.21を先に、10.99.0.22をその後ろに。そして、getent hosts api.labhub.localが実際に返すIPを、/root/dns/first.txtに書いてください。/root/dns/resolve.sh <이름>を作ってください。解決に成功したら、次の2行を出力して終了コード0、失敗したらunresolvedを知らせて終了コード3です。引数がなければ、0以外のコードです(プレースホルダーは、名前とアドレスです)。name=<이름>ip=<주소>
参考
getent hosts 이름は、IP 정식이름 별칭...の形式で出力します(韓国語の語は、名前、正式名、エイリアスを意味するプレースホルダーです)。dig +short +time=2 +tries=1 이름で、短く尋ねられます(プレースホルダーは名前です)。- よくある間違い1: ステップ4で、digの結果が空だからといって、失敗と判断してはいけません。hostsにだけある名前は、DNSが知らないのが正常です。
- よくある間違い2: ステップ7で2行の順序を入れ替えると、結果が変わります。先に書かれた行が勝ちます。
リゾルバーのアドレスを確認する
/etc/resolv.confの最初のnameserverのアドレスを、/root/dns/nameserver.txtに書いてください。
/etc/resolv.confのnameserver行です。複数あれば、最初のものだけを書いてください。
hostsファイルに名前を登録する
/etc/hostsに、10.99.0.10をapp.labhub.localと短い名前appの2つで登録してください。
1行にIPの後ろに名前を複数書くと、すべてエイリアスになります。getentで確認してください。
ネームサービスの順序を確認する
/etc/nsswitch.confのhosts:項目の値(コロンの後ろ全体)を、/root/dns/order.txtに書いてください。ファイルがなければunavailableです。
/etc/nsswitch.confのhosts:行です。コロンの後ろの値だけを書いてください。
getentとdigを比較する
同じ名前app.labhub.localを、getentとdig +shortでそれぞれ尋ねた結果を、/root/dns/compare.txtに、次の2行で書いてください。digが何も答えなければnoneと書きます(プレースホルダーは結果です)。
getent=<결과>dig=<결과 또는 none>
同じ名前を2つのツールで尋ねてください。結果がなぜ違うのか考えてみてください。digが何も答えを受け取れなければ、noneと書きます。
検索ドメインを確認する
/etc/resolv.confの検索ドメインの一覧を、/root/dns/search.txtに、空白で区切って書いてください。なければnoneです。
resolv.confのsearch行です。なければnoneと書いてください。
逆引き
10.99.0.10を逆引きした結果の名前を、/root/dns/reverse.txtに書いてください。
getent hostsにIPを入れると、逆方向に動作します。
同じ名前が2行、どちらが勝つか
/etc/hostsにapi.labhub.localを2行で登録してください。10.99.0.21を先に、10.99.0.22をその後ろに。そして、getent hosts api.labhub.localが実際に返すIPを、/root/dns/first.txtに書いてください。
順序が結果を変えます。21を先に書いてください。
名前解決のヘルパーを作る
/root/dns/resolve.sh <이름>を作ってください。解決に成功したら、次の2行を出力して終了コード0、失敗したらunresolvedを知らせて終了コード3です。引数がなければ、0以外のコードです(プレースホルダーは、名前とアドレスです)。
name=<이름>ip=<주소>
成功したら名前とIPを出力して0、失敗したらunresolvedと終了コード3です。