2番目のリモートホストでscpする方法


83

remote1ホストを経由して、ローカルマシンからremote2ホストから直接ファイルをSCPする方法があるのだろうか。

ネットワークは、remote1ホストからremote2ホストへの接続のみを許可します。また、remote1ホストもremote2ホストもローカルマシンにscpできません。

次のようなものはありますか?

scp user1@remote1:user2@remote2:file .

最初のウィンドウ:ssh remote1、次にscp remot2:file .

2番目のシェル: scp remote1:file .

最初のウィンドウ: rm file; logout

これらすべての手順を実行するスクリプトを作成することもできますが、直接的な方法がある場合は、それを使用したいと思います。

ありがとう。

編集: SSHトンネルを開くようなことを考えていますが、どの値をどこに置くかについて混乱しています。

現時点では、アクセスするために、ローカルマシンにremote1次のものがあります$HOME/.ssh/config

Host remote1
   User     user1
   Hostname localhost
   Port     45678

オンremote1にすると、アクセスするremote2には、標準のローカルDNSとポート22になります。何をオンremote1または変更する必要がありlocalhostますか?

回答:


95

1つのコマンドでファイルを直接コピーする方法はわかりませんが、バックグラウンドでSSHインスタンスを実行して、ポート転送トンネルを開いたままにしておくことができれば、1つのコマンドでファイルをコピーできます。

このような:

# First, open the tunnel
ssh -L 1234:remote2:22 -p 45678 user1@remote1
# Then, use the tunnel to copy the file directly from remote2
scp -P 1234 user2@localhost:file .

最初のインスタンスがへの転送接続をリッスンしているのはローカルホストのポート1234であるためuser2@localhost、実際のscpコマンドと同じように接続することに注意してください。後続のファイルコピーごとに最初のコマンドを実行する必要がないことにも注意してください。単に実行したままにすることができます。sshremote2


1
おかげで、これは私が必要とするものに近いようです。トンネルを作成しました。フィンガープリントはサーバーのフィンガープリントと一致しますが、「Permisiondenied(publickey)」エラーが発生します。ネットワーク/システム管理者になぜ機能しないのかを尋ねる必要があると思います。
danosaure 2012

3
ありがとう!remote1 SSHがポート22をリッスンしているため、に変更-p 45678する必要がありました-p 22
Montaro 2015年

また、の-p 22代わりに使用する必要がありました-p 45678。またscp -P 1234 ...、私にはうまくいきません。取得していssh: connect to host localhost port 1234: Connection refusedます。試してみるとscp -P 22 ...動作しますがremote 1、ローカルマシンではなくファイルをコピーしています(remote2)。
罪人

同じためのUIツールはありますか?
ExploringApple

70

ダブル ssh

複雑な場合でも、ssh;-)を使用するだけで、単一のコマンドラインを使用してファイル転送を処理できます。
これはremote1、に接続できない場合に役立ちますlocalhost

ssh user1@remote1 'ssh user2@remote2 "cat file"' > file

tar

ただし、ファイルのプロパティ(所有権、アクセス許可など)は失われます。

ただし、tarこれらのファイルプロパティを保持するのはあなたの友達です。

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar c file"' | tar x

圧縮してネットワーク帯域幅を減らすこともできます。

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj file"' | tar xj

またtar、基本的な方法で再帰ディレクトリを転送することもできますssh

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj ."' | tar xj

ionice

ファイルが巨大で、他の重要なネットワークアプリケーションを妨害したくない場合は、ツールによって提供されるネットワークスループットの制限を見逃す可能性がscpありrsyncます(たとえばscp -l 1024 user@remote:file、1メガビット/秒を超えて使用しない)。

ただし、回避策はionice、単一のコマンドラインを維持するために使用しています。

ionice -c2 -n7 ssh u1@remote1 'ionice -c2 -n7 ssh u2@remote2 "cat file"' > file

注:ionice古いディストリビューションでは利用できない場合があります。


すべての説明に感謝しますが、Dolda2000のソリューションの方が簡単だと思います。それは私が試していたものでしたが、理解できませんでした。
danosaure 2012

5
これは見事に良い答えであり、より多くの投票に値します。また、私の意見では、受け入れられた答えよりもはるかに簡単です。
Rik Smith-Unna

2
私はこれが受け入れられた答えよりも良い解決策であることに同意します。このようにして、接続は自動的にクリーンアップされます。
ダグ

ありがとう、とてもいい答えです!逆に、ローカルからリモートにコピーするのはどうですか?
domTomCat 2018

31

これでうまくいきます:

scp -o 'Host remote2' -o 'ProxyCommand ssh user@remote1 nc %h %p' \ 
    user@remote2:path/to/file .

ホストからファイルをremote2直接SCPするには、2つのオプション(HostおよびProxyCommand)を〜/ .ssh / configファイルに追加します(スーパーユーザーに関するこの回答も参照してください)。次に、実行できます。

scp user@remote2:path/to/file .

を考えることなく、ローカルマシンからremote1


いいアプローチ!でも-o 'Host remote2'(すなわちの〜/ .ssh / configに触れることなく一度にコピーするために)をコマンドラインから起動するときに本当に必要とされていないようだ
マイク

こっちも一緒。これは私のために働く-o 'Host remote2'ます。ありがとう。
罪人

7

opensshバージョン7.3以降では、簡単です。構成ファイルでProxyJumpオプションを使用します。

# Add to ~/.ssh/config 
Host bastion
    Hostname bastion.client.com
    User userForBastion
    IdentityFile ~/.ssh/bastion.pem

Host appMachine
    Hostname appMachine.internal.com
    User bastion
    ProxyJump bastion                   # openssh 7.3 version new feature ProxyJump
    IdentityFile ~/.ssh/appMachine.pem. #no need to copy pem file to bastion host  

ログインまたはコピーするために実行するコマンド

ssh appMachine   # no need to specify any tunnel. 
scp helloWorld.txt appMachine:.   # copy without intermediate jumphost/bastion host copy.** 

もちろん、設定ファイルで設定されていない場合は、オプション「-J」を使用してsshコマンドに要塞ジャンプホストを指定できます。

現在、scpは「-J」フラグをサポートしていないようです。(manページで見つかりませんでした。ただし、上記のscpは設定ファイルの設定で機能します)


1
要塞サーバーがプロキシにのみ使用される場合(つまり、異なるIdentityFileなどがない場合)、構成ファイルに要塞サーバーを追加する必要はありません。単にProxyJumpbastion.client.comをappMachineセクションに追加します。
Tomer Cohen 2018

1

scp非常に便利な、まったく同じジョブに最近追加する新しいオプションがあります-3

TL; DR ssh構成ファイルで認証がすでに設定されている現在のホストの場合は、次のようにします。

scp -3 remote1:file remote2:file

君の scpは最近のバージョンのものでなければなりません。

上記の他のすべての手法では、remote1からremote2に、またはその逆に認証を設定する必要がありますが、これは必ずしも良い考えではありません。
引数-3は、現在のホストを仲介として使用して2つのリモートホストからファイルを移動することを意味します。このホストは実際には両方のリモートホストに対して認証を行うため、相互にアクセスする必要はありません。
ssh設定ファイルで認証を設定する必要があります。これはかなり簡単で十分に文書化されており、TL; DRでコマンドを実行するだけです。

この回答のソースはhttps://superuser.com/a/686527/713762です


0

この構成は私にとってうまく機能します:

Host jump
   User username
   Hostname jumphost.yourorg.intranet
Host production
   User username
   Hostname production.yourorg.intranet
   ProxyCommand ssh -q -W %h:%p jump

次に、コマンド

scp myfile production:~

myfile本番マシンにコピーします。


0

これを使用して作業したOlibreのソリューションへの小さな追加ソース。

tarリモートホストからローカルへのコピーに使用する3つの方法があるのと同様に、ダブルsshの状況でのローカルホストからリモートホストへのコピーでは、次のように機能しますファイルからコピーする必要がディレクトリ、そうでない場合はフルパスを使用します/ファイル名)

圧縮せずに単一のファイルを転送します。

tar c filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar x"'

圧縮を使用して単一のファイルを転送します。

tar cj filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

再帰的なディレクトリ転送:

tar cj . |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

ここでの&&は、コマンドの前半が機能しない場合、たとえばディレクトリが欠落している場合や、送信元/宛先パス名にエラーがある場合に、コマンドが実行されないようにします。

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