Automating SSH or SFTP in scripts
Recently I needed to automate copying a MySQL database to a backup server. We keep a copy of our site and DB on this box in the event that our main systems go down, or there’s a problem with our internet connection. It’s kind of like a poor man’s colocation setup. I actually prefer the setup over true colocation for the vast majority of small and medium-sized business, because it’s far simpler and requires far less overhead and continuous support. When I started searching around for resources on how to automate the SFTP connection, I was hit in the face with tons of dead ends. Several Google searches were spitting back mailing list and forum archives of plenty of questions regarding how to create backup scripts that connect to a remote server via SFTP. If you are in this boat, read on. Here’s the problem. At some point in the development of SFTP, the writers decided that storing access credentials in files as part of an automated process was a very bad idea. So they coded SFTP to bypass the password challenge when invoked from a script (aka the -b flag, which runs commands from a file). Instead, they recommend that you create a private key pair between the two systems. This preemptive measure handshake eliminates the need for passwords entirely, making your code a bit simpler. It’s fairly easy to do but, of course, most developers groan at the thought of having to learn yet another technique, and looks for ways around the restriction. I did both, and recommend the key pair approach. I’ll describe both here, and let you decide for yourself. SSH/SFTP connection without passwords The following example is borrowed from an article on The Linux Problem Base, but there are several out there explaining the same approach. First log in on A as user a and generate a pair of authentication keys. Do not enter a passphrase:
a@A:~> ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/a/.ssh/id_rsa): Created directory '/home/a/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/a/.ssh/id_rsa. Your public key has been saved in /home/a/.ssh/id_rsa.pub. The key fingerprint is: 3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a@A
Now use ssh to create a directory ~/.ssh as user b on system B. The directory may already exist, which is fine:
a@A:~> ssh b@B mkdir -p .ssh b@B's password:
Finally append a’s new public key to b@B:.ssh/authorized_keys and enter b’s password one last time. Note that you must be looking at the local directory in which you saved the key in step one.
cd /home/a/ a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys' b@B's password:
From now on you can log into B as b from A as a without password. Try this to confirm:
a@A:~> ssh b@B hostname
It should return the hostname of system B without prompting for a password. It’s painless and easy, and every SSH connection you make going forward requires less typing. However, if you still really want to use a password, you have two options. Utilize the -o Flag So the SFTP team made their stance clear, and backed it up with action. However, it’s not impossible to bypass the restriction. The -o flag allows you to access all the options available in the sshd_config file, so you can change any of them on the fly. Here we need to disable the batchmode directive, so your SFTP call would look something like this:
sftp -o "batchmode no" -b /tmp/bat user@host
I found this one on a random forum post, and it comes with an important warning:
Note that it must come *before* -b, which may be surprising - this is
due to ssh processing -o options as if they were read from the config
file - ssh_config(5) again:
The only problem here is that the password challenge gets sent back out to the command line, requiring normal keyboard interaction. Use SSHPass So if that’s still not good enough for you, check out a SourceForge project called SSHPass. From the link:
Sshpass is a tool for non-interactivly performing password authentication with SSH's so called "interactive keyboard password authentication". Most user should use SSH's more secure public key authentiaction instead.
SSHPass is available from default Debian apt servers; I couldn’t find anything reliable on its availability through yum.
Proceed at your own risk. If you server allows any sort of public access, even to a large handful of outside users, I strongly recommend going the key route.
Update Feb 27, 2009: Reader pointed out that OpenSSH has a shortcut function,
ssh-copy-id, to install your public key on a remote machine. Nice.
comments powered by Disqus