Security is a premium topic today and securing cloud servers with SSH authentication has to be the first task after launching your new system. Often in a private cloud you have the option of adding in SSH Keys during the build of the instance. In public clouds this often is not the case. This is why the first task after launching systems is securing cloud servers with SSH.
For the demonstration we are using OS X as the client connecting to cloud based servers with LINODE. In using OS X as the client, we can show how to add SSH keys to the keychain, simplifying access to our keys. We will generate secure keys adding them both to the local keychain and to the remote server. Once verified we can disable password access for the root account on the remote server.
Generating Secure SSH Key Pairs
In my previous blog we took a look at generating secure keys in Linux, this we can also do from the command line of our OS X client. Using the ed25519 keys allows for quick encryption over the wire that is very secure.
[andrewm@iMac ~ ] $ ssh-keygen -t ed25519 -o -a 25 -C "CloudMac"
Using the same ssh-keygen command that we have in Linux we can specify the type of key pair to be the ed25519, or Edwards Twisted Curve. The options -o and -a allow us to run multiple encryptions on the private key to help protect against brute force attacks. We are using 25 encrypt rounds here. The last option -C sets a readable comment to the keynote. This appears in the remote server’s authorised_key file and is good to link back to the client in a recognisable manner. Using both the ed25519 key pair and the encryption rounds have already completed two of the steps that we need in securing cloud servers with SSH.
The public key generated will be sent to the remote SSH Servers, the private key is the secure file that we maintain access to and protect. This is used as the key to the server in much the same way as a physical key is used to unlock doors.
Adding SSH Private Keys to the OS X Keychain
Using the the ssh-agent command we can start a BASH shell and cache the private key that we will use to access remote servers. In this way we need to authenticate just once to the key when we start the shell. Another way and very convenient in OS X is to make use of the secure Keychain. We open this when we login to OS X so provides convenient and secure access to our private key. From the command line we make use of the ssh-add command and the option -K:
[andrewm@iMac ~ ] $ ssh-add -K ~/.ssh/id_ed25519
This is a very cool feature and nicely integrated into the ssh suite.
If you are not using OS X then you may use the -i option with the ssh client:
$ ssh -i .ssh/id_ed25519 -l user ssh-server-address
This opens the key each time but you can cache the key with the following commands:
$ ssh-agent bash $ ssh-add ~/.ssh/id_ed25519
In this way you have similar behaviour to the Keychain other than you have to authenticate to the private key when you add it to the agent. You must run these commands each time you want to have a shell with the key cached. Where you are running a GUI on your Linux desktop you may also fined that you have Desktop based tools that can be used to integrate the private key into you Desktop login.
Adding the Public key to the Server
To authenticate the user on the server we must copy the user’s public key to the server. Much in the same way that we can verify the identities of Servers by storing the public key server’s can authenticate us to the public key we have stored on the server. On many cloud servers we only have the root account provisioned with the virtual machine. So password access is granted to root via SSH. This may be necessary to begin but should be stopped as soon as possible as a server with SSH access on the internet should not allow password access by root. The password can be cracked and your server compromised. We first copy the public key to the server using password based authentication:
[andrewm@iMac ~ ] $ ssh-copy-id -i .ssh/id_ed25519.pub root@ssh-server-address
This copies the specified public key to the target server and /root/.ssh/authorized_keys. With the key in place we should be able to authenticate using this key. From the client:
[andrewm@iMac ~ ] $ ssh root@ssh-server-address
We should gain direct access without having to add the password. If you are prompted for the passphrase then you may not have the key cached on the client. If we have gained access to the server then we will be authenticated as the root user. If we read the last line form the authorised_keys file we will be able to file we can view the public key we added with our system comment:
root@yogi:~# tail -n 1 ~/.ssh/authorized_keys ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPZOMXnXcGAEf1RgG1djn38+rvmHsXSuwDNaG48nkhVm CloudMac
We can also check the authentication log on the server to check that we are authentication with the ed25519 key:
root@yogi:~# tail /var/log/auth.log ..... Aug 11 10:35:14 yogi sshd[17588]: Accepted publickey for root from 81.97.40.21 port 54357 ssh2: ED25519 SHA256:4afLKXpzst2AKImVAC58qm7qeD4lCA6O1r+fSsql52M .....
On CentOS the log file will be /var/log/secure
Preventing Root Login with Password
As we mentioned before, many cloud servers allow root login via SSH as no other user account exists. We need a starting method to login to the system and we can set the password in the deployment script. Once we have confirmed that we do indeed have public key authentication working for the root account then we can disable password based login for the account.On the SSH Server and authenticated as the root user we can edit the /etc/ssh/sshd_config file. We need to look for the line that reads:
PermitRootLogin Yes
and change it to read:
PermitRootLogin without-password
With this set, we can save the file and restart the SSHD service so we implement this with systemctl. My system is systems based:
root@yogi:~# systemctl restart sshd
We now will only be able to login as the root user with the key-based authentication. This goes a very log way towards securing cloud servers with SSH controlled access.
Working with the SSH Client Config
We can create on the client system, the iMAC in my case, a file called config in the ~/.ssh/ directory. The ~/.ssh/config file is the client specific SSH client configuration file that can overwrite the defaults in /etc/ssh/ssh_config file. With this file we can create shortcuts to servers and the usernames that we want to use:
Host * UseKeychain yes AddKeystoAgent yes IdentityFile ~/.ssh/id_rsa ServerAliveInterval 300 ServerAliveCountMax 2 Host cloud HostName your-ssh-server-address User root IdentityFile ~/.ssh/id_ed25519
The Host * section defines default settings for all server. Host cloud further defines an alias that we can use to access the server and settings specific to this server. The address to use and the username. We also specify a different key to the default RSA key. We can now simply use:
[andrewm@iMac ~ ] $ ssh cloud
The video follows