トンネル上のクライアントはゲートウェイに到達でき、ゲートウェイは内部リゾルバーに到達できるので、DNS は動くはずです。動かないのは、それが二つの別の許可であり、動作する DNS サービスは三つ目の事柄だからです。リスナーはクライアントが到達できるアドレスに存在する必要があり、ファイアウォールはそのアドレスへのクエリを許可する必要があり、クライアントにはそれを使うよう伝える必要があります。トンネルを両方向に開くことは、最初の二つを偶然に解決し、三つ目を未完了のままにします。

リスナーは二つの向きを持つローカルサービスです

内向きでは、クライアントがゲートウェイのトンネルアドレスのポート 53 にクエリを送ります。外向きでは、デーモンがそのクエリを設定された上流へ転送します。両方の半分が動く必要があり、失敗の仕方も異なります。

クライアントが報告するタイムアウトとゲートウェイで見えるタイムアウトは同じ障害ではありません。

トンネルアドレスを束縛し、すべてのアドレスを束縛しない

この作業専用の dnsmasq インスタンスには、明示的な待ち受けアドレス、起動後にトンネルが現れることを許容するバインドモード、そして一つの明確な上流が必要です。これが私が使う最小の版です:

listen-address=127.0.0.1,10.90.0.1
bind-dynamic
no-resolv
no-hosts
server=192.168.50.53

bind-dynamic 個々のアドレスを束縛し、tun0 が後から現れる場合にも対処します(VPN サービスが再起動するホストではこれが重要です)。loopback を列挙すれば、公開リスナーを追加せずにローカルツールを動かし続けられます。no-resolv はデーモンがホストのリゾルバー設定から上流を継承するのを止め、no-hosts はこのインスタンスがゲートウェイの hosts ファイルを公開するのを防ぎます。これらのどのオプションも、誰かにサービスへのクエリを許可するものではありません。

二つ目のデーモンを起動する前に、ポート 53 に既存のリスナー がないか確認し、間違ったディレクトリの迷いファイルではなくディストリビューションの設定の所有者を使ってください。

DNS の入力を許可し、トンネルの通過は許可しない

これを機能させるファイアウォール規則は、トンネルインターフェース、クライアントプール、ゲートウェイアドレス、ポート 53 に限定されたローカル入力規則です。プロトコルごとに一つ、二つの規則で十分です:

sudo ufw allow in on tun0 proto udp from 10.90.0.0/24 to 10.90.0.1 port 53
sudo ufw allow in on tun0 proto tcp from 10.90.0.0/24 to 10.90.0.1 port 53

DNS は UDP だけでなく TCP でも動くので、UDP だけの規則では大きな応答が断続的に見える形で失敗します。これはufw route の許可ではなく、tun0 に対する広い許可になってはいけません。順序は内容と同じくらい重要です:tun0 からのすべての入力を落とす先行規則が依然として勝ち、最終的な破棄の下に許可を追加しても何も生まれません。

ゲートウェイ DNS が設計の一部になったのなら、その以前のポリシーを意図的に見直し、理由を記録してください。

上流側の半分は別の経路です

クエリはゲートウェイを自身のアドレスから上流リゾルバーへ出ていくので、ゲートウェイのルートとそのリゾルバーへの出力ポリシーがこのやり取りを許可する必要があります。これはクライアントをリスナーへ通す規則とは別の規則であり、別の症状で失敗します。

応答を動かすために無制限のトンネル出力を追加しないでください;追跡される応答には必要ありません。

オプションをプッシュし、その後ハンドオフを確認する

サーバーはプッシュされたオプションでリゾルバーをクライアントに通知できます。これはオプションであり、OS が従わなければならない指示ではありません:

push "dhcp-option DNS 10.90.0.1"

Linux のコマンドラインクライアントは接続マネージャーのリゾルバー統合を必要とすることがあり、管理対象デバイスは管理プロファイルの更新を必要とすることがあります。接続後にクライアントの有効なリゾルバーを確認し、プッシュが適用されたと決めつけないでください。二つの仕組みが同時に DNS を設定しようとすると、解決がちらつくように見える競合が生じます。

目標はクライアントのリゾルバー設定の所有者を一つにすることであり、プッシュがその所有者になるのは通常、クライアントプラットフォームが同意する場合だけです。

実際に構築したものをテストする

プライベートな完全修飾名を一つと、許可された外部名を一つ、UDP と TCP の両方でトンネルアドレスに対して直接問い合わせます。その後、アプリの通常の検索経路でも繰り返します。

直接のクエリが動くのにアプリが失敗するなら、障害はサーバーではなくハンドオフにあります:

  • クライアントはプッシュされたオプションを一度も適用していません。
  • 別のリゾルバーが後から設定され、競合に勝ちました。
  • アプリは独自のリゾルバーライブラリかキャッシュされた応答を使っています。

最後に、承認された VPN 経路の外にある送信元がリスナーをまったく使えないことを確認してください。解決の成功は返されたアドレスを許可するものではないので、この二つの問いは分けておいてください。

関連記事