Big thanks to the great reps of Linode for turning me on to their hosting at PyCon last week. Since I’m starting with a fresh Ubuntu server, I wanted to do it right, so I spent some time learning how to properly do public/private keys for logins and to disable remote root logins…
Your First Log-In
The first time ssh’ing to your new instance a warning will appear letting you know that you haven’t seen this hostname and/or IP before and asks you if you really want to connect (i.e. do you trust this server):
The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established. ECDSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'xxx.xxx.xxx.xxx' (ECDSA) to the list of known hosts. email@example.com's password: Welcome to Ubuntu 11.10 (GNU/Linux 3.0.18-linode43 i686) * Documentation: https://help.ubuntu.com/ The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@lixxx-xxx:~#
If you answer in the affirmative and supply the correct password, your new server’s public key will be stored under two possible entries in your local
~/.ssh/known_hosts file: one for the IP address and the other for the hostname (if used). FYI: you can delete an entry by using:
$ ssh-keygen -R xxx.xxx.xxx.xxx
Create a new user
In later steps we’re going to disallow remote logins by the root user, so this step is CRITICAL!
$ sudo adduser NEWUSERNAME ... lots of easy steps here ...
Add you’ll probably want to add this new user to the
sudoers list so they can do things like install system-wide packages and perform upgrades. Edit (as root) the file
/etc/sudoers and add your new username to the list under
User privilege specification:
# User privilege specification root,NEWUSERNAME ALL=(ALL:ALL) ALL
Create a private/public key pair on the client machine. The default type is ‘rsa’, but let’s use the
-t option for demonstration purposes. Also, to stop a default email address from getting into the comment, we’ll be specific and use a good email (doesn’t have to be an email, could be a location like “mylaptop”, etc…):
$ ssh-keygen -t rsa -b 4096 -C firstname.lastname@example.org ... answer the questions
When asked to enter the filename, you can accept the default or go with a custom name. I’ll use “MYKEY_rsa” for this workflow. Also, I’ve NOT used a passphrase. You may add a passphrase for added security…
Transfer your public key to the remote machine
The remote machine needs your public key to decrypt the data you send it that’s encrypted with your private key. Below are steps to do this both manually and then quickly with the
~/.ssh directory on the server and protect it:
$ mkdir ~/.ssh $ chmod 700 ~/.ssh
Transfer your public key from the client to remote machine:
$ cat ~/.ssh/MYKEY_rsa.pub | ssh NEWUSERNAME@xxx.xxx.xxx.xxx 'cat >> ~/.ssh/authorized_keys' email@example.com's password: XXXXXX
This method is a lot more bullet-proof.
$ ssh-copy-id -i ~/.ssh/MYKEY_rsa.pub NEWUSERNAME@xxx.xxx.xxx.xxx firstname.lastname@example.org's password: XXXXXX Now try logging into the machine, with "ssh 'email@example.com'", and check in: ~/.ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
Make yourself known to
You’ve given your public identity to the remote server and you’ve added it to your
known_hosts. Now, if you attempt an
ssh connection, you’ll see this error if you’ve used a non-default name for your keys:
Agent admitted failure to sign using the key.
This is because
ssh didn’t know which identity you to use. To remedy this, let the
ssh agent know about your new identity so it can provide the correct credentials behind the scenes when needed.
$ ssh-add ~/.ssh/MYKEY_rsa
FYI: to delete all your identities, use this command:
$ ssh-add -D
Ubuntu will prompt you for the password, if the private key has one (I didn’t supply one in this workflow).
Disallow Keyboard-based And Remote Root Logins:
Now that authentication can happen using public/private keys, we can now safely disable standard keyboard password authentication on the server. On the server machine, open the file
/etc/ssh/sshd_config and make the following changes:
PasswordAuthentication no ChallengeResponseAuthentication no
ONLY if you’ve created a new user and given them
sudo permissions should you modify this line:
sshd config file (using Ubuntu’s upstart):
$ sudo service ssh reload
Now (just to test things) back on the client, tell our agent to forget our key, and attempt a regular
ssh connection. You should get a ‘Permission denied’ error:
$ ssh NEWUSERNAME@xxx.xxx.xxx.xxx Agent admitted failure to sign using the key. Permission denied (publickey).
Add the key back to the agent, and all should be good!
$ ssh-add MYKEY_rsa Identity added: MYKEY_rsa (MYKEY_rsa) $ ssh NEWUSERNAME@xxx.xxx.xxx.xxx
Now to test your new user and their sudo permissions, try installing a cool database!
$ sudo apt-get install redis-server