SSHリバーストンネリングを実行していますが、トンネルに接続できません

SSHリバーストンネリングを実行していますが、トンネルに接続できません

私は、127.0.0.1 のポート 80 で IIS を実行している Windows 11 ボックスを持っており、これは CGNAT 経由でインターネットに接続されています。また、Linode (VPS サプライヤー) の VPS も持っています。VPS の IP アドレスは 139.162.19.185 です。インターネット上のどこからでも、VPS 経由で Wi​​ndows 11 ボックスのサーバー/ポートに接続したいと考えています。

管理者モードで Windows 11 コマンド プロンプトを使用して、以下のコマンドを実行しました。

ssh -R 80:localhost:80 [email protected]

VPSのSSHトンネルにアクセスしようとするとhttp://139.162.19.185:80、接続が拒否されましたが、ローカルホストにアクセスしようとするとhttp://127.0.0.1、IIS スタートホームページが表示されます。

/etc/ssh/sshd_config ファイルを確認したところ、GatewayPorts と AllowTcpForwarding の両方が有効になっています。

アップデート:

これはnetstat -tlnpの結果です

root@localhost:~# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:80            0.0.0.0:*               LISTEN      35027/sshd: root@pt
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      434/sshd: /usr/sbin
tcp6       0      0 ::1:80                  :::*                    LISTEN      35027/sshd: root@pt
tcp6       0      0 :::22                   :::*                    LISTEN      434/sshd: /usr/sbin
root@localhost:~#

curl の結果は次のとおりです。

root@localhost:~# curl http://127.0.0.1:80
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Hostname</h2>
<hr><p>HTTP Error 400. The request hostname is invalid.</p>
</BODY></HTML>
root@localhost:~#

編集する必要がある設定ファイルはありますか? Linode にファイアウォールがあるかどうかを確認するためにデバッグを試みました。apache2 をインストールしましたが、ポート 80 で正常に動作するため、ポート 80 はブロックされていません。

答え1

このオプションの使用方法は-R、リモート側をループバック インターフェイスにのみバインドすることを意味します。sshマニュアル ページから:

     -R [bind_address:]port:host:hostport

     ...

             By default, TCP listening sockets on the server will be bound to the loopback interface only.  This may be overridden by
             specifying a bind_address.  An empty bind_address, or the address ‘*’, indicates that the remote socket should listen on
             all interfaces.  Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see
             sshd_config(5)).

簡単に言えば、次のようになります。

  • -R port:host:hostportループバックのみにバインドします
  • -R :port:host:hostportすべてのインターフェースにバインドします
  • 意志-R *:port:host:hostport-R 0.0.0.0:port:host:hostport

したがって、あなたの状況では、次のいずれかが機能するはずです。

ssh -R :80:localhost:80 [email protected]
ssh -R *:80:localhost:80 [email protected]
ssh -R 0.0.0.0:80:localhost:80 [email protected]

*以下は、ドキュメントのテキストに基づいてこの動作を説明する私のオリジナルの試みです。いくつかの説明を加えています。

PORT:IP:PORT 構文を使用しましたが、bind_address が指定されていません。

specifying a bind_address上記の説明のテキストは:、リモート ポート (PORT:IP:PORT の最初のポート) の前に があることを指しています。例にあるように はありません。つまり、:bind_address を指定していないことを意味し、man ページによると、リモート側はループバック インターフェイス (デフォルト) にのみバインドします。すべてのインターフェイスにバインドするには、:実際の bind_address が「空の文字列」であっても、bind_address を指定する必要があります (つまり、リモート ポートの前に を追加します)。この場合、「空の文字列」または のどちらでも機能しますが、ループバック アドレスのみへのバインドに限定されないようにするには が必須である*ことに注意してください。:

アップデート

@barlop からのコメントを受けて、私の説明があまり明確ではなかったようですので、ここで段階的に説明しようと思います。

  • オプションは として定義されます-R [bind_address:]port:host:hostport
  • 全体の[bind_address:]部分はオプションです。存在しない場合は、オプションの形式が となり、デフォルトの動作が適用されます。-R port:host:hostportつまり、 となります。TCP listening sockets on the server will be bound to the loopback interface only
  • 部分が存在する場合[bind_address:]、それはフォーマットがあることを意味します。-R bind_address:port:host:hostport最初の部分:はもはやオプションではないことに注意してください。この瞬間から、bind_address複数の値を取ることができます。可能な値の1つは確かに空の文字列! したがって、オプションにコロンを追加すると、bind_address今回は空ではあるものの を指定することになります (説明によると、これは を意味すると解釈されますthe remote socket should listen to all interfaces)。

これで少しは明確になったと思いますが、基本的にはnot specifying a bind_addressと はspecifying an empty string as bind_address2 つの異なるものです。「空の文字列」bind_address はバインド アドレスと見なされ、:PORT:IP:PORT左端のコロンの前にアドレスとして何も書き込まない構文を使用することを指します。

以下は私がテストしたときの出力です (別のポートですが、効果は同じです)。

SSH を実行し、リモート マシンで netstat -an を実行していることを確認します。

gepa@localhost:~$ ssh -R :5555:localhost:5555 cloud1 netstat -an | grep :5555
tcp        0      0 0.0.0.0:5555            0.0.0.0:*               LISTEN     
tcp6       0      0 :::5555                 :::*                    LISTEN     

gepa@localhost:~$ ssh -R 5555:localhost:5555 cloud1 netstat -an | grep :5555
tcp        0      0 127.0.0.1:5555          0.0.0.0:*               LISTEN     
tcp6       0      0 ::1:5555                :::*                    LISTEN     

:最初の の前にを追加すると5555、 を省略した場合と比較して、リモート ホストがすべてのインターフェイスをリッスンすることに注意してください:

$ ssh -R *:5555:localhost:5555 compところで、空の文字列bind_addressを使わず、またはと書く方がはるかに明確です。0.0.0.0:80:localhost:80

また、PORT:IP:PORT 構文が 127.0.0.1 にバインドされる理由は、セキュリティ上の理由です。したがって、非ローカルにバインドする場合は、ワイルドカードを使用するか、0.0.0.0 を指定するか、LAN からのみ接続する場合は LAN アドレスを指定するなど、明確に指定することをお勧めします。

関連情報