エラーで停止する段階を備えた OpenVPN クライアントのプロビジョニング
五つの段階が、途中で止まったままのインストールを残さないようにします。入力の確認、セットの準備、アトミックな入れ替え、単一の所有者の有効化、廃止の計画です。
エラーを報告したまま処理を続けるプロビジョニングスクリプトは、決して実行されないスクリプトより悪いものです。クライアントの設定は、保護された鍵、ゲートウェイ上の ID、そしてすでにトラフィックを処理している可能性のあるサービスに触れます。それぞれに停止条件が必要であり、スクリプトは停止した時点でどの段階に達したかを知っている必要があります。
全体を五つのチェックポイントを持つ一つのトランザクションとして扱い、各チェックポイントが自力で続行を拒否するようにします。
ファイルシステムに触れる前に入力を修正する
明示的な契約から始めます。ID は一つ、プロファイルの供給元は一つ、想定されるサービスの所有者は一つです。プロファイルが存在すること、それが参照する証明書と鍵が読めること、対象ディレクトリが想定したパッケージのものであることを確認します。パスが解決できることは、その背後の素材が完全である証拠にはなりません。
空の変数は早い段階で拒否します。何にも展開されない未設定の $DEVICE は、install -m 400 $KEY /etc/openvpn/client/ をディレクトリに向けたコピーに変えてしまい、障害は後になって自分の鍵を読めないサービスとして現れます。
ステージングディレクトリでプロファイル一式を組み立てる
まず完全な一式を非公開の場所に構築します。プロファイル、CA、クライアント証明書、鍵、そしてプロファイルが呼び出すあらゆる補助です。install -m 400 -o root -g root でコピーし、権限を後からではなく作成時に設定します。次にプロファイル内の参照を確認します。相対的な ca や key の行は、サービスが起動した時点でユニットの作業ディレクトリを基準に解決されるからです。一式全体が検証されるまで、稼働中のディレクトリには何も書き込むべきではありません。
この実行が生成したものの非秘密の指紋を記録します。たとえばバージョン標識の隣に保存した sha256sum office.conf です。この単一の値があるからこそ、再実行は更新と何もしないことを区別できます。
アトミックに入れ替え、直前の一式を保持する
ファイルシステムが許す場所では、準備した一式を一回の操作で所定の位置へ移動し、レビュー済みの直前の一式をタイムスタンプ付きの名前で保持します。古い鍵の隣に新しいプロファイルを残す部分的なコピーは、誤った ID で認証し、理由について何も有用な記録を残さないサービスを生みます。入れ替えをアトミックにできない場合は、プロファイルが最後に着地するように移動順を決めます。
対象がすでに存在する場合、この実行が更新なのか、同一の再実行なのか、別の端末のプロファイルとの衝突なのかを明示的に判断します。別の ID に属するプロファイルを黙って上書きすることは、二台のマシンが一つの証明書を共有してしまう道です。代わりに実行を拒否し、衝突する所有者を名指しします。
単一の所有者を有効化し、それを証明する
有効化の経路を一つ選びます。systemd のインスタンスか NetworkManager のどちらかで、一貫して使います。有効化されたユニットの隣で管理外の openvpn プロセスを起動すると、トンネルが二本になり、DNS 更新が競合し、停止コマンドがどちらを対象とするのか明確な答えが得られません。有効化の後は systemctl is-active openvpn-client@office を確認し、次にリモートプレフィックスへの経路、次にトンネルが導入したリゾルバについて resolvectl status を確認します。トンネルが存在する理由である一つのリソースに到達して終えます。
動作中のプロセスと緑のトレイアイコンはプロセスの事実であり、ID とトラフィックポリシーが引き継ぎを生き延びた証拠ではありません。
再実行と廃止は別々のワークフロー
二度目の実行は、同じレビュー済みファイルと同じ所有者に収束すべきであり、二つ目のアカウントや二つ目のデーモンを作るべきではありません。廃止はそれ自体の手順です。正確な所有者を停止し、ポリシーに従ってローカルプロファイルを保管または削除し、ゲートウェイで ID を取り消します。ローカルの鍵ファイルを削除しても、すでにマシンを離れたコピーは取り消されません。
コンソールアクセスや二つ目の管理経路など、トンネルに依存しない復旧経路を保ちます。マシンから閉め出してしまうプロビジョニングの変更は、どの段階も成功を報告していても失敗した変更です。
残す価値のあるスクリプトは、所有権と証拠をめぐるトランザクションです。特権的なコピーコマンドの短い一覧は同じものではありません。