When issuing a command such as scp host1:file host2:. I observed public key authentication succeeding on host1, but failing on host2. It was through digging into the verbose output that I discovered that commands formatted as such are essentially equivalent to ssh host1 scp file1 host2:. with the additional constraint that agent forwarding is explicitly disabled through a -o option. My expectation was that it would be more equivalent to ssh host1 tar cf - file1 | ssh host2 tar xf - or using scp syntax, something like ssh -x -t host1 scp -f file1 | ssh -x -t host2 scp -t . but I was unable to get that particular syntax to work. The reasons for this expectation are: 1. agent forwarding: I may not trust host1, so don't want to forward my agent onto that host, but still may need it for access to host2. 2. accessible networks: I may not be able to reach host2 from host1, but can reach both hosts from the localhost I'm running scp on. 3. DNS resolution: host2 may resolve to different IPs on the localhost versus on host1. That difference would not be obvious to the user without close examination of the verbose output. 4. Obvious test: "scp host1:file ." and "scp file host2:." both work, but combining them into a single command does something completely unexpected, and breaks. I realize that, under the behavior I expected, the localhost running scp would act simply as a conduit for two remote connections, which may be perceived as wasting bandwidth on that host, but that behavior is precisely what I needed, and is how I expected it to act based simply on the format of the command. If I had wanted to transfer directly from host1 to host2, I would have run it's sensible equivalent of ssh host1 scp file1 host2:. The bug summary is a little misleading, as it doesn't describe my expectations as explained above, but it does show the symptom that led to me filing this bug report. My hope is that it will make searching for the symptom easier for confused end users such as me. Feel free to change if you find a better way of summarizing this. The tar solution allows me to work around this, so I wouldn't consider this a severe issue. Documenting this format more completely may be sufficient, but as it is, there is no solution I know of using only ssh/scp equivalent to what the tar solution gives me. If most people are like me, they wouldn't think using two remote paths would form a chain from localhost to host1 then to host2; they would assume the path is from host1 through localhost to host2.
I agree that the current behavior when two remote hosts are specified is unexpected, illogical, and should be considered a bug. The "scp" manual page says that "Copies between two remote hosts are also permitted.". This is not quite the case - and if the current behavior remains (and I think it shouldn't...), it should at least be explained. The reason I think the current behavior is NOT useful, is that on today's internet, security is rarely symmetrical: The fact that host A can ssh to host B and to host C, doesn't mean that B and C can ssh back to A, or ssh between themselves. So when I do on host A 'scp B:... C:...', I certainly don't expect B and C to communicate directly - if I wanted to do that I would have written "ssh B -c scp ... C:". When I go and run 'scp B:... C:...' on A, I fully expect all the data to pass through A. scp B:... C:... could have been very useful when I want to transfer a large remote file between B and C, without keeping a copy on A and when B and C cannot communicate directly (because of routing or authentication issues).
Created attachment 1963 [details] openssh-scp-remotetoremote.patch Only set ForwardAgent=no for local-to-remote and remote-to-local cases.
Comment on attachment 1963 [details] openssh-scp-remotetoremote.patch Ignore that patch, it's rubbish. On further investigation there's some more work required. In the mean time if you want a workaround, try adding: Host yourhost ForwardAgent yes to your ~/.ssh/config file and see if that helps
Created attachment 1966 [details] /home/djm/scp-propagate-opts.diff propogate commandline options on remote-remote copies
Yes, we agree that this behaviour is stupid. Unfortunately, scp just rcp, which is 27 years old and is widely understood to behave exactly as it does. If we change it then we will break users' expectations and scripts. We aren't really interested in extending scp either. It implements no backwards compatibility mechanisms and the code is unpleasant to work on. That being said, the current behaviour of scp is broken in that it doesn't propagate options from the commandline to the ssh command used to invoke the remote-remote copy. This stops a user from manually specifying that they want to forward their agent on the commandline (doing it in the config file already works ok). The patch I just attached fixes this.
Comment on attachment 1966 [details] /home/djm/scp-propagate-opts.diff >+ addargs(&remote_remote_args, "-oBatchmode yes"); > addargs(&args, "-oBatchmode yes"); Is that going to work? I would expect it to get parsed as 2 args by the remote shell and broken into '-oBatchmode' and 'yes' then have ssh choke on a missing arg to BatchMode.
easy fix: s/ /=/
Created attachment 1968 [details] /home/djm/scp-propagate-opts.diff revised patch
Patch applied, but as I mentioned we can't/won't make further alterations to scp.
Markus reminds me that we can open two connections (to source and destination host) without requiring any protocol changes, so the only thing to overcome here is the code smell.
The -3 option to establish connections to both source and destination from the local host was added back in openssh-5.7.
Close all resolved bugs after 7.3p1 release