イメージが起動し、サービスが始まり、クライアントが接続する。そこで一度立ち止まり、いま起きたのが二つのまったく異なる操作のどちらなのかを問うべきだ。コピーが以前から存在した一つの論理ゲートウェイを復元しているのか、それとも艦隊に二つ目のゲートウェイを加えているのか。どちらも正当であり、身元とアクセスへの影響は異なる。きれいに起動したという事実は、どちらをも証明しない。

答えを決めるのは三つの条件であり、それはイメージが運びうる三つの材料のバケツである。イメージを構築する前に仕分けせよ。二度配備した後ではない。

まず、二つの操作のどちらを行っているのかを決める

復元は一つのサービス身元を保つ。古いインスタンスは消え、名前と証明書は残り、クライアントは同じエンドポイントを信頼し続ける。追加は二つ目の身元を作り、クライアント、ログ、失効のすべてがそれを見分けなければならない。

この区別は見た目の問題ではない。二つの稼働ホストが同じゲートウェイ証明書を提示すれば、クライアントはそれらを見分けられず、監査証跡も見分けられず、その証明書を失効させれば両方が一度に消える。意図的な高可用性設計が望むのはまさにそれかもしれないが、慌てたイメージコピーが意図することはほとんどない。

したがって最初の判断は一文であり、イメージがビルドホストを離れる前に書き留める。このコピーはゲートウェイAを復元するのか、それともこのコピーはゲートウェイBになるのか。その後のすべては、その一文に対する帳簿付けである。誰もそれを書けないなら、そのコピーは構築の準備ができていない。

再利用可能な入力、身元と権限、配備状態

再利用可能なバケツは簡単なほうだ。パッケージ、秘密を含まないレビュー済みの設定、サービステンプレート、堅牢化の設定。イメージが本当に得意とするのはこれであり、無制限に再現できる。

身元と権限のバケツこそ、コピーが誤る場所だ。ゲートウェイの秘密鍵と証明書は、そのゲートウェイをすべてのクライアントに対して識別する。認証局の署名鍵は別の力を持つ別の対象であり、身元を発行する。発行者を信頼することは、新しいゲートウェイすべてに発行能力が必要という意味ではない。署名鍵をイメージの中に入れて配れば、そのイメージを読めるあらゆるものにその能力を与えることになる。

配備状態のバケツは、設定に見えるために人々が忘れるほうだ。待ち受けアドレス、アドレスプール、プッシュされるルート、リゾルバの設定、ローカル統合は、いずれも最初のホストについての前提を符号化している。それをコピーした二つ目のノードは、別のゲートウェイがすでに所有するプールから割り当てたり、元の隣にしか存在しない資源へクライアントを向けたりしかねない。

新しいノードに何を与えるべきか、誰が与えるか

独立に管理されるノードは、承認された登録手続きを通じて自身の資格情報を受け取るべきであり、署名の操作は新しいホスト上ではなく署名鍵のある場所で行うべきだ。他のノードを乱さずに取り下げられる身元はどれかを記録せよ。答えが「すべて」なら、その設計は一つの身元が二つのふりをしている。

ネットワークの値も同じ扱いに値する。既存のゲートウェイと衝突しないプール、待ち受けアドレス、プッシュするルートの組を選び、イメージではなくプロビジョニング入力に書き込む。入力はレビューできるが、イメージはできない。

正当な中間的な事例もある。サポートされたリカバリやレプリケーションの設計は、古いコピーへの制御されたアクセスとローテーション計画を伴って、複数ホストにまたがる一つの論理サービス身元を意図的に保つことがある。それは所有者のいる判断であり、イメージが便利だったから生じる既定値ではない。

openssl x509 -in /etc/openvpn/server/server.crt -noout -subject -issuer -dates
find /etc/openvpn -name '*.key' -o -name '*.pem' | head -20

最初のコマンドは、ノードが実際にどの身元を提示し、誰が署名したかを示す。二つ目は出発点の棚卸しであり、証明ではない。秘密の材料はそのディレクトリの外、アプリケーションのデータベース内、あるいは稼働中のファイルシステムにもう現れないスナップショット層に存在しうる。

イメージのコピーが静かに持ち運ぶもの

イメージの最新リビジョンからファイルを削除しても、古いリビジョン、レイヤキャッシュ、存在していた間に取得されたスナップショットからは消えない。だからこそ資格情報を含むイメージは、構築の瞬間だけでなく、その生涯を通じて機微な対象として扱わなければならない。

イメージの中身とプロビジョニング入力は別々の問いとして確認せよ。イメージは「この成果物の中に何があるか」に答え、入力は「このインスタンスが初回起動で何になるか」に答える。共有鍵を取得するブートストラップスクリプトを持つきれいなイメージは、前者にはよく、後者には悪く答える。

正当に秘密を含むリカバリ用イメージは、必要とする人だけに限定し、どこに保管されているかを記録せよ。その代わりになるもの、つまりプロビジョニングなしで動くから便利なイメージは、見つけた誰にでもゲートウェイの身元を与える同じイメージだ。その二つの作業のうち構築ログに現れるのは一方だけである。

本番前の受け入れ確認

ノードがトラフィックを受け取る前に、四つのことを確認する。提示する身元、受け入れるクライアント、到達を許可されている資源、配るアドレスの戻り経路。

systemctl status openvpn-server@lab --no-pager
ss -lunp 'sport = :1194'
ip -4 route show table all | grep -F '10.90.'

次に、事故を捕まえるのは否定形の確認だ。新しいノードに、元のホスト向けだった管理者アクセスやクライアントアクセスが残っていないか。コピーされた設定は、余分なクライアント項目、継承された管理ルート、最初のホストでは意味のあったプッシュ指示を運んでいることがある。

生きた秘密を含むイメージがすでに承認された境界の外へ出ているなら、資格情報を差し替え、コピーを封じ込めよ。最新ビルドからファイルを消すことは、古いコピーがまだ保持している資格情報を退役させることと同じではない。その二つの事実の間の隙間こそ、攻撃者が必要とする窓である。

関連記事