dnsmasq はアドレスがすでに使用中というエラーで終了し、ログには犯人の代わりにポートが記されます。VPN も動かしているマシンでは、押し出されたルートを疑いがちですが、bind の失敗はどのクライアントもクエリを送る前に起きます。すでに何かがソケットを握っており、その正体を特定するのが作業です。ルートの変更でポートが空くことはありません。

順序は次の五段階です。エラーを再現し、リスナーを一覧し、ワイルドカードを理解し、担当を割り当て、最後に検証します。

手順 1: エラーを再現して読む

サービスが使っているのと同じ設定で dnsmasq を前面で起動すると、当て推量のログではなく端末にエラーが出ます。メッセージのアドレスファミリーとローカルアドレスに注目してください。特定アドレスへの bind とワイルドカードへの bind は、所有者の異なる別の失敗です。

正確な文言を残してください。アドレス使用中、権限の失敗、インターフェースの欠如は、いずれも起動失敗として現れ、それぞれ別の修理を指しています。

手順 2: 所有者を一覧する

まずソケットを一覧します。送信元ポート 53 での絞り込みは、見る権限があれば両方のトランスポートと所有プロセスを示します:

ss -lntup 'sport = :53'

出力は列で読みます。トランスポート、ローカルアドレス、ポート、プロセスです。TCP のリスナーと UDP のリスナーは別のソケットなので、片方を止めても他方は空きません。ワイルドカードアドレスはすべてのインターフェースを覆うため、どの行も名前を挙げていなくても VPN のアドレスはすでに使われています。プロセス名を見れば、ディストリビューション管理のリゾルバか、コンテナか、以前の実験が動かしっぱなしにしたものかが分かります。

手順 3: ワイルドカードの罠

bind-interfaces オプションは、dnsmasq がワイルドカードのソケットを bind するか、設定済みのインターフェースごとに一つのソケットを bind するかを変えます。これは dnsmasq のリファレンス が説明しているとおりです。これがないと、dnsmasq はワイルドカードを bind したうえで要求をインターフェースごとに絞り込むことがあり、別のデーモンがワイルドカードを握っていると即座に失敗します。Linux は bind-dynamic を追加し、起動後に作られたインターフェースを扱います。VPN のインターフェースが接続時にしか現れない場合、これは現実的な問題です。

だからこそ、別々のインターフェース向けに設定したように見える二つのデーモンが衝突します。衝突は意図ではなくソケットで起きています。bind の方式は意図して選び、変更する前に自分のバージョンの文書化された挙動を読んでください。

手順 4: 担当を割り当てる

どのデーモンが VPN クライアントに応答し、どれがホストに応答するかを決めます。トンネルのアドレスで待ち受け、上流へ転送する一つのリゾルバはよくある構成です。それぞれが 53 番ポートを所有していると仮定する二つのリゾルバは、構成とは言えません。

次に、その判断を各サービス自身の設定に表します。待ち受けアドレス、インターフェースの絞り込み、転送です。変更はサービスの所有者、つまりディストリビューションのユニット、ネットワークマネージャー、コンテナランタイムのいずれかを通して行い、再起動後も残るようにします。

手順 5: ソケットを検証し、次に経路を

再起動後、クライアントを試す前に意図したソケットがあることを確認します。一度も bind していないデーモンはルートでは救えませんし、正しく bind されたソケットに対するクライアントの失敗は、別の修正を要する別の問題です。そのうえで、トンネル上のクライアントからの到達性を確認します。必要な名前が解決するかを問うのは、その後のことです。

切り分けておくべき三つの結果があります。ソケットがあること、クライアントがそこへ届くこと、答えが正しいことです。

やってはいけないこと

何が依存しているか分からないまま、ポートを空けるために見慣れないリゾルバを止めないでください。ホスト自身の名前解決が通常それに依存しています。二つ目のデーモンを公開の待ち受けアドレスへ移す古いレシピを写さないでください。副作用として、誰があなたに問い合わせできるかを決めてしまいます。失敗がローカルだったのに転送を足さないでください。

マシンが管理下にあるなら、所有権の判断を次の管理者が見つけられる場所に記録します。イメージを再構築するたびにポートの衝突は戻ってきます。

関連記事