配備タグは、人々がこの機能に手を伸ばすよくある理由です。各接続は拠点やロールのようなものを持ち、サーバーは二つ目の資格情報フォーマットを発明せずにそれを読むべきだ、というわけです。コミュニティ版 OpenVPN にはすでにその仕組みがあり、小さなものです。厄介なのは期待のほうです。クライアントプロファイルに普通の変数を設定してもサーバーでは何も起きず、届いた値はクライアントが送ったことだけを証明します。

これは、機能する経路、実際に何が届いたかを示す検証手順、そして中途半端に設定されたフックを残さないロールバックのためのランブックです。ここで新しい証明書、新しいプラグイン、プロトコル拡張は必要ありません。

変数を設定し、経路を有効にする

クライアントプロファイルでは二行が仕事をし、どちらも必要です。一行目がなければ送るものがなく、二行目がなければクライアントはピア情報をまったく提供しません。順序は問いません。これは知っておく価値があります。二行は生成されたプロファイルの別々の場所に置かれることが多いからです。重要なのは、クライアントが読む前にプロファイルを書き換える何かがあっても、両方が残ることです。

setenv UV_DEPLOY field-support
push-peer-info

UV_ 接頭辞は飾りではありません。普通の DEPLOY 変数はクライアントプロセス内に留まり、決して転送されません。一方、接頭辞付きの形式は、プロトコルがユーザー定義フィールドのために予約している名前空間です。承認済みプロファイルの残りをそのまま保ち、配備するクライアントビルドが両方のディレクティブをサポートすることを展開前に確認してください。

実用的な確認が一つ、最後ではなくここに入ります。ディレクティブがクライアントのバイナリに届き、ラッパーに飲み込まれていないことを確かめてください。独自のコマンドラインを生成する GUI クライアントや、保存済みプロファイルを再読み込みする管理インターフェースは、認識しない行を落とすことがあります。サーバーに何も見えないなら、まずここを見てください。

サーバーフックからフィールドを読む

サーバー側では、受信したピア情報が検証され、接続ワークフローの環境に挿入されるからこそ、あなた側でプロトコルを扱うことなくフックから読めるのです。サーバーは制御チャネルを解析する必要も、あなたのために何かを保存する必要もありません。接続の確立中に値がそこにあるだけです。認証済みの名前の隣にラベルを記録する最小限の client-connect スクリプトは次のとおりです。

#!/bin/sh
# /etc/openvpn/server/hooks/label.sh
printf '%s %s\n' "$common_name" "${UV_DEPLOY:-unset}" \
  >> /var/log/openvpn/deploy-labels.log

ログを解析するのではなく環境を通して変数を読み、常に既定値を与えてください。${UV_DEPLOY:-unset} はフィールドを決して送らないクライアントでもスクリプトを動かし続け、段階的な展開ではこれが通常の状態です。名前を探すために環境全体をログに吐き出さないでください。ラベルよりはるかに多くが含まれ、保存するつもりのなかった値まで入っています。

スクリプトを手で実行すると、すべてに対して unset と報告します。手動のシェルは接続の環境を引き継がないからです。これはスクリプトの不具合でも、フィールドが欠けている証拠でもありません。変数が存在する唯一の文脈である実際の接続で試してください。

実際に何が届いたかを検証する

ラベル付きのクライアントとラベルなしのクライアントを一つずつ接続し、ファイルを読んでください。この組がテストです。一方の行には値が、もう一方には既定値が入り、どちらも期待する同じ認証済みの識別名を示すはずです。

tail -n 5 /var/log/openvpn/deploy-labels.log
# field-support deployed-client-07
# unset         legacy-laptop-02

それらのコメント行は出力の形を示すもので、あなたのサーバーの記録ではありません。自分のファイルを読んでください。二つ目のクライアントにも値が出るなら、変数は環境のどこか別の場所で設定されており、ピアフィールドではなく古い設定を読んでいます。

接続についてサーバーログも確認してください。ピア情報がそこに現れることがあり、これはデバッグに便利で、値を退屈に保つ理由でもあります。人の名前も、チケット番号も、ログの読者に見られて困るものも入れてはいけません。

ラベルを身元ではなく主張として扱う

クライアントプロファイルを編集できる者なら誰でもタグを変えられ、トンネルが認証済みであることはタグを権威あるものにはしません。トランスポートは転送中の値を守りますが、その主張を証明はしません。認可は依然として認証済みの身元と、サーバーが所有する登録記録に属し、必要なときにはラベルがその記録と照合されます。

この区別が、ラベルを使ってよい場所を決めます。良い用途は、セッションを正しいログファイルに振り分けること、ダッシュボードの表示グループを選ぶこと、サポートセッションに印を付けて後から人が見つけられるようにすることです。悪い用途は、端末をサブネットに入れること、ファイアウォールポリシーを選ぶこと、どの顧客のデータをセッションが読めるかを決めることです。

値がパス、クエリ、シェルコマンドに到達する前に検証してください。想定される文字列の許可リストで配備タグには十分で、費用もかかりません。ピアが提供した文字列をシェルコマンドラインに決して埋め込まず、保存する観測はセッションに限定し、次のクライアントが再利用する トンネルアドレス には結び付けないでください。

case "${UV_DEPLOY:-}" in
  field-support|field-qa|lab) : ;;
  *) UV_DEPLOY=unknown ;;
esac

きれいに元に戻す

機能の削除は二つの削除と一つの検証です。クライアントプロファイルから setenv と push-peer-info の行を外し、次にサーバー上のフックとそのログ出力先を削除または無効化します。

grep -rn 'UV_DEPLOY\|push-peer-info' /etc/openvpn/
tail -n 3 /var/log/openvpn/deploy-labels.log

その後にクライアントを一つ再接続し、ログ行が出なくなったことを確認します。プロファイル変更後も発火し続けるフックは、たいていテスト端末にまだ配備されている二つ目のプロファイルです。今見つけるほうが監査中に見つけるより安く済みます。

最後に残るのは、出所が記録された小さく範囲の限定されたセッションメタデータです。クライアントが主張し、サーバーが記録し、アクセスについて何もそれに依存しません。これがこの機能の有用な形であり、そこに至るのに新しい資格情報は要りません。

関連記事