Secure Connection to Server Using SSH
Introduction
To connect to your server from another device (whether in your house or from outside), you can use Secure Shell protocol or SSH. This is a command line access to the server using the IP address of your server. This is very useful specially if your server is not easy to access. This way you can use your laptop to fully access the server and install the applications you need without physical access! I highly recommend doing this right after you install your server.
Once you setup SSH, anyone with the authentication can access your server, so it is highly recommended to create a strong and secure SSH setup to avoid getting hacked.
There are many ways to improve the security of your SSH connection. The easiest way is to use authentication keys instead of password.
Step 1: Installing SSH Package
The first step is to install and setup the SSH package in Ubuntu.
sudo apt-get install openssh-server
Then, edit the configuration file:
sudo nano /etc/ssh/sshd_config
Here, make these changes:
Go to Permit Root Login and change yes to no.
Go to Password Authentication and uncomment and change yes to no
Restart the service:
sudo systemctl restart ssh
Next, you need to change the firewall setting of your server:
sudo ufw allow 22/tcp
sudo ufw disable && sudo ufw enable
Step 2: Generating Public and Private Keys
SSH uses key pairs to authenticate a user. To create a set of keys for your account run (make sure your have not switched to root here!)
ssh-keygen -t rsa
Accept the defaults, and create a passphrase for your key. You will need to enter this passphrase every time you want to connect to your server. Next, add the public key to the list of authorized keys for your account
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Your private key (which needs to be kept private!) is located at ~/.ssh/id_rsa. You need to securely copy it to the computer that you want to use to connect to your server.
Step 3: Setting Up the Router for Remote SSH Connection
If you want to remotely connect to your server while away from home, first you need the IP address assigned to your home by your ISP. To find it, simply search What is my IP while connected to internet at home. But that's not all! Then, you need to tell your router to send traffic on its port 22 (used for SSH) to your server. Each router has a different way of doing that but it is usually called Port Forwarding. On my TP-Link Archer 5400 v2, it is done in Advanced > NAT Forwarding > Virtual Servers and then adding a new entry with following data:
- External Port: 22 (or you can choose something else, but then you need to choose the same port in PuTTY later)
- nternal IP: This is the local IP address of your server
- Internal Port: Use 22 here.
- Protocol: TCP
Step 4: Connecting to Your Server Using PuTTY
On Windows OS, you can use a well-known program called PuTTY to connect to your server remotely. Download the latest version of the software and install it. Before you run it though, you need to convert the private key you generated in Step 2 to a format that PuTTY accepts. Thankfully, PuTTY has already a tool to do that and it is installed with PuTTY automatically. Find and run PuTTYgen, and from the Conversation menu, select Import key. Browse to the location of the private key you copied from the server and select it. It will ask for your passphrase before it can access it, and then generates a private key in PuTTY format. Save it in .ppk format and close the software.
Next, run PuTTY. It will open without any connection by default. First, head to Connection > SSH > Auth and in Authentication parameters section, browse and select the private key in ppk format you generated. Optionally, you can change the color scheme of the terminal in Windows > Colours.
Next, head back to Session and in Host Name section, enter the IP address of your server. If you are connecting using the same local network as your server, you only need the local IP address of your server which can be found by running ip a on your server. If you want to connect to your server from outside, then you need the IP address of your home as explained in Step 3. Change the Port from 22 if you chose a different port in Step 3, otherwise leave it.
Tip: To make things easier, give this connection a name in Saved Sessions box and hit Save. This way, next time you open PuTTY you just choose the session and load it!
Now you are ready to remotely connect to your server! Just hit Open, enter the username and passphrase (not your account password) and you are in.
More Security with 2FA for SSH
If you want even more security when connecting to your server through SSH, you can add a second authentication layer to the process. First, install the required packages:
sudo apt-get install -y libqrencode3 libpam-google-authenticator
Then, run (do not use sudo here!)
google-authenticator -t -d -f -r 3 -R 30 -w 17
At the end of the process, you are given a secret key and bunch of emergency keys. Open the authenticator app of your choice (you can choose Google Authenticator, or better yet LastPass Authenticator if you use LastPass) and add the key using the secret key. If you want to use your YubiKey instead, you can add it to Yubico Authenticator. Choose SSH-1 as the algorithm with 6 characters.
Write down the emergency codes somewhere. You can also back up the hidden file ~/.google_authenticator at your home directory to a safe location in case you want to link another authenticator app.
Next, edit the Pam file:
sudo nano /etc/pam.d/sshd
Find @include common-password at the end and add this line:
auth required pam_google_authenticator.so nullok
Next, comment the following line
#@include common-auth
Save the file and exit. Then, open
sudo nano /etc/ssh/sshd_config
and make these changes:
ChallengeResponseAuthentication yes
Add this line after UsePAM yes
AuthenticationMethods publickey,password publickey,keyboard-interactive
If you have changed the PasswordAuthentication to no, change it back to yes.
Save and exit, then reset SSH:
sudo systemctl restart sshd.service
To check the process, run
ssh -v localhost
and follow the steps. If it was successful, then everything is complete!
SSH with OpenPGP feature of YubiKey
Instead of using a public and private key pair to access your server, you can use YubiKey! To achieve this, you first need to generate a set of keys for your YubiKey. This is a separate process explained in another post, but here it is assumed that you already have your YubiKey with all the required PGP keys and you have also copied the Public Key of these keys on your Windows machine.
The process is divided into two steps. First, you need to do the followings on your Ubuntu server:
sudo add-apt-repository ppa:yubico/stable && sudo apt-get update
sudo apt-get install yubikey-manager-qt scdaemon gnupg2 curl
nano ~/.gnupg/gpg-agent.conf
and paste
enable-ssh-support
enable-putty-support
default-cache-ttl 60
max-cache-ttl 120
pinentry-program /usr/bin/pinentry-gnome3
Save and close. Run
gpgconf --launch gpg-agent
nano ~/.bashrc
and paste this at the end
export GPG_TTY="$(tty)"
export SSH_AUTH_SOCK="/run/user/$UID/gnupg/S.gpg-agent.ssh"
gpg-connect-agent updatestartuptty /bye
Logout and Login to apply the change! Attach your YubiKey and then run
ssh-add -L
Tip: If you get this error: "Could not open a connection to your authentication agent.", then run these two lines first:
ssh-agent
eval $(ssh-agent)
If yo did not get any error, the output will give you the public key and serial number. Copy the serial number and then run
ssh-add -L | grep "cardno:SERIAL_NUMBER" > ~/.ssh/id_rsa_yubikey.pub
cat ~/.ssh/id_rsa_yubikey.pub >> ~/.ssh/authorized_keys
Make sure to replace the SERIAL_NUMBER with the actual serial number of your card!
On the Windows OS that you want to use to remotely connect to the server using PuTTY you need to do the followings (replace username with your actual username on your Windows machine in the following codes):
First, make sure that both PuTTY and gpg4win are installed on your machine. Open a Command Prompt (Windows key + R and then type cmd and hit enter) and type
gpg --import PUBLIC_KEY.asc
Here, PUBLIC_KEY.asc is the public key of your YubiKey PGP keys.
Add the following lines in C:\Users\username\AppData\Roaming\gnupg\gpg-agent.conf (if the file does not exist, then create it using notepad).
enable-ssh-support
enable-putty-support
Save and close the file. Then, go to: Control Panel > System > Advanced system settings > Advanced > Environment Variables and add a new system variable as:
Variable Name: SSH_AUTH_SOCK
Variable Value: C:\Users\username\AppData\Roaming\gnupg\S.gpg-agent.ssh
Then on Command Prompt run
gpg --card-status --with-keygrip
and copy the keygrip for Authentication Key and paste it in this file (create it if it does not exist): C:\Users\username\AppData\Roaming\gnupg\sshcontrol. Make sure to press enter at the end of the line.
Press Windows Key + R and type shell:startup. In the folder, create a .bat file (give it whatever name you want) and paste "C:\Program Files (x86)\GNU\GnuPG\gpg-connect-agent.exe" /bye
Start Command Prompt as normal user, not admin, and run:
gpg-connect-agent KILLAGENT /bye
gpg --card-status
Tip: You might need to run gpg --card-status in a Command Prompt every time you restart your computer!
That's it. You should be able to use your YubiKey to authenticate using PuTTY now. Whenever you try to connect and after entering your username, a window should pop up and ask for the PIN on your YubiKey.