SCP files from one host to another

Everyone knows how to copy files around using SCP, but it can be a pain if you have to enter passwords for every copy. If you have an administration host with shared ssh keys to every other host, you can just use a quick little one liner to drag files from hostA, through the admin box, over to hostB:

adminbox # ssh hostA "tar cf - /usr/local/sbin/myscript.sh 2>/dev/null" | ssh hostB "cd / && tar xvf - 1>/dev/null"

Using tar, the file is output to STDOUT and piped over ssh, then read from STDIN. It copies /usr/local/sbin/myscript.sh from hostA to hostB. Because the admin box has ssh keys to both hostA and hostB, the process is automatic and does not require password authentication. This means you can use this method in scripts for batch copies, etc. Also, you won’t have to create a temporary copy on the admin host.

Drop it into a simple shell script and it will be even easier:

#!/bin/bash
# FILE: file_dragger.sh
# AUTHOR: fordodone <fordodone at email.com>
# DATE: 2013/07/11
# NOTES: drags a file from one host to another
#

if [ $# -ne 3 ]
then
echo ""
echo "usage: </full/path/to/file> <src> <dst>"
echo ""
exit
fi

ssh $2 "tar cf - $1 2>/dev/null" | ssh $3 "cd / && tar xvf - 1>/dev/null"

To use it for the original copy example do this:

# file_dragger.sh /usr/local/sbin/myscript.sh hostA hostB
#

From time to time you might encounter a failure message about SSH and host identification. SSH remembers the fingerprint of keys of other hosts it connects to. It stores these keys in a file, so that if the fingerprint changes you will hear about it. This can happen with some DHCP addresses. For example, HostA has a DHCP address of 192.168.1.102. You change HostA’s IP address, to a static address, and the lease for 192.168.1.102 expires. Then you bring up HostB and it gets the DHCP address of 192.168.1.102. When you go to ssh to 192.168.1.102, you get an error. That’s because SSH recognizes that it’s a different host altogether. This helps prevent in MIM attacks, or IP spoofing. In this case we know what’s going on, so it’s safe to remove the old fingerprint for HostA and reconnect to HostB subsequently storing it’s fingerprint.

# ssh 192.168.1.102
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
34:6e:16:28:90:21:bd:6a:80:e4:97:41:85:ef:4a:ad.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:15
ECDSA host key for 192.168.1.102 has changed and you have requested strict checking.
Host key verification failed.
#

One way to fix this is to use vi to edit the known_hosts file. Use the :15 command to navigate to line 15 and use dd keystroke to remove this entry, then :wq to save and quit vi.

Another alternative is to use sed to remove line 15:

# sed -i '15d' /root/.ssh/known_hosts
#

Also, the ssh-keygen utility comes with this built in:

# ssh-keygen -f '/root/.ssh/known_hosts' -R 192.168.1.102
/root/.ssh/known_hosts updated.
Original contents retained as /root/.ssh/known_hosts.old
# 

append file with wget

To append a file with one fetched from a URL, use wget and output to STDOUT then redirect and append where needed.

# wget -q 'http://10.11.178.141/all_pub_keys' -O - >>/root/.ssh/authorized_keys

In this case I wanted to add some public keys to an existing authorized_keys file.

rsync on different ssh port

By default ssh runs on TCP port 22. If you have a ssh configured to listen on a non standard port, you may need a special option to make rsync connect to that port. I was writing a quick backup script for this worpress site, and ran into this issue. In my case I was trying to rsync to a remote server with ssh listening on 4590. You have to give rsync a special ssh option:

# rsync -a --rsh='ssh -p 4590' /srv/www/wp-uploads/ backupsite.com:/backups/wp/wp-uplodas