中間ホスト経由のscpファイル


85

A、B、Cの3台のマシンにアクセスできます。可能な(ssh)接続は次のとおりです。

A -> B
B <-> C

AからCにファイルを取得する必要があるため、AからBにファイルをscpし、次にBからCにscpすることができます。ただし、Bには十分なディスク領域がないため、これはオプションではありません。B経由でAからCにファイルをscpする方法はありますか?私はどのマシンにもルートアクセス権がないため、永続的なトンネルをセットアップできるとは思わないが、間違っている場合は修正してください!


6
私はこれが質問に答えないことを知っていますが、rsyncについて知らない人、またはホストを介してホップするためにそれを使用する方法を知らない人にとって、これは有用なヒントかもしれません: '-e'オプションを使用してください次のようなrsyncを使用:A$ rsync <options> -e 'ssh B ssh' source C:destination
14

回答:


108

ProxyJump

OpenSSH 7.3の新機能:

A$ scp -oProxyJump=B thefile C:destination

(舞台裏では、これはProxyCommandとssh -W

ProxyCommand

他の回答の-Wを含むように更新されました。

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

Aに非常に古いSSHクライアントがインストールされている場合(-Wサポートなし)、またはBがTCP転送を許可しないように構成されている場合(シェルコマンドは引き続き許可されている場合)、代替手段を使用します:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

パイプ

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

1つのファイルのみ:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

「トンネル」からB

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

完了したら、以前に開始したsshプロセス(のためにバックグラウンドに落ちた-f -N)を強制終了することを忘れないでください。

  • -fコマンド実行の直前にバックグラウンドに移動するようにsshに要求します。これは、sshがパスワードまたはパスフレーズを要求するが、ユーザーがバックグラウンドでそれを望む場合に便利です。これは、-nを意味します。
  • -Nリモートコマンドを実行しないでください。これは、ポートを転送するだけの場合に便利です。

BからAへの逆「トンネル」

ただし、常に機能するとは限りません。

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R リモート(サーバー)ホスト上の指定されたTCPポートまたはUnixソケットへの接続が、ローカル側の指定されたホストとポート、またはUnixソケットに転送されることを指定します。

これらの例@grawityに感謝します。一つの質問-`tar c thefile anotherfileを反転させることは可能ですか?ssh B "ssh C \" cd destination && tar xv \ ""
´´

@dmeu:ええ、可能です。
悲しみ

MacOSを使用していると言った場合、以前に開始したsshプロセスを「強制終了」する方法
エアロウィンドウォーカー

注意:いつものように、あなたがしたい場合scp から C、けれども B、 A、あなたが行うことができますA$ scp -oProxyJump=B C:destination thefile
jvriesem

@Pabloベターは-Sを使用してから、-Oを終了します。または...少なくともpkill -f。
-grawity

24

2011年初頭以降のscpのバージョンには、「-3」オプションがあります。

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

これがある場合は、単に実行できます:

B$ scp -3 A:file C:file

私の場合、ホストAはB(VPNされた)からのみアクセスできました。ホストCはBと同じLAN上にありました。AからCにファイルを取得したかったため、scp -3が見事に解決しました。
ジョー

両方のホストがパスワードを要求したときに、これで問題が発生しました。両方を一度に要求するようで(同じ行に2つのパスワードプロンプトが表示されます)、パスワードを受け入れられませんでした。パスワードを繰り返し入力することで(両方のホストで同じパスワード)、最終的には機能するようになりましたが、把握するのは困難でした。
コリンD

8

ほぼすべては、すでに述べたが、ここで私の最後のペニーですされています:私はなしのProxyCommandバリアントを使用しncたりsocOpenSSHプロキシとJumphostクックブックに基づいて、次の構成を作成しました。

  1. 次のプレーヤーがいます。

    • HOME_HOST:ファイルをターゲットホストにコピーする場所です
    • HOP_HOST:このホストを介してコピーます(HOP_USERとして記録されます)
    • TARGET_HOST:宛先です(TARGET_USERとして認証されます)
  2. 最初に私は私の自宅のホストからの私の地元の公開鍵を追加.ssh/id_dsa.pub.ssh/authorized_keys、両方のホップホストとターゲットホストで。はい、ホームホストから両方のホストへの同じ公開キー。通常は、TARGETに追加する必要があるHOP公開キーであると予想されます。

  3. 次に.ssh/config、次のエントリを追加して少し調整しました。

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. その後、コピー操作は次のように簡単ですscp FILE TARGET_HOST:。ホップノードとターゲットノードの両方からの二重バナーが表示されますが、機能します。

もちろん、上記を使用してターゲットに直接sshすることもできますssh TARGET_HOST。scpとsshで動作します。

別のより一般的なオプションは、sshuttleユーティリティです。これは、一種の透過プロキシ(vpn over ssh)のように見えます。A-> B <-> Cの場合、Cのネットワークの各ノードに接続できます:A-> B- [CDEFG]。adminは必要ありませんが、Python 2.7(3.5もOK)が必要です。試してみる価値はあります。


7
ssh -L 4321:hostC:22 youruser@hostB

別のシェルで:

scp -P 4321 localfile youruser@127.0.0.1

これはポート転送を使用しています。ここでの唯一の制限は、ポートBを許可するようにホストBを構成する必要があることです。それ以外の場合、これは正常に機能するはずです。

説明のように、-Lそして-Rあなたがポートを転送することができます。で-L指定された最初のポートは、sshが発信元マシン(ホストA)でリッスンを開始するポートであり、SSH接続を介してそのポートで受信したものをホストBに転送し、ポート22でホストCにルーティングします。

編集する

構文を少し台無しにしました。LOCALマシンで転送を設定します。


@astrofrog-答えの1つがニーズを満たしている場合、おそらくそれらの1つを受け入れる必要があります。
ブライアンヴァンデンバーグ

2

GrawityのProxyCommandの回答は私にとってはうまくいきましたが、SSHにあまり詳しくないので、いくつかの実験が必要でした。Grawityの答えをもっと詳しく説明して、他の初心者が自分のようなSSHを手伝うようにすると思いました。より明示的な表記法の定義は次のとおりです。

マシンA:使用しているマシン

サーバーB: userB@ip.address.for.B(ジャンプホストまたはミドルサーバー)

サーバーC: userC@ip.address.for.C(コピー先のリモートサーバー)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p userB@ip.address.for.B" thefile userC@ip.address.for.C:destination

具体例

したがって、具体的な例として、(Server C)0.0.1.2という名前のユーザーアカウントを持つIPを持つサーバーにアクセスできるとしますbar。ただし、それに到達するには、最初に(Server B)0.0.1.1という名前のユーザーアカウントでIP を使用してサーバーにログインする必要がありますfoo。次にbaz.txt、現在のマシン(マシンA)にあるファイルをサーバー0.0.1.2/home/bar/ディレクトリにコピーします。この例で上記のProxyCommandを使用するには、次を実行します。

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" baz.txt bar@0.0.1.2:/home/bar/

ファイルと宛先の順序を切り替えることにより、サーバーCからファイルを簡単にコピーすることもできます。したがって、たとえば、baz.txt既にあるサーバーに0.0.1.2ある場合は、/home/bar/次を使用してマシンにコピーできます。

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" bar@0.0.1.2:/home/bar/baz.txt /destination/path/on/A

これが、他の人よりも少し詳しく説明する必要がある人に役立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.