プロファイルごとの検査で複数の vpnc トンネルを維持する
同梱の再接続スクリプトはトンネルが一つだけという前提です。各 vpnc プロファイルに専用ポートを与え、実際のサービスを検査し、検査を一つの固定順序で連鎖させます。
vpnc プロファイルが一つならローミング後もきれいに再接続しますが、三つあると交代で互いのソケット、ルート、リゾルバの状態を壊してしまいます。同梱の再接続スクリプトはトンネル一つを前提に書かれているため、どれか一つでも停止すると全プロファイルを再起動します。これを直すには、ローカルポートを分けること、プロファイルごとに実際のサービスを検査すること、二つの接続を同時に走らせない一つの順序付き連鎖という三つが必要です。
各プロファイルに専用のローカルポートを与える
既定のローカルポートに置いたままの vpnc プロファイルは、すでに動いているプロファイルと競合します。一つ目がポートを握っている間に二つ目の接続が失敗し、ログの行はローカルな衝突ではなくゲートウェイの問題のように見えます。代わりにプロファイルファイルごとに一行を設定してください:
Local Port 0ゼロにするとカーネルが一時ポートを選ぶため、二つのプロファイルを同時に確立できます。各ファイルは提供するゲートウェイとグループの名前にし、root だけが読めるように保ち、共有の既定ではなく必ず対応するプロファイルで接続する。共有の既定ファイルこそ、誰かがプロファイル名を変えた後にスクリプトが誤ったトンネルへ再接続する原因です。
プロファイルファイルは資格情報を含むため、権限は設計の一部であり、後片付けの話ではありません。/etc/vpnc 配下で誰でも読めるファイルは、グループの秘密をすべてのローカルユーザーに渡してしまいます。モードは 0600、所有者は root にして、秘密を引数にコピーするのではなく root としてファイルを読ませてください。検査スクリプトがファイルの内容を決してログに出さないべき理由もここにあります。
トンネルのアドレスではなく、プロファイルごとに一つのサービスを検査する
トンネル自身のアドレスへの echo 要求は、インターフェースが存在することくらいしか証明しません。その先のホストがトンネルを正当化するアプリケーションにまだ届くかは何も語りません。インターフェースは上がっていても、その先のルートがすでに消えていることがあります。
プロファイルごとに短い TCP タイムアウトで一つのサービスを検査し、検査に失敗したプロファイルだけを再接続します。二秒あれば死んだ経路と遅い経路を分けられ、TCP の検査は途中で ICMP が許可されているかどうかに依存しません。プロファイル間で変えるのは対象と設定名だけにします:
#!/bin/bash
set -eu
if ! nc -z -w 2 10.63.7.20 8443; then
/usr/sbin/vpnc-connect ops.conf
fiそれを /usr/local/bin/ensure-vpn-ops.sh として保存し、実行可能にして、検査の対象と設定名だけを変えて各プロファイルで繰り返します。プロトコルの問いに答える検査は、echo を捨てても利用者に必要なサービスは転送し続けるゲートウェイを越えて生き残ります。
検査を連鎖させて決して競合させない
同梱の再接続スクリプトは検査を順番に呼び出せますし、その順番こそが要点です。二つの vpnc-connect 呼び出しが同時に走ると、誰も制御できない順序でルーティングテーブルを書き換え、健全なプロファイルがルートを失うのはまさにこれが原因です。
呼び出しは前面のままにし、下位インターフェースのために短い落ち着き待ちを入れ、連鎖は root の cron テーブルから予約します:
#!/bin/bash
sleep 20
/usr/local/bin/ensure-vpn-ops.sh
/usr/local/bin/ensure-vpn-lab.sh起動スクリプトと cron エントリで順序を同一に保ってください。起動時に違う順序で走る連鎖は事実上別のプログラムであり、あるプロファイルが別のプロファイルのルートに依存する場合は、依存先を先に置き、前のトンネルがまだ立ち上がっている間に後の検査は無害に失敗させます。
ログを監視し、それから一つをわざと壊す
実行ごとにプロファイル、検査の対象、結果、取った対応を一行で記録します。これがなければ、毎分揺れるトンネルは一度も切れなかったものとまったく同じに見え、検査の不具合をゲートウェイの障害と区別できません。ログは連鎖が失敗したプロファイルだけに触れたことも証明します。再起動に耐える場所へ書き込んでください、さもなければ証拠はプロセスと共に消えます。
次にトンネルを意図的に壊し、何が起きるかを見ます。一つのプロファイルを止め、どのプロセスとルートがまだ残っているか確認します:
pgrep -a vpnc
ip -4 route show | grep -E '10[.]63|10[.]90'
tail -n 5 /var/log/ensure-vpn.log再接続されるのは止めたプロファイルだけであるべきで、他のセッションはプロセスもルートも保つべきです。二つのプロファイルが再起動するなら、連鎖は想定していないどこかで並行して走っています。
監視役がやってはいけないこと
何かが失敗するたびにすべてを再起動する監視役は、試験中は健全に見え、保守時間帯に障害を起こします。再起動はプロファイル単位で、決して全体では行いません。
同じプロトコルに対応する保守されたクライアントをゲートウェイが提供するならそちらを選び、プロファイルファイルがすでに秘密を保持しているので、スクリプトにパスワードを埋め込んだりコマンドラインで渡したりしないでください。トンネルが上がった後に一般ユーザーで動かす必要がある作業は、連鎖全体をそのアカウントで動かすのではなく、スクリプトの内側から権限を落とします。最後に、別の割り当てアドレスで戻って、トンネルのアドレスに向けた検査では決して気づけない古いルートを残すことがあるので、再接続後はルートを読み直してください。