一台のマシンはすでに承認済みの VPN アクセスを持ち、二台目のマシンはちょうど一つのプライベートな HTTPS サービスを必要としており、ローカルの SSH 転送が、二台目のマシンにトンネルを与えることなくその隙間を埋められます。転送が運ぶのはネットワーク全体ではなく一つの TCP 宛先であり、まさにその制限が要点です。以下の五つの手順は、それぞれ失敗する理由が異なり後の手順で前の抜けを埋められないため、順番に進めてください。前提条件が一つでも欠けていれば、この設計では解決できず、コマンドの調整ではどうにもなりません。

第一ステップ:三つの前提条件を確認する

どのコマンドも意味を持つ前に、三つのことがすでに真である必要があります。一台目のマシンを転送ホストとして使う許可、そこへの有効な SSH アクセス、そして目的の宛先を許可するサーバーポリシーです。ファイル転送用に作られた SSH アカウントでは転送が無効になっていることがあり、転送を許可するサーバーでも、その経由で到達できる宛先を制限している場合があります。合意なしに同僚のワークステーションをジャンプポイントとして使うのはコマンドが問題なく動いてもポリシー上の問題なので、テストの前に確認してください。

二つのコマンドがそのリストの技術的な半分を片付けます。一つ目はアカウントと鍵が対話的なプロンプトなしで機能することを証明し、二つ目は設定ファイル内のコメント化された例ではなく、実際に有効なサーバーポリシーを出力します。

ssh -o BatchMode=yes [email protected] 'echo ok'
sudo sshd -T | grep -E 'allowtcpforwarding|permitopen'

第二ステップ:loopback ポートをバインドし、セッションを維持する

クライアントアプリケーションを実行するマシンで、プライベートサービスへのローカル転送を開きます。ローカルネットワークに公開されないよう明示的に loopback にバインドし、どのローカルサービスも使っていない高いポートを選びます。閉じるとリスナーも閉じるため、作業中はセッションを動かしたままにしてください。ExitOnForwardFailure は、拒否されたバインドや使用中のポートを、転送なしで残るセッションではなく即時の終了に変え、これが最も時間を浪費する失敗の形です。

プライベート接続はジャンプホストから張られるため、そのホストの DNS、ルート、VPN ポリシー、サービスへのアクセスがすべて機能している必要があります。SSH セッションはジャンプホストにない到達性を作り出すものではなく、VPN が一度も流していないルートを修復することもできません。コマンドの無言を信じるのではなく、リスナーが実際に存在する場所で確認してください。

ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:9443:portal.lab.example:443 [email protected]
ss -ltn '( sport = :9443 )'

第三ステップ:ソケットがローカルでも HTTPS の名前を保つ

https://127.0.0.1:9443/ を閲覧すると TLS サーバー名とアプリケーションの権限が変わります。portal.lab.example 用に発行された証明書は loopback アドレスに対して検証されず、その結果のエラーは転送の近道ではなく壊れた証明書のように見えます。コマンドラインでのテストでは実際の URL を保ち、ソケットの宛先だけを変えてください。--connect-to が行うのはこれであり、curl のマニュアル が以下で使う四フィールド形式を説明しています。

curl --noproxy portal.lab.example --connect-to portal.lab.example:443:127.0.0.1:9443 https://portal.lab.example/

名前は URL、TLS ハンドシェイク、Host ヘッダーに残り、TCP 接続だけがローカルのリスナーに向かいます。プロキシを使わないオプションは、設定済みの HTTP プロキシに横取りさせず、この転送でテストを続けるためのものであり、証明書の検証を有効に保つことが結果を意味あるものにします。

第四ステップ:一本の転送でカバーできない範囲を知る

TCP 転送一本がカバーするのは一つの宛先ポートです。二つ目のホスト名へリダイレクトするページ、プライベートネットワーク内のホストからアセットを読み込むページ、別のポートへ送信するページには、それぞれ専用の転送が必要であり、どれも一つ目と同じポリシー確認が要ります。ブラウザーの作業には、プロキシ設定やローカルの対応付けを通じて実際の名前をローカルポートへ送るようブラウザーに指示する必要があるという独自の要件が加わります。したがってコマンドラインのテストが成功しても経路が通ることは証明できても、ブラウザーでも成功するとは証明できません。

UDP、SMB 探索、ドメインサインインは TCP 転送をまったく通りません。本当の要件が一般的なネットワークアクセスなら、この設計は間違った道具であり、サポートされたリモートアクセスゲートウェイが正解です。

第五ステップ:後片付けと記録

テストが終わったらセッションを停止し、リスナーが消えたことを確認してください。選んだポートがすでに使用中だった場合は、番号を空けるために無関係なローカルサービスを止めるのではなく、別の未使用の loopback ポートを選び、URL、テストコマンド、メモをまとめて更新します。ノート PC で転送を開いたままにすると、診断が管理されないサービスに変わります。

ジャンプホスト、転送先、ローカルポート、そして誰がこの取り決めを承認したかを書き留めてください。誰かのシェル履歴にしか存在しない転送は、再起動一回で同じ調査をやり直すことになり、次の人は三つの前提条件のどれが確認済みかを知りません。

関連記事