I have a file on my local computer I wish to copy to a remote server using the SSH program (not scp, not rsync, not sftp), the local file is an SSL private key and I do not want to create any temporary copies on the remote server during the transfer.

The root user on the remote server cannot login via SSH for security reasons, however my remote user (with the same username as my local user) can make root changes through the sudo command after a password prompt.

Problem: How do I copy the local file, login via SSH, switch to the root user with sudo password prompt and then write the file to the remote server in a root user owned directory? And preferably all in a single line command!

  • scp and sftp both run over ssh, so are equally secure. – user1751825 Feb 28 '16 at 11:48
  • @user1751825 The question is not about transfer security, but about the security of temporary storing file on the remote side. – Jakuje Feb 28 '16 at 12:26

cat is your friend:

cat key | ssh user@host sudo "cat > final_location"

But this would require passwordless authentication (might overcome using ControlMaster) and passwordless sudo (NOPASSWD or authentication using pam_ssh_agent_auth -- I recommend to give a try this one, if you are familiar with ssh-agent).

You might also want to temporary allow root logins (with public key -- there is option PermitRootLogin without-password, which does exactly what you want) and then you can simply use the scp method.

Otherwise I don't think there is any other reasonable way, except of Copy Paste method.

  • The password-less authentication problem can be overcome by using a BASH variable instead of redirecting STDIN and telling ssh to associate a TTY on the remote machine. See my answer below. – Andrew Young Mar 21 '16 at 16:22
  • Sorry this doesn't help, I don't want to enable passwordless sudo or have to make configuration changes to sshd to allow cat with sudo prior to simply wanting to securely copy a file. I have access to the file locally, I have access on the remote side with sudo, I'm looking for the 'out of the box' answer that works just about everywhere without system config changes. – Run.dll May 10 '16 at 1:49

This will do what you want it to do. Notice the -t option that is passed to ssh. This assigns a TTY so that the sudo password prompt works properly.

TEXT=`cat ~/.ssh/id_dsa.pub` ssh user@host -t sudo "bash -c \"echo '$TEXT' > foo.pub\""

This works as long as there are no single quotes in the input data. If there are, you can use base64 to encode/decode the data during transmission.

TEXT=`base64 ~/.ssh/id_dsa.pub` ssh user@host -t sudo "bash -c \"echo '$TEXT' | base64 -d > foo.pub\""
  • Replace "foo.pub" with the full path of the file you want to write to on the remote machine and replace "~/.ssh/id_dsa.pub" with the file to read from the local machine. (But it sounds like you're sending SSH keys.) – Andrew Young Feb 29 '16 at 22:18
  • The file is created after sudo prompt, but the file is empty on the remote side, the contents didn't make it. – Run.dll May 10 '16 at 1:53
  • weird, $ TEXT=`base64 test.txt` echo $TEXT is empty, but $ base64 test.txt returns aGVsbG8gd29ybGQK, GNU bash, version 4.3.11, ideas? – Run.dll May 10 '16 at 2:03
  • That's weird, the same command works properly for me on GNU bash, version 4.3.42. I can't imagine the two are that different. Make sure that there are no spaces between TEXT the equals sign and the backtick. – Andrew Young May 11 '16 at 20:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.