M1とm2の2台のマシンがあり、マシンm2はSSHを使用してm1に接続できます。 m1にしか接続できないマシンm1bisと、m2にしか接続できないマシンm2bisがあります。マシンm1のポートpに接続することで、m1bisがポートqのマシンm2bisに到達できるようにしたいと思います。 pとqの両方が非特権ポートである、つまり1024より大きいとしましょう。写真の場合:
+-------+ q +----+ SSH +----+ p +-------+
| m1bis | ----> | m1 | <------ | m2 | ----> | m2bis |
+-------+ +----+ +----+ +-------+
M1とm2にシェルアクセスできます。私がこれを行う通常の方法は、m2で以下を実行することにより、SSHリバースポートフォワードを使用することです。
ssh -R *:q:m2bis:p m1
これにより、m1のSSHデーモンがすべてのインターフェイスのポートqでリッスンし、着信接続をマシンm2bisのポートpに中継します。このように、m1bisがマシンm1のポートqに接続すると、接続はSSHによってm1からm2にルーティングされ、接続は実際にはマシンm2bisのポートpで行われます。ここまでは順調ですね。
問題は、m1のSSHサーバー構成で設定GatewayPorts=yes
を有効にする必要があることです。ただし、有効になっておらず、m1のルートではないため、有効にできません。
ただし、これを回避してポートフォワーディングを実行することを実際に妨げるものは何もないように思われます。m1へのシェルアクセスがあり、m1とm2の間にSSH接続があり、m1でリッスンするプロセスを実行できます。 (SSHデーモンにリッスンを行わせる代わりに)すべてのインターフェースのポートqで、SSHを介して接続をルーティングします。したがって、基本的に、私は自分のポートフォワードを構築するために必要なすべての権限を持っています。
実際にこれを行うことはできますか?簡単な方法はありますか?
追加要件:
netcat
、socat
などの一般的なユーティリティを備えたbashスクリプト、または自己完結型のCを好みます。プログラム。友人が別の解決策を提案しました。socat
コマンドがm1にインストールされている場合、ループバックアドレスをリッスンしながら、ポートq2でSSHリバースポートフォワードを実行できます。つまり、m2で次のコマンドを実行します。
ssh -R q2:m2bis:p m1
また、m1でsocat
を次のように使用します。これにより、ポートqの着信接続が、ループバックアドレスをリッスンしているポートフォワーディングにリダイレクトされます。
socat tcp-listen:q,reuseaddr,fork tcp:localhost:q2
正常に機能する解決策は、m1で独自のSSHデーモンを実行することです。これはrootなしで実行できます。通常のユーザーであるときにSSHデーモンを実行する方法は次のとおりです。
最初にホストキーを生成します。
ssh-keygen -f test_Host_rsa -N '' -t rsa
ssh-keygen -f test_Host_dsa -N '' -t dsa
ssh-keygen -f test_Host_ed25519 -N '' -t ed25519
次に、sshdの構成ファイルを記述します。2222は、m1で使用されず、m2が接続できる非特権ポートであり、現在のフォルダーへの絶対パスも指定する必要があります。
cat >sshd_config <<EOF
Port 2222
HostKey /folder/where/the/files/are/test_Host_rsa
HostKey /folder/where/the/files/are/test_Host_dsa
HostKey /folder/where/the/files/are/test_Host_ed25519
GatewayPorts yes
次に、SSHデーモンを実行します。
/usr/sbin/sshd -f sshd_config
これで、SSHデーモンでGatewayPortsが有効になっているため、m2はm1のポート2222に接続し、リバースポートフォワードを実行できます。つまり、m2では次のコマンドを実行できます。
ssh -p 2222 -R *:q:m2bis:p m1