Originally published August 9, 2019 @ 8:02 pm
Consider this not-so-hypothetical scenario: you have some data on server_a
that you would like to copy to server_b
. Unfortunately, these two servers cannot communicate with each other. Nor do they have access to any common network-mounted storage. Bummer. I do have a jumpbox from which I can SSH to either server using a service account with passwordless root sudo
privileges.
Such accounts often exists in environments that utilize CMS tools and other types of centralized automation. Normally I would SSH to server_a
; make a tarball of whatever I need; logout back to the jumpbox; SCP the tarball to the jumpbox; SCP it further to server_b
; SSH there and untar; finally, delete the tarballs from all three systems.
This multi-step process is tedious, not very secure, and sometimes requires considerable additional filesystem space. Now imagine a few files changed on the source and you need to transfer just those changes. Ugh…
A much better option is to use sshfs
(yum install sshfs
). The little script I have below was written for RHEL/CentOS 5-7 and has a couple of prerequisites: a) you have a server that can connect to both server_a
and server_b
via SSH with key authentication only using a common service account; b) this service account on both server_a
and server_b
can sudo - root
without being prompted for a password.
The basic command syntax is quite simple:
g source:/path/[file] target:/path/
The script will SSH to source
and to target
and will run sftp-server
on both as root. This would allow you to mount filesystems from both machines with root privileges. The script will then create target:/path/
if it doesn’t already exist. Finally, the script will run a basic rsync
archive operation to transfer data. The temporary mounts on your jumpbox will then be unmounted and removed.
You can also download this script from my GitHub page. Copy it to a folder of your choice and make a convenient link, say, /sbin/g
.
#!/bin/bash # # | # ___/"\___ # __________/ o \__________ # (I) (G) \___/ (O) (R) # Igor Os # igor@comradegeneral.com # 2019-08-09 # ---------------------------------------------------------------------------- # Just a quick way of copying files/folders from any to any server using your # automation service account. This acconut would need passwordless sudo # # Syntax: # g <source_host>:/<path>/[filename] <target_host>:/<path>/ # if "<target_host>:/<path>/" does not exist, it will be created. # # Example: # root@saltmaster# g dev-tomcat01:/etc/ntp/ prod-tomcat02:/etc/ntp_from_dev-tomcat01/ # # CHANGE CONTROL # ---------------------------------------------------------------------------- # 2019-08-09 igor wrote this script # ---------------------------------------------------------------------------- rnd="${RANDOM}" u="service_account" rsa_id="$(find /home/${u}/.ssh -mindepth 1 -maxdepth 1 -type f -name "id*rsa" | head -1)" if [ ! -r "${rsa_id}" ]; then exit 3; fi ssh_opt="-qtT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=3 -o BatchMode=yes -i ${rsa_id}" sshfs_opt="allow_other,IdentityFile=${rsa_id},UserKnownHostsFile=/dev/null,StrictHostKeyChecking=no" if [ ! -z "" ] && [ ! -z "" ] then s="" s_host="$(awk -F':' '{print $1}' <<<"${s}")" s_node="$(awk -F':' '{for(i=2;i<=NF;++i)print $i}' <<<"${s}")" s_dir="$(awk -F'/' -v OFS='/' '{$NF=""; print $0}' <<<"${s_node}")" s_file="$(awk -F'/' '{print $NF}' <<<"${s_node}")" t="" t_host="$(awk -F':' '{print $1}' <<<"${t}")" t_dir="$(awk -F':' '{for(i=2;i<=NF;++i)print $i}' <<<"${t}")" else exit 1 fi s_mnt="/mnt/source/${s_host}_${rnd}" t_mnt="/mnt/target/${t_host}_${rnd}" mkdir -p "${s_mnt}" "${t_mnt}" /usr/bin/ssh ${ssh_opt} ${u}@${t_host} "sudo su - root -c 'mkdir -p \"${t_dir}\"'" 2>/dev/null 1>&2 sshfs -o ${sshfs_opt} ${u}@${s_host}:${s_dir} ${s_mnt} -o sftp_server="/usr/bin/sudo /usr/libexec/openssh/sftp-server" sshfs -o ${sshfs_opt} ${u}@${t_host}:${t_dir} ${t_mnt} -o sftp_server="/usr/bin/sudo /usr/libexec/openssh/sftp-server" if [ $(mountpoint "${s_mnt}" 2>/dev/null 1>&2; echo $?) -eq 0 ] && [ $(mountpoint "${t_mnt}" 2>/dev/null 1>&2; echo $?) -eq 0 ] then if [ ! -z "${s_file}" ] then rsync -aqKx "${s_mnt}/${s_file}" "${t_mnt}"/ else rsync -aqKx "${s_mnt}"/ "${t_mnt}"/ fi umount -f ${s_mnt} ${t_mnt} fi /bin/rmdir "${s_mnt}" "${t_mnt}"
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.