一台のMac画面にはローカルSSH転送か、それともフルVPNか
一つのホスト上の一つの画面なら、ループバックのSSH転送はVPNより小さい。いつそれで足りるのか、何を暗号化するのか、いつ使うのをやめるべきかを説明する。
自分のマシンから一台のMacの画面を見る必要があり、そのMacはすでにSSHで接続できるホストの背後にあり、それがVPNに値するかが問題だ。通常は値しない。ローカル転送を一つ使えば、すでにあるSSHセッションを通ってTCPポートが一つ運ばれ、一つのホスト上の一つの画面なら、ネットワーク全体をルーティングするより小さく、監査しやすい仕組みになる。
これを決める条件は三つあり、どれか一つが変われば管理されたVPNへ進むべきだ。
決めるのは三つの条件
一つ目は範囲で、一つのホスト上の一つのサービスか、複数のホストと複数のポートかだ。二つ目は、踏み台と対象の間の各ホップがすでに信頼できるかどうかで、SSHが守るのは自分が終端する区間だけだ。三つ目は、構築した後に誰がその仕組みを支えるかで、手作りのトンネルは、それを理解した人より長く生き残る傾向がある。始める前にその人を名指しし、コマンドをその人が見つけられる場所に書いておく。文書化されていない転送は、開始日が先送りされた将来のインシデントだ。
答えが「一つ」「はい」「今のところ自分」なら、転送が適切な道具だ。どれか一つの答えが変われば、年単位で見ると、支援のあるリモートアクセス設計のほうが、文書化されていないトンネルの後のインシデントレビューより安くつく。
ネットワークではなく一つのポートを転送する
ローカル転送は自分のマシンにリスナーを開き、各接続をSSHサーバー経由で、そのサーバーが到達できる宛先へ中継する。画面共有サービスがTCP 5900で待ち受けるMacと、mac.corp.exampleを解決できる踏み台なら、コマンドは短く、意図的に狭い。その中のどのオプションも、シェルなし、全インターフェースのリスナーなし、デーモンなしというように、仕組みを小さく保つためにある。レシピではなく、範囲の宣言として読んでほしい。
ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:15900:mac.corp.example:5900 [email protected]リスナーを127.0.0.1に束縛すれば、他のどのインターフェースからも切り離される。これは形式ではなく、すべてのインターフェースに束縛した転送は、同じカフェのWi-Fiにいる誰に対しても、あなたのノートPCを社内ネットワークへの開いた中継にしてしまう。ポートがすでに使われているなら、別の高いポートを選んでビューアを更新し、例に合わせるために無関係なサービスを止めてはいけない。
踏み台のアカウントにも、その宛先へ転送する許可が必要だ。強化されたSSH設定には、ポート転送を完全に無効にするものもあれば、permit-listenやpermit-openの指示で制限するものもある。拒否されたチャネルをパスワード間違いと決めつける前に、サーバーのポリシーを読むこと。
SSHが暗号化する範囲と、それが止まる場所
SSHセッションはMacから踏み台までの通信を守り、転送はVNCプロトコルを理解しないまま、そのセッションの内側で運ぶ。接続が踏み台を離れて対象へ向かうと、それはもうSSHセッションの内側にはない。その最後のホップにどんな保護があっても、それは対象のプロトコルと、プライベートネットワーク自身の制御に属する。
だからこそ、最初のホップがSSHを使ったというだけで、最後のVNCホップを端から端まで暗号化されていると説明してはいけない。クライアントから踏み台までは強く、その先は対象が対応する範囲だというように、区間を正直に説明する。経路全体を一つの仕組みで暗号化することが要件なら、転送はそれを満たさない。
対象側の認証はまた別だ。SSHアカウントはmacOSへのログインを与えず、画面共有サービスはいまも独自の資格情報を求め、いまも独自のアクセスリストを適用する。接続を受け付けるローカルのリスナーは、リモートのサービスがセッションを許可するかどうかを何も証明しない。
フルVPNが正しい判断になるのはいつか
作業に複数のポートが必要ならVPNを選び、Apple Remote Desktopの管理とレポートの機能は、TCP転送一つでは運べない追加のTCPとUDPの通信を使う。転送は製品全体の部分実装ではなく、別の、より小さな道具だ。
複数の管理者が変わる場所から接続するならVPNを選び、管理されたプロファイルは、各自がコマンドラインを発明することなく、ルート、資格情報、ポリシーを配布する。監査記録で誰が何に接続したかを示す必要があるならVPNを選び、ユーザーごとのSSHセッションと共有のローカル転送では、残る記録が大きく異なる。
組織自身のゲートなしにノートPCから対象ネットワークへまったく到達できてはいけないなら、最後にVPNを選ぶ。個人の転送は設計上そのゲートを迂回するからこそ、シェルの履歴ではなく変更記録に載せるべきものだ。
転送は大きな音を立てて失敗させる
ExitOnForwardFailure=yesを使い、束縛に失敗したらセッションを止め、接続しているように見えて何も転送しないシェルを残してはいけない。ホスト鍵の検証は有効にしたまま、パスワードより鍵かエージェントを選ぶ。そのうえで、ビューアが使う正確なURLを試すべきで、動くSSHセッションと動く画面接続は別の結果だからだ。
macOSのネイティブクライアントでは、ローカルのURL open "vnc://127.0.0.1:15900" でビューアに到達する。ウィンドウが開き、リモートのホストが認証を拒否するなら、トンネルは正常で問題は対象側にある。ウィンドウが一度も開かないなら、問題はリスナーかポートにある。
終わったらセッションを止め、ポート、踏み台、対象、アカウントのポリシーを書き留める。誰も文書化していない転送は、半年後にはバックドアと区別がつかず、だから小さく、名前を付け、一時的に保つべきだというのが最も強い根拠だ。