Recipe 6.10 Authenticating in cron Jobs
6.10.1 Problem
You want to invoke unattended remote
commands, i.e., as cron or batch jobs, and do it securely without any
prompting for passwords.
6.10.2 Solution
Use a plaintext key and a forced command.
Create a plaintext key:
$ cd ~/.ssh
$ ssh-keygen -t dsa -f batchkey -N "Install the public key (batchkey.pub) on the
server machine. [Recipe 6.4]Associate a forced command with the public key on the server machine,
to limit its capabilities:~/.ssh/authorized_keys:
command="/usr/local/bin/my_restricted_command" ssh-dss AAAAB3NzaC1kc3MAA ...Disable other capabilities for this key as well, such as forwarding
and pseudo-ttys, and if feasible, restrict use of the key to a
particular source address or set of addresses. (This is a single line
in authorized_keys, though it's
split on our page.)~/.ssh/authorized_keys:
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty, from="myclient.
example.com", command="/usr/local/bin/my_restricted_command" ssh-dss
AAAAB3NzaC1kc3MAA ...Use the plaintext key in batch scripts on the client machine:
$ ssh -i ~/.ssh/batchkey remotehost ...
Alternatively, use hostbased authentication [Recipe 6.8] instead of public-key authentication.
6.10.3 Discussion
A plaintext key is a cryptographic key with no
passphrase. Usually it's not appropriate to omit the
passphrase, since a thief who steals the key could immediately use it
to impersonate you. But for batch jobs, plaintext keys are a
reasonable approach, especially if the key's scope
can be restricted to specific remote commands. You create a plaintext
key by supplying an empty password to the -N
option:
$ ssh-keygen -t dsa -f batchkey -N "
A forced command is a server-side
restriction on a given public key listed in
~/.ssh/authorized_keys. When someone
authenticates by that key, the forced command is automatically
invoked in place of any command supplied by the client. So, if you
associate a forced command with a key (say,
batchkey) with the following public component:
~/.ssh/authorized_keys:
command="/bin/who" ssh-dss key...
and a client tries to invoke (say) /bin/ls via
this key:
$ ssh -i batchkey remotehost /bin/ls
the forced command /bin/who is invoked instead.
Therefore, you prevent the key from being used for unplanned
purposes. You can further restrict use of this key by source address
using the from keyword:
~/.ssh/authorized_keys:
command="/bin/who",from="client.example.com" ssh-dss key...
Additionally, disable any unneeded capabilities for this key, such as
port
forwarding, X forwarding, agent forwarding, and the allocation of
pseudo-ttys for interactive sessions. The key options
no-port-forwarding,
no-X11-forwarding,
no-agent-forwarding, and
no-pty, respectively, perform these jobs.
Make sure you edit authorized_keys with an
appropriate text editor that does not blindly insert newlines. Your
key and all its options must remain on a single line of text, with no
whitespace around the commas.
Carefully consider whether to include plaintext keys in your regular system
backups. If you do include them, a thief need only steal a backup
tape to obtain them. If you don't, then you risk
losing them, but if new keys can easily be generated and installed,
perhaps this is an acceptable tradeoff.
Finally, store plaintext keys only on local disks, not insecurely
shared volumes such as NFS partitions. Otherwise their unencrypted
contents will travel over the network and risk interception. [Recipe 9.19]
6.10.4 See Also