Linux 版 Azure VPN Client: DNS ドメインを設定できません
トンネルは上がるのに、Linux クライアントが DNS ドメインを設定できません。systemd-resolved を確認し、D-Bus 呼び出しを観察して、polkit アクションを修正します。
トンネルが上がり、証明書が検証されたあと、ダイアログが DNS サーバーまたはドメインを設定できなかったと告げます。Linux ではこのダイアログは通常ゲートウェイの話ではありません。クライアントは名前設定を D-Bus 経由で systemd-resolved に渡し、その受け渡しが拒否されるとインターフェースは上がったまま、名前解決は依然として古いリンクを指しています。同じノート PC はプロファイルにサフィックスが付く前は名前を正しく解決しており、これが追う価値のある手がかりです。ダイアログが現れた瞬間、トンネル側には何の変化もありませんでした。
サフィックスがなければ、クライアントはネームサーバーだけを送ります。検索ドメインを追加すると、二つ目の呼び出し SetLinkDomains が加わります。これには独自の認可チェックがあり、だからこそ同じプロファイルが Windows では動き、ここでは失敗します。ゲートウェイはどちらでも同じ設定を送っており、それを拒否しているのはローカルの部品です。
systemd-resolved が解決を担っていることを確認する
このクライアントは systemd-resolved とだけ話し、他の何とも話しません。Arch や他のいくつかのディストリビューションはこれを無効のまま出荷しており、/etc/resolv.conf はまったく別のリゾルバーのものかもしれません。だから権限を見る前に所有者を確定してください。
三つのコマンドで決着します。
systemctl status systemd-resolved
ls -l /etc/resolv.conf
resolvectl status
探すのは、稼働中のサービス、/run/systemd/resolve/stub-resolv.conf を指すシンボリックリンク、そして resolvectl のリンクごとの DNS です。代わりに NetworkManager が所有している場合は、クライアントと争うのではなく resolved に移してください。以下の drop-in は両方のキーを設定します。
[main]
dns=systemd-resolved
systemd-resolved=true
そのファイルができたら NetworkManager を一度再起動します。無効なリゾルバーと、その D-Bus 名を呼び続けるクライアントが揃うと、どちらの名前も出ないエラーになります。
失敗する D-Bus 呼び出しを観察する
この手順でダイアログは具体的な答えに変わります。一方の端末でリゾルバーのインターフェースを、もう一方でジャーナルを見てから、再接続します。
sudo dbus-monitor --system "interface='org.freedesktop.resolve1.Manager'"
journalctl -fu systemd-resolved
三つの呼び出しが現れるはずです。SetLinkDNS、SetLinkDomains と SetLinkDefaultRoute です。エラー応答として返るものが直すべき呼び出しです。その応答は通常理由を示します。たとえば org.freedesktop.DBus.Error.AccessDenied に対して SetLinkDomains です。どの呼び出しだったかを控えてください。次の節はその呼び出しを通す話です。
クライアントに必要な polkit アクションを与える
ルールを書く前にポリシーを読みます。サービスとして動くクライアントは対話的なプロンプトに答えられないため、暗黙の auth_admin_keep は行き止まりです。
pkaction --verbose --action-id org.freedesktop.resolve1.set-domains
pkaction --action-id org.freedesktop.resolve1.set-dns-servers --verbose
答えが auth_admin_keep なら、クライアントには明示的なルールが必要です。以下のスニペットは VPN クライアントが接続中に使う四つの resolve1 アクションを許可し、それ以外はすべて polkit.Result.NOT_HANDLED のままにします。
polkit.addRule(function(action, subject) {
var allowed = [
"org.freedesktop.resolve1.set-dns-servers",
"org.freedesktop.resolve1.set-domains",
"org.freedesktop.resolve1.set-default-route",
"org.freedesktop.resolve1.revert"
];
if (allowed.indexOf(action.id) !== -1 &&
subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
return polkit.Result.NOT_HANDLED;
});
これを /etc/polkit-1/rules.d/ に、後で見分けられるファイルとして置きます。たとえば 50-azurevpn.rules です。ログアウトして再ログインする前に、スニペット内のグループ名を自分のものに置き換えてください。狭く保ってください。すべてのアカウントにすべての resolve1 アクションを許可するのは、このクライアントが必要とする範囲より広く、後から監査するのがずっと難しくなります。
polkit を編集する前にプロファイルの XML を確認する
手で編集したプロファイルは何も言わずに無視されることがあります。Microsoft は 平坦なレイアウトを文書化しています。そこでは dnsserver の項目が dnsservers の直下にあり、サフィックスは dnssuffixes の直下にあります。各アドレスの周りに余分なラッパー要素があるとその形ではなくなり、クライアントはゲートウェイが送る内容へ静かに戻ります。
polkit に触る前に削除テストを行います。サフィックスのブロックを外して再接続し、ダイアログが変わるか見ます。変わるなら、失敗していた呼び出しはドメインの受け渡しであり、修正は認可であって別の XML 編集ではありません。
トンネルリンク上のドメインを検証する
再接続して resolvectl status をもう一度読み、トンネルリンクがネームサーバーと検索ドメインを併せて持っていることを確認します。公開名ではなく短いプライベート名を解決してください。名前は解決するのに背後のサービスが応答しない場合、DNS の受け渡しは成功しており、残る問題はルーティングです。
チケットに、リゾルバーの所有者、失敗した D-Bus 呼び出し、ルールファイル、プロファイルの版を書きます。その四行が、次の Linux ノート PC を繰り返しの調査ではなく短い修正に変えます。