Run Automated Scripts Over SSH

We’ve shown you how to use SSH to transfer files securely. But there’s a major issue with SSH’s default behaviour. You are only connected with the remote machine after you’ve manually entered the password which rules it out for any tasks you want to run unattended. Or does it?

Here’s a quick lowdown on how the OpenSSH CLI tools (scp and sftp) work so that you can better appreciate the issue. When you want to copy over files to or from the remote host, you can use scp which automatically initiates a SSH connection to the remote host. Every time you run a scp command it establishes a new connection to the remote. So if you have multiple scp commands you’d be entering the same password several times.

This is why you wouldn’t want to use scp in any scripts you want to run unattended. There’s also the fact that if you have multiple accounts on several machines on the network, you’d have trouble memorizing unique, strong passwords for each.

To overcome this problem, you need to switch OpenSSH’s default authentication mechanism to a key-based system.

Key to success

By default OpenSSH only uses keys to authenticate a server’s identity the first time a client encounters a new remote machine:

When you respond by typing “yes”, the remote host is added to the list of known hosts. So in addition to the server authenticating the client by asking for a password, the client also authenticates the server using a key.

Similarly, you too can get yourself a set of keys to prove your identity. OpenSSH uses a pair of keys to prove your identity and create a secure connection to a remote server. The private key is for-your-eyes-only and is used by your OpenSSH client to prove your identity to servers. Then there’s the public key which you’re supposed to keep under all your accounts on all the remote machines you want to SSH into.

To create a key, on your client enter:

Remember not to leave the passphrase empty and make note of the location where the keys are stored. The “id_rsa” file is readable only by your account, and its contents are encrypted with the passphrase you supplied during generation.

The next step is to copy the public key to the remote server. Assuming you wish to login into user “admin” on the remote machine called “”, you can move the keys with a single command:

After you’ve provided the passphrase for your private key, the public key will be automatically placed in the correct location on the remote server, which by default is the “~/.ssh/authorized_keys” file.

When you now ssh into the remote machine, you’ll be prompted for your passphrase. The only advantage of using keys is that instead of authenticating you with a password that’s transmitted unencrypted, the remote server and your client establish your identity based on the keys.

Also you can now ssh into several remote boxes using the same passphrase, as long as these remote machines have your public key. So you don’t have to remember multiple passwords.

But you still can’t run scripts without being interrupted for passphrases.

SSH-agent to the rescue

OpenSSH bundles a tool called ssh-agent, that keeps your private keys in memory. Once an agent is running, instead of prompting you for passphrases, the SSH clients will interact with the agent.

You can start the agent with “ssh-agent /bin/bash“, assuming you are using the bash shell.

Any commands which require access to your OpenSSH private keys will be intercepted and answered by the agent.

When the agent runs, you need to equip it with your keys. This is done by invoking the “ssh-add” program that by default loads the keys from the default identity file (~/.ssh/id_rsa).

Now when you log into the remote computer with “ssh“, you’ll be allowed without entering the passphrase!

Similarly, scp and sftp will also be able to connect to the remote hosts without ever asking you for a passphrase. So you can now schedule and run scripts that manipulate files on a remote machine automatically.

Also now that you are using keys, it’s a good idea to disable authentication via passwords. To do this, edit the remote server’s config file (/etc/ssh/.sshd_config) and change the “PasswordAuthentication” parameter from “yes” to “no”. From now on, if anyone tries to connect to your SSH service who doesn’t have a public key on the server, they will be denied access without even seeing the login prompt.

Image credit: Karunakar Rayker

Mayank Sharma

Mayank Sharma has been writing on Linux for over a decade and is a regular contributor to Linux Format magazine.


  1. The only problem with using SSH-agent to enter your passphrase is that you have to remember to run it before running scripts/ssh/scp/sftp/whatever. If you create the keys *without* a passphrase, then you can do everything without needing another program running and sucking up resources. Not using a passphrase makes the keys *slightly* less secure…but not enough to make any *real* difference.

  2. Agree about not forgetting to run SSH-agent beforehand. We just run with “no passphrase” — it’s easier — from one master server and one master account. Break IT and you’re IN; break elsewhere and you’re there but nowhere else. And that server’s watched and audited. (Well they all all but you know what I mean.)

    Now, error in the text: “advantage of using keys is that instead of authenticating you with a password that’s transmitted unencrypted”. BZZZZT, wrong. Unless you switched to talking about telnet and I missed it.

    A temporary secure channel between points is established at connection time. (And the “new server” prompt indicates a possible MitM attack, but since you’re connecting for the first time and don’t have out of band data you just have to trust it.) Not that connection is AUTHENTICATED or anything, the server has no idea (yet) who you are and if you’re really got valid credentials. But those credentials themselves are passed over encrypted.

    The “advantage of using keys” is that with a password (passphrase) it is technically possible for someone to guess/generate your password with 100s-ish bits of search space. With a key you can generate 1000s-ish of bits, and no one is going to be able to brute force break it.

    In effect though they are the exact same thing, just one is longer and stored somewhere.

    Let’s say A-Za-z0-9 and + and – are your encoding characters. Each one has 6 bits of random data if. (Dictionary and known words lower that somewhat.) A 128-bit password has 21 chars, for 256 it’s 42. A typing English word is 5 chars or 30 bits, so 128-bit is 4 words and 256 is 8 words. Really, really hard but not impossible, especially if you used easily guessed words. (“How Now Brown Cow” — who hoo, I’m in! In the movies though, “PASSWORD” or “OVERRIDE” seems to be the password of choice.)

    A 4096-bit key, easily generated, is 680 characters or 135 words that you’d have to type. Shorter than “War and Peace”, but not by much. And: no typos, or start over from scratch. At 20 WPM that’s 7 minutes of typeo-less :-) typing just to login once.

    SSH-agent is great for attended sessions but if your server has an unattended start (crash / power outage) then at startup, nothing can connect anywhere until someone gets to that box. For servers, it’s keys and empty passphrases for us.

    (And: “ssh-copy-id” is a nice timesaver, but DIY is not that harder. DIY works _everywhere_, new, old, and ancient systems alike.)

  3. I have found the hard way that if ChallengeResponseAuthentication is not also No, then password logins still work.

    Not the best reference, but

Comments are closed.