SSHでのデータのトンネリングは非常に簡単です
ssh -D9999 username@example.com
は localhost
のポート 9999 を example.com
へのトンネルとして設定しますが、私にはもっと具体的な必要性があります
- 私はローカルで
localhost
で作業しています host1
はlocalhost
にアクセスできますhost2
はhost1
からの接続しか受け付けませんlocalhost
からhost2
へのトンネルを作成する必要があります
事実上、私は “マルチホップ “のSSHトンネルを作成したいと思います。どうすればいいのでしょうか?理想的には、マシンの すべての でスーパーユーザになる必要なしにこれを行いたいと思います
389 Mala 2010-01-16
基本的には3つの可能性があります
localhost
からhost1
へのトンネルssh -L 9999:host2:1234 -N host1
前述の通り、
host1
からhost2
への接続は確保されませんlocalhost
からhost1
へ、host1
からhost2
へのトンネルssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
これにより、
localhost
からhost1
までのトンネルと、host1
からhost2
までの別のトンネルが開かれます。しかし、ポート9999
からhost2:1234
はhost1
の誰でも使うことができます。これは問題になるかもしれないし、ならないかもしれないlocalhost
からhost1
へ、localhost
からhost2
へのトンネルssh -L 9998:host2:22 -N host1 ssh -L 9999:localhost:1234 -N -p 9998 localhost
これにより、
localhost
からhost1
へのトンネルが開かれ、host2
の SSH サービスが利用できるようになります。そして、最初のトンネルを通ってlocalhost
からhost2
に 2 つ目のトンネルが開かれます
通常、私はオプション1を使用します。host1
から host2
への接続を確保する必要がある場合は、オプション2を使う。オプション3は主にhost2
上のサービスにアクセスするのに便利で、host2
自身からしかアクセスできない
368 Mika Fischer 2010-01-17
SSH用のProxyCommand
設定ディレクティブの使用法を説明した優れた回答があります
これを~/.ssh/config
に追加します(詳細はman 5 ssh_config
を参照)
Host host2
ProxyCommand ssh host1 -W %h:%p
そうすると、ssh host2
は自動的にhost1
を経由してトンネルを通過します(X11転送などでも動作します)
これは、例えばドメインで識別されるホストのクラス全体に対しても動作します
Host *.mycompany.com
ProxyCommand ssh gateway.mycompany.com -W %h:%p
Update
OpenSSH 7.3 は ProxyJump
ディレクティブを導入しました
Host host2
ProxyJump host1
165 kynan 2010-08-01
OpenSSH v7.3 以降では -J
スイッチと ProxyJump
オプションがサポートされています
ssh -J jumpuser1@jumphost1,jumpuser2@jumphost2,...,jumpuserN@jumphostN user@host
48 nikolay 2016-08-10
プライベートネットワークへの ssh ゲートウェイが 1 つあります。外にいて、プライベートネットワーク内のマシンでリモートシェルを使いたい場合は、ゲートウェイにsshして、そこからプライベートマシンに接続しなければなりません
この手順を自動化するには、以下のスクリプトを使用します
#!/bin/bash
ssh -f -L some_port:private_machine:22 user@gateway "sleep 10" && ssh -p some_port private_user@localhost
何が起きているのか
- プライベートマシンへの ssh プロトコル (ポート 22) のトンネルを確立します
- 成功した場合のみ、トンネルを使ってプライベートマシンにsshします。(&&オペレータはこれを保証します)
- プライベート ssh セッションを閉じた後、ssh トンネルも閉じたい。これは “sleep 10” というトリックを使って行います。通常、最初の ssh コマンドは 10 秒後に閉じますが、この間に 2 番目の ssh コマンドがトンネルを使って接続を確立しています。その結果、最初の ssh コマンドは、次の 2 つの条件が満たされるまでトンネルを開いたままにします: sleep 10 が終了し、トンネルが使用されなくなります
20 Bernhard Kausler 2010-01-24
上記を読んで全てを接着した後、以下のPerlスクリプトを作成しました(/usr/binにmsshとして保存して実行可能な状態にします)
#!/usr/bin/perl
$iport = 13021;
$first = 1;
foreach (@ARGV) {
if (/^-/) {
$args .= " $_";
}
elsif (/^((.+)@)?([^:]+):?(\d+)?$/) {
$user = $1;
$host = $3;
$port = $4 || 22;
if ($first) {
$cmd = "ssh ${user}${host} -p $port -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
$args = '';
$first = 0;
}
else {
$cmd .= " -L $iport:$host:$port";
push @cmds, "$cmd -f sleep 10 $args";
$cmd = "ssh ${user}localhost -p $iport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
$args = '';
$iport ++;
}
}
}
push @cmds, "$cmd $args";
foreach (@cmds) {
print "$_\n";
system($_);
}
Usage:
HOSTAとHOSTB(同一ユーザー)を経由してHOSTCにアクセスする場合
mssh HOSTA HOSTB HOSTC
HOSTAとHOSTB経由でHOSTCにアクセスし、デフォルト以外のSSHポート番号と異なるユーザを使用する場合
mssh user1@HOSTA:1234 user2@HOSTB:1222 user3@HOSTC:78231
HOSTAやHOSTBを経由してHOSTCにアクセスし、X転送を利用する場合
mssh HOSTA HOSTB HOSTC -X
HOSTAとHOSTBを介してHOSTCのポート8080にアクセスする
mssh HOSTA HOSTB -L8080:HOSTC:8080
18 Bob Muller 2012-01-11
この答えは、ProxyCommandの使用を伴うので、kynanと似ています。しかし、IMOではその方が便利です
ホップマシンに netcat がインストールされている場合は、このスニペットを ~/.ssh/config に追加することができます
Host *+*
ProxyCommand ssh $(echo %h | sed 's/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') nc $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')
Then
ssh -D9999 host1+host2 -l username
はあなたの頼みを聞いてくれます
このトリックを読んだ元の場所を探してここに来ました。見つけたらリンクを貼っておきますね
8 silviot 2013-03-13
思うようなことをしました
ssh -D 9999 -J host1 host2
両方のパスワードの入力を求められたので、host2へのSOCKSプロキシとしてlocalhost:9999を使うことができます。これが最初に示した例に最も近いと思います
7 Cheryl 2017-11-21
私の回答は、ここの他の回答と本当に同じなのですが、~/.ssh/config
とProxyJumpの有用性を明確にしたかったのです
例えば、3ホップで目的地に到達する必要があり、各ホップごとに特定のユーザ名、ホスト、ポート、IDが必要だとします。ID の基準があるので、これは ~/.ssh/config
の設定ファイルでしかできません
Host hop1
User user1
HostName host1
Port 22
IdentityFile ~/.ssh/pem/identity1.pem
Host hop2
User user2
HostName host2
Port 22
IdentityFile ~/.ssh/pem/identity2.pem
ProxyJump hop1
Host hop3
User user3
HostName host3
Port 22
IdentityFile ~/.ssh/pem/identity3.pem
ProxyJump hop2
お使いのコンピュータから、それぞれのジャンプを個別にテストすることができます
[yourpc] $ ssh hop1 # will go from your PC to host1 in a single step
[host1] $ exit
[yourpc] $ ssh hop2 # will go from your PC to host2 via host1 (i.e. two steps)
[host2] $ exit
[yourpc] $ ssh hop3 # will go from your PC to host3 via host1 and host2 (i.e. three steps)
[host3] $ exit
[yourpc] $
~/.ssh/config
ファイルについてのもう一つのクールな点は、これによって sftp
ファイルの転送も可能になるということです
[yourpc] $ sftp hop1 # for file transfers between your PC and host1
Connected to hop1.
sftp> quit
[yourpc] $ sftp hop2 # for file transfers between your PC and host2
Connected to hop2.
sftp> quit
[yourpc] $ sftp hop3 # for file transfers between your PC and host3
Connected to hop3.
sftp> quit
5 Stephen Quan 2019-12-18
ssh -L 9999:host2:80 -R 9999:localhost:9999 host1
-L 9999:host2:80
つまり、localhost:9999にバインドして、localhost:9999に送られたパケットをhost2:80に転送する
-R 9999:localhost:9999
host1:9999で受信したパケットをlocalhost:9999に転送することを意味します
4 chinmaya 2010-01-19
を使うと、ポートフォワーディングを使って host2
のサービスに localhost
からアクセスできるようになるはずです。良いガイドは こちら にあります。抜粋
ポートフォワーディングには、ローカルフォワーディングとリモートフォワーディングの2種類があります。これらはそれぞれ、発信トンネルと着信トンネルとも呼ばれます。ローカルポート転送は、ローカルポートに来たトラフィックを指定したリモートポートに転送します
例えば、コマンドを発行すると
ssh2 -L 1234:localhost:23 username@host
クライアントのポート 1234 に来るすべてのトラフィックは、サーバ (ホスト) のポート 23 に転送されます。接続が確立された後、localhost は sshdserver によって解決されることに注意してください。したがって、この場合、localhost はサーバ (ホスト) 自体を指します
リモートポート転送は、リモートポートに来るトラフィックを指定したローカルポートに転送します
例えば、コマンドを発行すると
ssh2 -R 1234:localhost:23 username@host
サーバ (ホスト) のポート 1234 に来るすべてのトラフィックは、クライアント (ローカルホスト) のポート 23 に転送されます
キャストでは、例のlocalhost
をhost2
に、host
をhost1
に置き換えてください
2 fideli 2010-01-16
この回答では、具体的な例を紹介します。コンピュータのホスト名、ユーザ名、パスワードを自分のものに置き換えるだけです
Problem statement
以下のようなネットワークトポロジーを想定してみましょう
our local computer <---> server 1 <---> server 2
具体的には、以下のコンピュータのホスト名、ユーザ名、パスワードがあるとします
LocalPC <---> hostname: mit.edu <---> hec.edu
username: bob username: john
password: dylan123 password: doe456
目標: LocalPC
のポート 9991
をリッスンする SOCKS プロキシを設定して、LocalPC
の接続がポート 9991
から開始されるたびに mit.edu
を通過し、hec.edu
を通過するようにしたい
使用例。hec.edu
には、セキュリティ上の理由から http://127.0.0.1:8001 にしかアクセスできない HTTP サーバがあります。LocalPC
でWebブラウザを開いてhttp://127.0.0.1:8001にアクセスできるようにしたい
Configuration
LocalPC
では、~/.ssh/config
で追加します
Host HEC
HostName hec.edu
User john
ProxyCommand ssh bob@mit.edu -W %h:%p
そして、LocalPC
のターミナルで実行します
ssh -D9991 HEC
bob
のパスワードをmit.edu
(つまりdylan123
)で聞き、john
のパスワードをhec.edu
(つまりdoe456
)で聞きます
その時点で、SOCKSプロキシはLocalPC
の9991
ポートで動作するようになりました
例えば、SOCKSプロキシを使ってLocalPC
のウェブページにアクセスしたい場合は、Firefoxで行うことができます
Some remarks:
~/.ssh/config
,HEC
は接続名です-D9991
は、ssh
にポート9991
にSOCKS4プロキシを設定するよう指示します
2 Franck Dernoncourt 2017-03-18
もし両方のマシンに SSH 接続できるのであれば、ssh の ProxyCommand ディレクティブを見てください。これを使うと、localhost から host2 に直接入ることができます (公開鍵を使うのであれば、一回のコマンドで簡単にできます!)。そうすれば、host2 でやりたいことが何でもできるようになります
0 None 2010-01-19
ベストアンサーのオプション2は、現在のものとは異なるsshユーザで使用することができます
export local_host_port=30000
export host1_user=xyz
export host1=mac-host
export host1_port=30000
export host2=192.168.56.115
export host2_user=ysg
export host2_port=13306
# Tunnel from localhost to host1 and from host1 to host2
# you could chain those as well to host3 ... hostn
ssh -tt -L $local_host_port:localhost:$host1_port $host1_user@$host1 \
ssh -tt -L $host1_port:localhost:$host2_port $host2_user@$host2
0 Yordan Georgiev 2017-10-05
私の場合は
localhost$ ssh -D 9999 host1
host1$ ssh -L 8890:localhost:8890 host2
ここで、host2:8890
はJupyter Notebook上で動作しています
そして、FirefoxをSOCKSホストとしてlocalhost:9999
を使うように設定してみました
ということで、今では私のマシンのhost2
でノートPCを起動し、localhost:8890
でFirefoxからアクセスできるようになりました
0 amarion 2018-07-26
受け入れられた回答に記載されている3つのオプションは、私のために全く動作しませんでした。私は両方のホストにあまり権限を持っていないので、私たちのDevOpsチームは認証に来るときにかなり厳格なルールを持っていて、MFAを行っているように見えます。どういうわけか、上記のコマンドは、私たちの認証ではうまく動作しません
本番サーバに直接sshすることができず、ジャンプサーバを使って1ホップしなければなりません
Yet Another Solution – ナイーブなもの
結局、私は非常にナイーブな方法でそれを行うことになりました: 私のラップトップ上ですべてのコマンドを実行しようとする代わりに、私は以下のように、それぞれのマシン上でコマンドを実行しています
- jumpサーバーにSSHして、
ssh -v -L 6969:localhost:2222 -N your-protected.dest.server
を実行します。パスワードの入力を求められたら、それを入力してください - 今、あなたのラップトップ上で、
ssh -v -L 6969:localhost:6969 -N your-jump-server.host.name
を実行します。これは、ラップトップ上のポート6969でのリクエストを、ジャンプサーバーに転送します。それから順番に、前のステップで設定したので、ジャンプサーバは再びポート6969のリクエストを保護された先のサーバのポート2222に転送します
いくつかのメッセージを印刷した後に、”hanggs “というコマンドが表示されているのを見るべきです。一つの例外 – Could not request local forwarding.
のようなエラーメッセージは表示されないはずですが、もし表示された場合はまだ動作していません。ラップトップからポート6969でリクエストを実行してみて、動作するかどうか確認してみてください
うまくいけば、あなたが上記のすべての方法に失敗した人であれば、おそらくあなたはこれを試すことができます
0 Shaung Cheng 2019-08-20
これだけは、二人以上のホストに助けられた
ssh -L 6010:localhost:6010 user1@host1 \
-t ssh -L 6010:localhost:6010 user2@host2 \
-t ssh -L 6010:localhost:6010 user3@host3
3つのパスワードを入力します
0 Vladimir Iashin 2020-02-22