
リモート ポート転送を介して SSH 接続を行う際に問題が発生します。
シナリオは、内部ネットワーク上のサーバー (ここでは「オリジン」と呼ぶ) が SSH 経由で DMZ 内のサーバー (「ターゲット」) にログインする必要があるエンタープライズ ネットワークです。DMZ 内のターゲット サーバーは内部ネットワークからの接続がロックダウンされているため (内部ネットワークからは見えません)、DMZ 内にジャンプ ホスト (「ジャンプホスト」) があり、そこを経由します。ジャンプホストでリモート ポート転送を設定することでこれを行います。
内部ネットワーク上のオリジン サーバーからジャンプホストに次のコマンドを実行します。
origin> ssh -R *:1234:target:22 myusername@jumphost
これは、ジャンプホスト上で SSH セッションを確立し、ポート 1234 (任意のポート番号の例) でリッスンを開始し、そのポート上の接続をターゲット サーバーのポート 22 (SSH) に転送するためのものです。
次に、元のサーバーからジャンプホストへの 2 番目の SSH セッションをポート 1234 で確立し、実際にポート 22 でターゲット サーバーに接続します。これが、ターゲット サーバーで作業を実行できる「実際の」SSH セッションです。
origin> ssh jumphost -P 1234
構成
ジャンプ ホストは、sshd_config で次の設定を使用して、リモート ポート転送を許可するように構成されています。
AllowTcpForwarding yes
GatewayPorts yes
また、オリジン サーバーとジャンプ ホストの間には、ポート 22 (リモート ポート転送を設定するための最初の SSH 接続用) とポート 1234 (転送されたポートでの後続の SSH 接続用) のファイアウォールが開いています。ジャンプ ホストとターゲットの間にもファイアウォールがあり、ポート 22 で開いています。
結果
2 番目の接続 (転送されたポートを介した接続) を確立すると、接続はすぐに閉じられます (「リモート ホストによって接続が閉じられました」)。
ターゲット サーバーで tcpdump を実行してもアクティビティは表示されません。つまり、接続がブロックされているようです。
ただし、ジャンプホストからターゲットへの通常の SSH セッションを正常に確立できます。両方ともポート 22 でターゲットに接続しますが、転送されたポートから入ってくる場合のみ接続が閉じられます。
さらに、ポート転送を内部ネットワーク上のサーバーにポイントさせると (つまり、内部ネットワークの起点から DMZ 内のジャンプホストに接続し、再び内部ネットワーク上の 3 番目のサーバーに戻る)、SSH セッションが正常に確立されます。
推測と疑問
これらすべてから、何らかのネットワーク セキュリティ設定が影響して、ジャンプ サーバーの転送ポート経由で DMZ 内のターゲット サーバーに接続できないのではないかと考えています。残念ながら、私にはそれを知るほどの知識がありません。
(1) ジャンプ サーバーの転送ポートを介してオリジン サーバーから送信される SSH 接続は、ネットワーク セキュリティ ポリシーの観点からは「異なる」ため、技術的にブロックできるのでしょうか。また、ブロックできる場合、どのようにブロックすればよいのでしょうか。また、その制限を解除するには何を行う必要がありますか。
(2)この接続が許可されない他の理由(ファイアウォールの構成、ルーターの構成、オリジンまたはジャンプホストのSSH設定など)はありますか?
(3) オリジン サーバーがターゲット サーバーを認識しないため、最初の ssh コマンドが意図したとおりに機能しないために失敗する可能性がありますか? 言い換えると、最初の ssh コマンド (「ターゲット」) で指定されたホスト名は、クライアント (オリジン) で解釈されるのでしょうか、それともトンネルを作成するために接続しているサーバー (ジャンプホスト) で解釈されるのでしょうか?
最も困惑しているのは、ジャンプホストからターゲットへの通常の SSH セッションを確立できるということです。転送されたポート経由で入ってくる SSH 接続も同じだろうと思いますが、どういうわけかそうではありません。
どのようなご意見でも大歓迎です。
答え1
リモート ポート転送ではなく、ローカル ポート転送を使用する必要があるようです。Dirk Loss による次の役立つブログ投稿を参照してください。
これには次の説明図が含まれます。
図を読むには、SSH トンネルの作成と利用に関わる 4 つの異なる役割の関係を説明していることを理解する必要があります。
- トンネルを確立するために使用されるssh クライアント (つまり
ssh
、OpenSSH コマンドライン クライアント)。 sshd
トンネルのもう一方の端を管理するために使用されるssh サーバー (つまり、OpenSSH サーバー デーモン)。- アプリケーション サーバー (別の ssh サーバーまたは http サーバーなど)。
- トンネル経由でアプリケーション サーバーにアクセスするアプリケーション クライアント (別の SSH クライアントや Web ブラウザーなど)。
また、2 つの異なる転送タイプが 2 つの異なるユースケースに対応していることを理解することも重要です。
ローカル転送: アプリケーションクライアントがsshクライアント経由で接続する場合
リモート転送: アプリケーションクライアントがSSHサーバー経由で接続する場合
リモート転送は、転送がローカル (ssh クライアント) ではなくリモート (ssh サーバー) で実行されるため、このように呼ばれます。また、「リモート転送 = 逆転送」という覚え方も便利です。
ご覧のとおり、ホストssh
のクライアントからプロキシ上のサーバーを経由して3 番目のホストへの接続を開始するには、ローカル ポート転送を使用する必要があります。リモート ポート転送は、トンネルへのエントリ ポイントをクライアントを実行しているホストではなく、サーバーを実行しているホストに配置する場合に使用します。origin
sshd
jumphost
target
sshd
ssh
マニュアル ページでは、ローカル ポート転送の構文は次のように記述されています。
ssh -L [bind_address:]port:host:hostport user@remote
これをより直感的に記述すると次のようになります。
ssh -L [local_bind_address:]local_port:remote_host:remote_host_port user@proxy_host
または、命名規則を使用して次のようにします。
ssh -L [origin_bind_address:]origin_port:target_host:target_host_port user@jump_host
代わりにローカル ポート転送を使用するようにコマンドを変更すると、次のようになります。
user@origin:~$ ssh -L *:1234:target:22 myusername@jumphost