|
By Bri Hatch. Summary: How to create passwordless logins to allow remote administration tasks securely with SSH - restricting possible actions for SSH identities. Setting up your accounts to allow identity-based authentication gives you several new options to allow passwordless access to those accounts. This week we'll see how well we can restrict the access granted to these identities. $HOME/.ssh/authorized_keys files, are where you stick the public keys of identities you wish to allow. These files without any arguments look something like this:
user@server$ cat ~/.ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA3nCnBRQR2x4Ak7I3gS62ASXGiC+5o sLmOX5yS894rjFdFEVKgiuhuU0W7NdE3Mymkm0oX3oZM1e7NNxDx/4/Cu/4fISP8o pwN4GG2wbubZARFyJpWNMcVe8ZdOdmrlXFYh49a18i++SScHnycmiL8AmEb06Obrh kc5iAyVnHAf08Lqk= user@client_machine
The above code listing is wrapped and indented for readability, but
in reality everything should be in one line. The only spaces
occur between SSH1 identities, however look slightly different, as seen here:
user@server$ cat ~/.ssh/authorized_keys 1024 35 118175573790683499614097477370143348554184947854197722520 41836228683278279897504160922892652206780215894929989167407130782 38841607878229644157746694554723410376922636437979652730247511201 90228759786298122911260638958674184210284497057700389946655115171 90400155609012033981180255475519919550519308405663149133021266378 user@client_machine Regardless which version you use, adding options will be done in the same way, so we'll assume RSA identities for simplicity. When set up in this manner, anyone who possesses the private keys that go with these public keys can log in as you on the server with no restrictions:
# Log in interactively client$ ssh user@server -i $HOME/identity_test/id_rsa user@server$ hostname server user@server$ exit # Run a command remotely client$ ssh user@server -i $HOME/identity_test/id_rsa "echo Success!" Success! client$
We can add several options to this key on the server to restrict in which
ways it can be used. Options are put at the beginning of the line, before
the key starts, and are separated from the rest of the line by whitespace.
Here are some of the more useful options. For a full list, see the
So lets set up an example from the ground up. Say you wished to allow the user "backups" on the machine beepbeep.my_net.net[2] to be able to copy the /etc/ directory of the machine futzy so you have a backup of the system configuration, just in case futzy goes belly up. To make sure we get all the files in /etc, we'll want to log into futzy as root. Normally you would run the following command:
backups@beepbeep$ scp -pr root@futzy:/etc/ /path/to/etc_backup/
The Here are the steps you'd need to take to get it working without a password so the backups user can do this all from cron, no password required. I'll breeze over some steps that were already described in detail in the previous articles. Log into beepbeep as backups and create the key:
backups@beepbeep$ cd backups@beepbeep$ mkdir keys backups@beepbeep$ cd keys backups@beepbeep$ ssh-keygen -t rsa -f futzy.scp.etc Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): enter Enter same passphrase again: enter Your identification has been saved in futzy.scp.etc. Your public key has been saved in futzy.scp.etc.pub. backups@beepbeep$ ls futzy.scp.etc futzy.scp.etc.pub
Now, copy the public key up to futzy. (You can use many other methods.)
backups@beepbeep$ scp futzy.scp.etc.pub root@futzy:/some/tmp/dir root@futzy's password: <type password> Now, log into futzy as root. We'll edit the public key to prepend a "from=" option so the key can only be used from beepbeep, and then add this to our authorized_keys file:
root@futzy# cd /root/.ssh root@futzy# cat /some/tmp/dir/futzy.scp.etc.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAqwRPEALGQbrhQQST9Obkj2OJrUsaRi1 SYtJbkpn6TxWddze2F/lzfKimgzaEhSWKuh/v0onGHvNaYuXWENdEhSWKuh/v0... root@futzy# vi /some/tmp/dir/futzy.scp.etc.pub # put from="beepbeep.my_net.net" at the beginning # of this line, and exit the editor. root@futzy# cat /some/tmp/dir/futzy.scp.etc.pub from="beepbeep.my_net.net" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAqwRP EALGQbrhQQST9Obkj2OJrUsaRi1SYtJbkpn6TxWddze2F/lzfKimgzaEhSWKuh... root@futzy# cat /some/tmp/dir/futzy.scp.etc.pub>> authorized_keys We now have set up the root account on futzy to allow this key to log in without a password, but only from beepbeep.my_net.net. Currently, any program can be run from beepbeep, so let's test it out:
backups@beepbeep$ ssh -i futzy.scp.etc root@futzy \ 'echo "Hi, I am " `hostname`; pwd' Hi, I am futzy /root You can also verify that this key is rejected from other machines.[3]
othermachine$ ssh -i futzy.scp.etc root@futsy root@futzy's password:
Now let's set up the key to run a forced command, regardless
of what the user sends us. On the server, let's create a
file called
root@futzy# cat <<'EOM' > /root/.ssh/show-original-command #!/bin/sh echo "Original SSH command is '$SSH_ORIGINAL_COMMAND'"; exit 0; EOM root@futzy# chmod u+x /root/.ssh/show-original-command And then modify the authorized_keys file using your favourite editor such that it runs this command. The new version of authorized_keys should look like this:
root@futzy# cat /some/tmp/dir/futzy.scp.etc.pub command="/root/.ssh/show-original-command",from="beepbeep.my_net.ne t" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAqwRPEALGQbrhQQST9Obkj2O... So now, let's connect from beepbeep exactly as we did before:
backups@beepbeep$ ssh -i futzy.scp.etc root@futsy \ 'echo "Hi, I am " `hostname`; pwd' Original command is 'echo "Hi, I am" `whoami`; pwd'
So, let's try running our
backups@beepbeep$ scp -i futzy.scp.etc -pr \ root@futzy:/etc/ /path/to/etc_backup/ Original command is 'scp -r -p -f /etc/'
Aha! Note that the
Many programs that can operate over SSH, such as rsync, run
commands that look different on the server side. Our
Of course, since our
root@futzy# cat /some/tmp/dir/futzy.scp.etc.pub command="scp -r -p -f /etc/",from="beepbeep.my_net.net ssh-rsa AA AAB3NzaC1yc2EAAAABIwAAAIEAqwRPEALGQbrhQQST9Obkj2OJrUsaRi1SYt... And, now to run it from beepbeep:
backups@beepbeep$ scp -i futzy.scp.etc -pr \ root@futzy:/etc/ /path/to/etc_backup/ adduser.conf 100% |***********************************| 1660 00:00 sources.list 100% |***********************************| 949 00:00 host.conf 100% |***********************************| 26 00:00 issue 100% |***********************************| 25 00:00 motd 100% |***********************************| 162 00:00 nsswitch.conf 100% |***********************************| 465 00:00 profile 52% |***************** | 377 00:00 ...
Excellent! But wait - what have we forgotten? There were a few
other options that are useful to restrict other features available
to SSH connections. Ideally we should add those in too. Adding
all the restrictions we can muster, our final
root@futzy# cat /some/tmp/dir/futzy.scp.etc.pub no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,c ommand="scp -r -p -f /etc/",from="beepbeep.my_net.net ssh-rsa AA AAB3NzaC1yc2EAAAABIwAAAIEAqwRPEALGQbrhQQST9Obkj2OJrUsaRi1SYt... Whew! Quite a mouthful. So, what have we accomplished here?
Should the identity fall in the hands of a cracker, it is useless
from any system other that beepbeep. If he has access to
beepbeep, all he can do is snag the
Now the drawback of this system should become clear if you think
about the limitations: each identity can only cause one command
to run. This means if you want to be able to run several commands,
for example mirroring
Next week[4] I'll introduce a program I've been using for a long time that allows you to have multiple authorized programs on a host-by-host basis using only one key. You still need to maintain a list of acceptable commands, but you do not need to generate separate keys for each. Until then, you may want to read an article by William Stearns (author of ssh-keyinstall and more) at Open Source Digest which has many fun SSH tricks.
NOTES:
[1] If you do want to allow specific port forwarding, you can use the
[2] Beepbeep is, of course, the sound a truck makes backing up. Nods to all my NUMBAlum brethren... [3] You'd need to copy the key to othermachine, of course. [4] Really, I promise. Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He's been using SSH to secure his remote logins since Tatu posted the first version of the code - even if the administrators of those machines refused to install it for him. Bri can be reached at bri@hackinglinuxexposed.com. Copyright Bri Hatch, 2003 This is the January 09, 2003 issue of the Linux Security: Tips, Tricks, and Hackery newsletter. If you wish to subscribe, visit http://lists.onsight.com/ or send email to Linux_Security-request@lists.onsight.com.
|