Page 1 of 1

ssh authentication

Posted: Sun Jan 07, 2007 2:56 am
by lambda
suppose you log into several remote servers using ssh. you don't want to memorize or type in lengthy commands, like

Code: Select all

ssh luser@192.168.110.20 -p 2222
every time. you can use ssh's config file to give descriptive (and short) names for such tasks.

create ~/.ssh/config and place something like this in it:

Code: Select all

Host slowpc
  HostName 192.168.110.20
  User luser
  Port 2222

Host web
  HostName fastbox-34.hosting-company.example.net
  User www
  Compression yes

Host homebox
  Hostname eliteroot.dyndns.org
  User r3wt
  Port 2233
  ForwardX11 yes
you get the general idea. type "man ssh_config" for a complete list of options.

the nice thing is, the host "names" you define in these files work for all ssh-related operations. so, now you can type

Code: Select all

scp ruby-on-rails-howto.pdf slowpc:/usr/local/data
instead of

Code: Select all

scp -P 2222 ruby-on-rails-howto.pdf luser@192.168.110.20:/usr/local/data


about the only thing you can't put in the config file is the password. let's face it, you really don't want to put the password in there -- if someone breaks into your account, they could gain access to all your remote accounts just by reading the file. not only that, but most people pick weak passwords. their first name. their first name followed by '123'. the name of some famous actor/actress/singer. stuff like that. no wonder their hotmail accounts are broken into all the time.

i'm guilty of this, too, by the way. since i'm the laziest person around, my root passwords on my home machines are usually one character long -- just a period. (then again, i have ssh set up to disallow remote logins by root, and my computers are all behind a one-way nat, so i'm safe.)

ssh gives you another mechanism for authenticating yourself to remote servers -- keys. keys are "stronger" than passwords because you can use a sentence as a key passphrase instead of a short 6-8 character password. it's pretty hard to guess a sentence, not so hard to guess a password.

here's how you create keys for ssh:

Code: Select all

% ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/me/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): i am the greatest!
Enter same passphrase again: i am the greatest!
Your identification has been saved in /home/me/.ssh/id_rsa.
Your public key has been saved in /home/me/.ssh/id_rsa.pub.
The key fingerprint is:
8d:72:c3:62:87:31:d0:00:7e:29:c8:4b:f4:31:32:b1 me@ultralisk
%
now we have two key files -- .ssh/id_rsa and .ssh/id_rsa.pub. to use these files to login to a remote system, we need to first put the public key file on the server, and place it into .ssh/authorized_keys (note: on some systems, you need to place them in ~/.ssh/authorized_keys2). we could just do

Code: Select all

scp .ssh/id_rsa.pub slowpc:.ssh/authorized_keys
but .ssh/authorized_keys may already exist on the server, and we don't want to overwrite its contents. so, we'll copy it elsewhere, and then login and append it to the end of the file:

Code: Select all

% scp .ssh/id_rsa.pub slowpc:my-new-key
Password:
id_rsa.pub                                    100%  602     0.6KB/s   00:00   
% ssh slowpc
Password:
[... login text ... ]
me@slowpc ~$ cat my-new-key >> .ssh/authorized_keys
me@slowpc ~$ rm my-new-key
me@slowpc ~$ exit
Connection close by foreign host
% scp .ssh/id_rsa.pub web:my-new-key
Password:
id_rsa.pub                                    100%  602     0.6KB/s   00:00   
[ you get the idea ]


what does this exercise buy us? well, now when we type ssh slowpc, we don't type in the password, we type in the passphrase. it's a long passphrase, and people aren't likely to guess it or crack it. people can try to watch your fingers as you type it in, but it'll be a lot harder for them to figure out what you're typing in.

but, you say, they can still try and login using the password, if they somehow guess it. yep. there are two options here. since you won't use passwords to login any more, you won't need to set the password to something easy to remember. so, your first option is to set the password to something completely unguessable. something that looks more like perl code than a word in english (or urdu/farsi/arabic/whatever). this is probably the better option.

the second option is to disable password logins entirely. simply edit /etc/ssh/sshd_config and set PasswordAuthentication no, and restart sshd. be careful, though. if you lose .ssh/id_rsa (your half of the two keys), or if .ssh/authorized_keys is deleted on the server, you won't be able to login using ssh.

but, you say, you've just made us type a long sentence every time we want to ssh to the server! yes, it is pretty annoying, having to type in your password a dozen times a day. and, right you are, it's a lot worse to type in a sentence; you end up wasting precious seconds every time you want to login or scp a file! why, you could be reading the gupshup forum on linuxpakistan!

ssh has something to help us with this problem. ssh ships with a program called "ssh-agent" that keeps track of your passphrases. if you run a recent distribution of linux, you probably have "ssh-agent" running right now. to check, type

Code: Select all

ps auxww | grep ssh-
on ubuntu, you'll find a file in /etc/X11/Xsession.d to start it whenever you login. i'm sure other distributions have something similar.

ssh-agent works with a tool called ssh-add to manage ssh key passphrases. it works like this

- you (or the distribution) run ssh-agent when you login
- you type "ssh-add .ssh/id_rsa < /dev/null" or just "ssh-add"
- ssh-add asks you for your passphrase
- if the passphrase is correct, it gives the passphrase to ssh-agent

now, whenever you try to login to a server that uses the id_rsa key, ssh will ask ssh-agent for the passphrase, and not you:

Code: Select all

% ssh -v web
OpenSSH_4.3p2 Debian-5ubuntu1, OpenSSL 0.9.8b 04 May 2006
debug1: Reading configuration data /home/me/.ssh/config
debug1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to fastbox-34.hosting-company.example.net [668.55.34.352] port 22.
debug1: Connection established.
debug1: identity file /home/me/.ssh/id_rsa type 2
debug1: Remote protocol version 2.0, remote software version OpenSSH_3.8.1p1 FreeBSD-20040419
debug1: match: OpenSSH_3.8.1p1 FreeBSD-20040419 pat OpenSSH_3.*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_4.3p2 Debian-5ubuntu1
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-cbc hmac-md5 none
debug1: kex: client->server aes128-cbc hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'fastbox-34.hosting-company.example.net' is known and matches the DSA host key.
debug1: Found key in /home/me/.ssh/known_hosts:7
debug1: ssh_dss_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Offering public key: /home/me/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-dss blen 434
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US
Last login: Sun Jan  7 01:30:33 2007 from dsl-202-59-94-4
me@fastbox-34 ~$
you can list all the keys managed by ssh-agent:

Code: Select all

% ssh-add -l
2048 8d:72:c3:62:87:31:d0:00:7e:29:c8:4b:f4:31:32:b1 .ssh/id_rsa (RSA)
%
read ssh-add's man page for other options.

if you read the above carefully, you probably read this line in ssh-keygen's output:

Code: Select all

Enter passphrase (empty for no passphrase):
you could just hit enter there, and avoid using ssh-agent altogether. but, it creates a security problem. now, if someone breaks into your account, they can just ssh to some other system without typing in a password or passphrase! that's worse than using bad passwords. you don't want to do that.

however, there are situations where you do need a passwordless login to a system. most of the time, it's because you want a cron job on your system to automatically execute a script or program (usually for backups) on the remote system. since your cron job can't use ssh-agent, here's what you do.

you need to create a pair of keys using ssh-keygen (don't call it ~/.ssh/id_rsa, call it ~/.ssh/backups_rsa or something) with an empty passphrase, and copy the pub key to the remote server's authorized_keys file, as described above. before you copy the nopass_rsa.pub file over, edit the file and add the command you want to execute on the remote system.

before:

Code: Select all

% cat .ssh/nopass_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqc4C01vgfUgLhTC
5zbFCVJdZxgTlsSoomNqs6+61UaHxrqPXCIcEKqUI4j6cFXd1ILR
WV5BNDYS3u7Acx0Z+mx5ZiI7PV3QtU0Cpwmq082+CncecLv2
5CU2q3tlqPkYhfeNVjYyD/RoP2E+f+qelUYJFazmRsI+jkpLp9PR/6
nY4gYr9VTB4NQzASZQbsnPR74WvGpgwcX2C0Fy3lLZACqgNG
VWrLfmydydHTLDNZflHASVoMyxt+R2/s8HWI9d0Uf+APWO4HvT
b1Q36WiFPvwbYZXLINn4/3ScBd6E+IRfgctyePwSqDFukBqsrR8b
0NC2NK8q7G+kbnZ0k4V57gw== me@ultralisk
%
after:

Code: Select all

% cat .ssh/nopass_rsa.pub
command="/usr/local/bin/my-cool-backup-script.sh" ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEAqc4C01vgfUgLhTC5zbFCVJdZ
xgTlsSoomNqs6+61UaHxrqPXCIcEKqUI4j6cFXd1ILRWV5BNDYS3u
7Acx0Z+mx5ZiI7PV3QtU0Cpwmq082+CncecLv25CU2q3tlqPkYhf
eNVjYyD/RoP2E+f+qelUYJFazmRsI+jkpLp9PR/6nY4gYr9VTB4NQz
ASZQbsnPR7f4WvGpgwcX2C0Fy3lLZACqgNGVWrLfmydydHTLDN
ZflHASVoMyxt+R2/s8HWI9d0Uf+APWO4HvTb1Q36WiFPvwbYZXL
INn4/3ScBd6E+IRfgctyePwSqDFukBqsrR8b0NC2NK8q7G+kbnZ
0k4V57gw== me@ultralisk
%
note that it's one long line -- don't use pico or something to edit it and wrap lines!

now your local script can login to the server and execute the command like

Code: Select all

ssh -I /home/me/.ssh/nopass_rsa mailgw /usr/local/bin/my-cool-backup-script.sh
.

Posted: Sun Jan 07, 2007 5:46 am
by fawad
AOA,
That's a very nice article. One thing I'd really like SSH to have it to be able to add port forwarding on the fly. A lot of time, you don't know the port to forward until after you login. In such a case, you have to logout and log back in with the correct commandline argument (or config options).

BTW, is there a SSH client GUI (preferrably KDE based) like putty is on Windows?

Posted: Sun Jan 07, 2007 3:20 pm
by mahin_pk
This is no Gup Shup, please do post more Gup Shup like this :). I am moving it to General for now and then to a new "HowTo & Tip's N Tricks" forum.

Now if we can find some one to translate it into Urdu [ comments / narration part ] any volunteer :?:

Nice work and Thanks for sharing.

Tariq.

Posted: Sun Jan 07, 2007 9:42 pm
by Zaheer
Here Is a Volunteer present !

Posted: Mon Jan 08, 2007 11:40 am
by linuxpakistan
A.O.A
What a great effort. I really enjoyed that article, as it shows about the worth of person and also worth of this "Linux Pakistan " forum. I think Linux Gurus in this forum should post advance level Gup Shup. Hope every body will enjoy that Series.

Regards
Muhammad Asif

Posted: Mon Jan 08, 2007 9:03 pm
by Atif_Khan
Nice sharing.

Posted: Sat Mar 31, 2007 3:58 am
by kragen
You can get a command-line prompt from ssh after connecting by hitting enter and then ~C, and from there you can set up new port forwardings on the fly without having to relogin:

Code: Select all

kragen@panacea:~$ (i typed ~C here)
ssh> ?
Commands:
      -Lport:host:hostport    Request local forward
      -Rport:host:hostport    Request remote forward
      -KRhostport             Cancel remote forward

great post by the greatest

Posted: Fri Apr 20, 2007 9:41 pm
by salmanslick
yeah datz true , these trips n tricks are very handy :P