WireGuard がインターフェースを作成できない:カーネルか権限か
ピアとのハンドシェイクが始まる前に、インターフェースの作成が失敗する。エラーを読み、欠けているモジュールなのか、権限の境界なのか、既存のインターフェース所有者なのかを見分ける。
WireGuard がインターフェースを作成できないと、設定するデバイスも、交換する鍵も、デバッグするハンドシェイクも存在しない。失敗は完全にローカルマシン側にあり、エラーの文面はローカルのスタックのどの部分が拒否したのかを語っている。これを正しく読むほうが、ピアの設定を入れ直すより速い。層は分離でき、メッセージは拒否した層を名指ししている。
エラーはどのピアも話す前に起きる
インターフェースの作成は、wireguard という種類のデバイスを求める、カーネルへの netlink リクエスト一回分である。カーネルにその種類を理解するドライバがあってもなくても、答えはすぐに返る。この段階ではパケットがマシンの外へ出ないので、エンドポイントのアドレスやサーバーの鍵が原因にはなり得ない。
この順序は診断上重要である。コマンドがデバイスを一度も作っていないなら、原因は誤った公開鍵でも遮断された UDP ポートでもない。まずローカル側の作成経路を直し、そのあとで初めて外側を見る。
どの実装がデバイスを所有すべきか
そのリクエストに答えられる実装は二つある。カーネル内のモジュールは wireguard というデバイス種別を登録し、wireguard-go のようなユーザー空間の実装は別の仕組みで同じインターフェースを提供する。モジュールが無い場合、カーネルは未対応デバイスのエラーでリクエストを拒否し、対処はモジュールを読み込むか、ツールをユーザー空間の実装に向けるかのどちらかになる。
どちらを選ぶ前に、実際に何が存在するかを確認する。一つ目のコマンドはモジュールが読み込まれているかを示し、二つ目はカーネルに直接問い合わせる:
lsmod | grep wireguard
ip link add wgtest0 type wireguard
二つ目のコマンドは可能な限り最小の再現であり、デバイスだけを求め、それ以外は何も求めない。未対応の種類というメッセージで失敗するなら、欠けているのは実装であって、あなたの設定ファイルではない。
| Error text | What refused | Next step |
|---|---|---|
| Unknown device type or operation not supported | The kernel has no wireguard driver | Load the module or use the userspace implementation |
| Operation not permitted | Missing privilege | Use the service context or grant the capability |
| File exists | The name is already in use | Inspect the owner before touching it |
| No such device in a container | No tunnel device or capability | Add the device and NET_ADMIN to the container |
権限とコンテナの境界
ネットワークデバイスの作成と設定には、root としてか、ネットワーク管理のケーパビリティを持つかのどちらかの権限が要る。通常のユーザーセッションではできず、この制約は設計そのものであって、確認していないインストーラーを走らせて回避すべき障害ではない。
コンテナの中では境界が二重になる。コンテナにはトンネルデバイスへのアクセスと、それを設定するケーパビリティが必要で、それを与えるフラグは Linux の VPN コンテナが使うものと同じである。通常どおりウェブを見られる制限付きのゲストでも、閲覧にはそのケーパビリティが要らないため、インターフェースは作れない。ケーパビリティはそれを必要とするサービスに与え、ホスト上のすべてのセッションに与えてはならない。
名前の衝突を解消してから再試行する
すでに存在するインターフェースが自動的に残骸とは限らない。別の管理ツールがその名前を所有して今まさに使っているかもしれないため、何かを削除する前に調べる:
ip link show wg0
sudo wg show wg0
所有者が稼働中のサービスなら、二つ目のデバイスを作るのではなく、そのサービスを設定する。本当に古いものなら、それを作成したツールで削除し、そのうえで文書化されたクライアントやユニットでインターフェースを起動し、設定とデバイスを一致させる。
作成が成功したら、次の失敗はより後ろの段階に属する、デバイスが存在した後に失敗を報告するユニットは、一度も作られなかったデバイスとは別の問題である。権限を変える前に、まずこの二つを切り分ける。