インターフェースは起動しているのに wg-quick が失敗したときの対処
失敗したユニットは中途半端なトンネルを残すことがあります。最初に失敗した手順を読み、掃除するか修復するかを決め、最後に要求で証明します。
ユニットは赤いのにインターフェースは存在し、トンネルもおおむね動いている——これが最も混乱する組み合わせである。設定は順序であり、まずインターフェースが作られ、次にアドレス、ルート、リゾルバの設定、任意のフックコマンドが続く。四番目の手順で失敗すると最初の三つは残るので、インターフェース名は起動が始まった証拠であって、完了した証拠ではない。余分な事実が一つあれば混乱は避けられたはずだ——失敗した手順である。
部分的な状態こそ通常の失敗
その挙動は破損とみなすのではなく、想定すべきものだ。インターフェースは設定の中で最も安価な部分であり、最も残しやすく、しかもマシンを半分動いているように見せる部分でもある。
まだ存在しないのは、失敗した手順より後に来るものすべてである。 失敗がリゾルバの段階だったなら、アドレスとルートはあり DNS はない。ルートだったなら、 トンネルにはアドレスがあり、そこを通る経路はない。
結果は、いくつかの試験には答え、別の試験では失敗するマシンであり、だから人々はサービスが点滅していると結論するが、実際には一度も正常に起動していない。完了しなかったサービスは点滅できない。同じ理由で繰り返し失敗できるだけである。
最初に失敗した手順を探す
現在の状態だけでなくユニットのジャーナルを読み、失敗した実行の先頭から読む。最後の行が終了コードを教え、最初のエラーが何を修復すべきかを教える。
次のコマンドはユニットの状態、そのユニットの起動ジャーナル、トンネルの現在の状態を表示する:
systemctl status wg-quick@wg0
journalctl -u wg-quick@wg0 -b --no-pager | tail -40
wg show
ip -4 addr show dev wg0リゾルバのエラー、すでに存在するルート、非ゼロで終了したフック、設定の解析失敗はどれもその画面に現れ、それぞれが自分の構成要素を名指しする。インターフェースの状態だけから推測することは、その情報すべてを無視している。
修復を決める三つの条件
掃除するのか、その場で修復するのか、ユニットを起動経路から外すのかを決め、何かを入力する前に決める。
インターフェースが壊れていて設定が正しいなら掃除してやり直し、設定が誤っているならそれを直して、それでも先に掃除する。部分的な状態の上で二つ目の管理プログラムを起動すると、一つのインターフェースに二人の所有者ができるからだ。失敗が、マシンにないリゾルバ補助のような欠けたシステム構成要素なら、ユニットを文句を言わなくなるまで編集するのではなく、依存関係を意図的に導入するか削除する。
この三つの場合は、謎の赤いユニットに見えるものの大半を覆う。見分ける問いは、同じ失敗がきれいな状態のマシンでも起きるかどうかであり、答えはたいてい最初のエラー行から来る。
再試行の前に掃除する
既存の状態の上での再試行は新しい理由で失敗し、元の理由を隠すことがある。インターフェースを作ったのと同じ道具でそれを下げ、そのあと何も残っていないことを確認する。
無関係なインターフェースを削除してはならず、ホストのネットワークスタックを初期化してもいけない。どちらも小さな対象を直すための大きな行為であり、失敗した一つのトンネルを、他の接続を作り直す必要があるマシンに変えてしまう。正しい範囲は一つのインターフェースと、それを所有するユニットである。それより広い範囲には、実行する前に書かれた理由が必要だ。
証明するのはトンネルであり、ユニットではない
緑のユニットは、起動の順序がゼロで終わったことを意味する。パケットが向こう側に届いたことや、リゾルバが意図どおりに設定されたことを意味しない。
トンネルを通して要求を送り、それを生んだ状態を読む:
systemctl is-active wg-quick@wg0
wg show wg0 latest-handshakes
ping -c 3 10.63.0.1
resolvectl query internal.example.net応答のないハンドシェイクでも、トンネルが形成され向こう側が静かであることは分かるので、これは一度も起動しなかったユニットとは別の問題である。ユニットの状態、ハンドシェイク、要求の結果を一つの記録に保つのは、これらが独立に失敗し、組み合わせだけがシステムを説明するからだ。