トンネルが張られている状態で予備のターミナルを閉じただけで、クライアント側でキーを一度も押していないのに VPN が落ちる。Linux 版 AnyConnect クライアントでは、報告される原因はルーティングではなくセッションの計上である。クライアントはトンネル確立時に存在していたログインセッションを記録し、そのいずれかの終了をトンネルを切り落とす理由として扱う。以下の確認は順番に実行するもので、最初に失敗した項目が、そもそもこの挙動なのかどうかを教えてくれる。クライアントの通常の出力にはターミナルへの言及が一切ないため、最初の直感であるコンセントレータのせいにするという判断は、たいてい無駄な努力になる。

システムファイルの編集から始めてはいけない。各手順は切断を説明するか候補を消すかのどちらかであり、負担の軽い手順を先に行う。

セッション由来の切断と下位ネットワークの切断を分ける

切断直後に再接続する。数秒で戻り、同じネットワークで、新しい資格情報も要求されないトンネルは、死んだアップリンクや Wi-Fi ローミングや コンセントレータ側のアイドルタイムアウトではなく、閉じられたセッションのようなローカルの引き金を示している。Connecting のまま止まるトンネルや、ネットワークを変えるまで失敗し続けるトンネルは別の記事の話だ。

トンネルが上がった時点で何が開いていたかを書き出す。クライアントを起動したターミナル、二つ目のシェル、グラフィカルログイン、別マシンからの SSH セッションである。この一覧はすぐ必要になるし、次の切断の後に記憶から再構成するのは当てにならない。

クライアントが接続時に何を記録したかを確認する

クライアントはプロセスの親もターミナルの所有権も見ていない。接続時に存在したログインセッションの集合をスナップショットし、後でその集合を比較する。メンバーが消えれば比較が失敗し、トンネルも一緒に落ちる。だから接続元のウィンドウを閉じても無害なのに、無関係な予備ターミナルを閉じると接続が死ぬことがある。重要なのはそのセッションが元の集合に含まれていたかどうかだ。判定は個数ではなく集合の比較なので、セッションの入れ替えも一つの消失と同じくらい致命的になりうる。

何かを変える前に、クライアントから見えていたものを列挙する。

who
w
last -n 10
sudo ls -l /run/utmp

who の各行は utmp 内のユーザープロセス項目である。セッションが二回、つまりグラフィカルログイン用とターミナル用に現れるなら、両方の項目が接続時に存在しており、どちらも候補になる。

utmp から自分の項目だけを外す

公開されている回避策は、これから使うセッションをクライアント起動前に utmp 内で見えなくする。小さな C プログラムが getutent() を走査し、ut_line が標準入力の TTY と等しいレコードを見つけて、そのレコードを書き換える。順序は意図的だ。setutent()、項目を読み、ut_id をコピーし、ut_type を DEAD_PROCESS に設定し、ユーザーと行のフィールドを消し、pututline() で書き戻し、最後に endutent() を呼ぶ。

コンパイルしてから、クライアントを起動するシェルで root として実行する。

sudo ./utmpremove && /opt/cisco/anyconnect/bin/vpn -s connect vpn.example.edu

このツールが何もしていないという報告の多くは、二つの失敗の型で説明できる。標準入力に結び付いた TTY に対して動作するため、端末のないスクリプトや cron ジョブから実行すると照合する対象が残らない。そして /run/utmp は一般ユーザーには書き込みできず、root 以外での実行は終了ステータスを確認しない限り黙って失敗する。

閉じた後もトンネルが残ることを確認する

仕組みを仮定せず検証する。残すつもりのセッションから接続し、二つ目のターミナルを開いて閉じ、そのうえで vpn state とインターフェース一覧でトンネルがまだ上がっていることを確認する。生き残れば、引き金はすべてのセッションではなく特定の種類のセッションであり、開いたままにすべきセッションが見つかったことになる。

それでも落ちるなら、監視されているセッションは別の場所、多くの場合はターミナルを生んだグラフィカルログインにあり、TTY 項目を一つ外しても効果はない。さらなる手術を加えるのではなく、最初の手順の完全な一覧で観察をやり直す。

utmp の書き換えが誤った答えになる場合

utmp は共有の計上であり、私的なテーブルではない。生きているセッションの項目を書き換えると、who や w や一部の監査ツールがそのセッションを過少に報告し、後で同じ項目を閉じるプログラムは完全に失敗することがある。ツールは自分のセッションに限定し、元のファイルのコピーを残し、すべてのレコードを消す起動サービスにしてはいけない。

組織がコンプライアンスのためにセッション計上を収集している場合、この回避策はその要件と衝突する。サポートされる答えは別のクライアント版か別のアクセス方法であり、修正パッチを当てた utmp ではない。ほとんどの人にとって最も侵襲の少ない修正は、一日中開いたままにするセッションからクライアントを起動し、そのウィンドウに触れないことだ。

チケットを閉じる前に、トンネルが上がった時点でクライアントがどのセッションを監視していたかを記録する。その一行が、不可解な切断を次にそのマシンを触る人にとって再現可能な条件に変える。

関連記事