How to Set up an OpenSSH Server with Ubuntu 18.04

7/25/2019 @ 12:27 AM CDT

I'll be starting grad school this coming fall with a focus in machine learning, and an important component of doing work in that field is having the hardware neccessary to run models such as deep neural networks. Even though UW-Madison has resources such as the Euler GPU cluster and some companies offer services such as Amazon's AWS, I was interested in owning my own hardware that I can dedicate to my personal projects and other work. I also wanted to start learning about Linux and computer customization and hardware. Initially, I wanted to have a desktop computer in my apartment where I could run all my models, but what makes a GPU cluster or AWS so great is that I can run my models from any location directly from my laptop. Having this sort of flexibility on my own hardware inspired me to set up my own SSH server.

Setting up this server was a new learning experience for me; I've never really done anything involving networks, installing and configuring operating systems (let alone Linux), and working with the hardware of a computer (I completed some CPU and RAM upgrades). As a result, this blog post exists as a way of documenting what I did and what I learned to give others who are interested in doing the same thing a head start. My aim of this post is to provide brief explanations on the basics, such as IP addresses, subnets, and a few basic (and essential!) Linux Terminal commands for novice Linux users while simultaneously providing useful information to intermediate Linux users who have never done much networking before.

Step 0: Decide on the purpose of your server

There are many types of servers you could set up: MySQL server, SSH server, web server (although your ISP may not be happy about it; check with them first!), FTP server, proxy server, home media server, etc. As the title of this post suggests, this tutorial focuses on setting up an SSH server. I recommend doing your research beforehand to ensure that you have a server that adequately suits your needs. Additionally, be sure to consider your hardware options so that your server can handle the tasks that you assign it. Since I plan on running deep learning models, I'll need to invest in a CUDA-enabled NVIDIA GPU with 6GB of memory as an absolute lower limit. A GPU with 6GB of memory would likely have difficulties training ResNet, computer vision, and NLP models. Having at least 16 GB of computer memory should run OK for models without using the GPU, but I've upgraded to 32 GB. For a CPU, Intel Xeon is a popular choice for servers since they typically have more cores, a larger L3 cache, and support more memory than the Intel Core Family. I found that this post provides a thorough and succinct comparision between the Intel Xeon and Intel Core i7 processors.

It's important to keep in mind the OS compatability between the remote computer you SSH from and your server. For example, my laptop is running macOS and my server runs Ubuntu Server 18.04. Both are Unix-based and, although the kernels aren't the same (which is why you can't run macOS applications on Linux and vice versa), both follow the Unix standard. This means that code I write and debug on my MacBook will run on the Ubuntu Server. If I were to write and debug code on a Windows computer and send it to my Ubuntu server, I'd first have to make changes to the source files to make it compatible with Linux (for example, changing directory names from something like C:\I\Dont\Like\Windows\ to /I/Dont/Like/Windows/). Futhermore, SSH runs natively in macOS, Linux, and Windows 10; any other versions of Windows will require an SSH client such as PuTTY.

Assuming you want your own OpenSSH server, let's get started!

Step 1: Prepare a bootable USB

For this step, you'll need a flash drive with at least 2 GB of space and a computer with an internet connection that you have permission to install software on. Visit the Ubuntu downloads page and download Ubuntu Server 18.04 LTS. As an aside, the file that you download is an ISO image, which is simply an archive file that is configured to be written to an optical disc such as a CD or DVD. ISO 9660 is a standard for file systems that are used with optical discs, hence the name "ISO." However, these ISO images have been developed over time so that they can be "burned" to USB drives, so the term "ISO" is used more for convention.

To burn the ISO to the USB drive, you'll need to download Etcher (if you're on Windows, be sure to download the "Installer" version rather than the "Portable" version) and install it. Plug in your USB drive to your computer and launch Etcher. Etcher is extremely simple to use; all you need to do tell Etcher where the ISO file is on your computer and which drive to burn the image to. Please be aware that burning the ISO to your USB drive will delete everything on the USB drive, so be sure to back up your data. Additionally, take the time to ensure that you select the correct drive to burn the ISO image to. You may accidently burn the ISO to the wrong USB drive if you have another one plugged into your computer.

If you used macOS to create the bootable USB drive, you may get a popup dialogue with the following warning once the ISO has been written to your USB: "The disk you insrted was not readable by this computer." Do not click "Initialize." Instead, click "Eject" and remove the USB drive.

Step 2: Install Ubuntu Server

Installing Ubuntu Server is a multi-step process, which I've outlined below.

  1. Plug the USB drive you prepared into the computer you want to install Ubuntu Server on. If your computer has no OS installed, the computer will automatically detect the USB drive and will begin the setup process. Otherwise, you will need to access the boot menu on your computer by pressing ESC, F1, F2, F8, F10, or F12 on startup depending on the computer's manufacturer. For the computers that I installed Ubuntu Server on, a menu appeared and presented me with a list of options, including "System Setup" and "Boot from USB." If you aren't given the option to simply boot from your USB drive, there will be an option to enter BIOS. In BIOS, you can go to the "Boot" tab and choose to boot from your USB drive. Once booting from your USB drive begins, ensure that your computer is connected to the internet via ethernet and then follow the on-screen instructions for installing Ubuntu.

  2. After configuring your keyboard, you'll have three options on how you want to configure Ubuntu on your computer. For this tutorial, choose "Install Ubuntu." The other two options allow you to configure your computer for MAAS (Metal As A Service). Essentially, MAAS allows the user to manage a pool of computers from which instances can be launched in the same way instances can be launched on Amazon AWS. Like Ubuntu itself, it's completely free, but you must provide your own hardware to run the instances on. This video provides a brief overview of MAAS if you're interested in learning more. Although this tutorial does not explain how to install MAAS, it is good to know about since it might make for another interesting project in the future.

  3. Next, the network connections must be configured. First, I'll specify how the configuration should look and then provide explanations in the following paragraphs if you're unsure of anything. Since this is a server, you'll want to set it up with a static private IP address. Select the interface you want to configure from the menu and then select "Edit IPv4" and change the configuration from "Automatic (DHCP)" to "Manual." For this tutorial, let's assume that your router's IP address is 192.168.1.1, which is the often the default IP address of routers manufacturers provide. The subnet should be configured to 192.168.1.0/24. For the address of the server, you'll need to choose an IP address on the network that isn't currently preoccupied by other devices on the network. To find an available IP address, open Terminal on a Linux or Mac computer (or Command Prompt in Windows) and run

    arp -a

    You're free to choose any IP addresses that aren't listed in the output, but I recommend choosing an address between 192.168.1.2 through 192.168.1.254.

    Enter the IP address of the router in the "Gateway" field (192.168.1.1 for this tutorial). The name servers can be set up to use the Google Public DNS: enter 8.8.8.8, 8.8.4.4 into this field. The search domain can be left empty if you don't have a domain set up.

    If computer networking is a newer topic for you, I'll breifly explain the terminology I just used to set up the network connections. My goal is that you will have a better understanding of how your Linux machine connects to the internet. Any device connected to the internet has two IP addresses: one is private and the other is public. A private IP address is a unqiue identifier for a device connected to a private network and is closely related to the router's IP address on a home network. A public IP address is unique as well, but it's different than a private IP address since a device's public IP address can be used to access the device from any network. For the purposes of installing Ubuntu, this configuration page is asking for a private IP address. Although you won't be using a public IP address here, it will become necessary to use in Step 5: Port forwarding.

    For a given router IP address of 192.168.1.1, a device on the network can have a private IP address in the range 192.168.0.0 through 192.168.255.255. In most households, a private IP address is assigned to a device automatically when it connects router. In this case, the router acts as a DHCP (Dynamic Host Configuration Protocol) server. This isn't a problem for most devices, but it should be avoided for a server like the one you're setting up. Basically, a server will receive many incoming and outgoing requests, and the benefit of using a static IP address (an IP address that never changes) is that it allows you to avoid the hassle of updating the IP address you are port forwarding to everytime your server requests a new IP address. Port forwarding is not defined here; instead, it's relevance is shown in Step 5: Port forwarding.

    You have set up your server using the IPv4 rather than IPv6; to elaborate on the differences of these two is out of the scope of this post, but in a nutshell IPv4 and IPv6 are two different protocols for how connections are established between devices (here is an interesting read that details their differences). The first thing to be specified for the network configuration was the subnet in CIDR notation. This notation is unique to IPv4, and it allows a network to reuse the same private IP address. This video gives a great explanation of how subnet masking works and provides plenty of examples if you'd like to know more.

    The last thing to note from the network configuration step are name servers. Name servers are the part of a DNS (Domain Name System) server that allows a domain name (such as acnagle.com) to be used instead of an IP address to access a host. By setting 8.8.8.8 and 8.8.4.4 as your name servers, you're using Google Public DNS to do that lookup. This will allow you to run

    ping -c3 8.8.8.8

    and

    ping -c3 www.google.com

    when the Ubuntu Server installation is complete and achieve the same outputs. ISPs provide access to a DNS server for their customers, and you could use that instead of the Google Public DNS if you'd like.

  4. You won't need a proxy address, and you likely aren't planning on using a diifferent Ubuntu mirror, so you don't need to change do anything for these steps.

  5. For hard drive configuration, I used the entire disk space since I wanted the computer to only function as a server, but you're free to choose "Manual" and reserve space for a dual-boot configuration. Be aware that these actions will delete everything from your hard drives.

  6. After configuring the hard drives, enter your login credentials. For a name, I suggest admin, local admin, or something along those lines. Unless you already have a server name in mind, I recommend choosing a meaningful name about the system you're setting up. Proceed with filling out the rest of your credentials.

  7. On the next prompt, choose to install OpenSSH. You're also given the option to import SSH identities from services such as GitHub. I chose to skip any importing for now, since this could easily be setup later. On the next prompt, you're giving the option to install server snaps, which are essentially software packages for added functionality to your server. None are required, and I didn't think any were necessary, so I didn't install any. Select "Done" and the installation will complete. You can then reboot your server and login with the credentials you provided during installation.

Step 3: Update and install packages

The very first commands you should run are

sudo apt-get update

followed by

sudo apt-get upgrade

The first command will update the list of available versions for all your packages, and the second command will upgrade your packages to those versions. If you're unfamiliar with bash commands, you can type

command --help

to get a brief overview of a command and it's associated flags, or

man command

if you want to refer to the manual, which will provide greater detail. Take this time to install any drivers or packages you know you will need. Since I want my server to run my machine learning models, I installed Anaconda Distribution followed by additional Python packages I needed, such as PyTorch.

Run

sudo apt install ufw

ufw is short for "uncomplicated firewall," and is the default firewall package for Ubuntu. Next, run

sudo ufw enable

to enable the firewall. In Step 5: Port forwarding, I'll explain how to use ufw to only allow certain ports or IP addresses to communicate with your server. Having a firewall is crucial for having a secure server that only you have access to.

Step 4: Setup SSH

To ensure that OpenSSH is installed, run

ssh

If you need to install it, run

sudo apt install openssh-server

To start the OpenSSH service, run

sudo service ssh start

Lastly, you can check on the status of the SSH service at anytime by running

sudo service ssh status

and then pressing q to quit.

You can check to make sure the SSH service is working as expected by accessing your server. Run the following command:

ssh localhost

localhost is an alias for the loopback address on a network. In other words, running ssh localhost will allow you to SSH into the computer you're currently working at. You will be prompted to enter your login credentials. This will ensure that you can successfully SSH into your server. If you successfully logged in, you can take this one step further by SSHing into server from any computer on the network. If you have a macOS or Linux computer nearby, open the terminal and run

ssh username@server-private-ip

For this tutorial, let's assume your username is "admin" and the private IP address for your server is 192.168.1.5. You would run

ssh admin@192.168.1.5

Run

exit

to terminate the SSH connection.

If you want to copy files from your remote computer to the server, you can do so using scp:

scp /path/to/file1 /path/to/file2 admin@192.168.1.5:/home/admin/

This command will take file1 and file2 from the machine you're currently working on and copy them to the /home/admin/ directory on your server.

Step 5: Port forwarding

If you want to access your server from a network other than your home network, then you'll need to set up port forwarding. Port forwarding specifies where your router should forward requests sent from outside the network. Ports used in networking and physical ports, such as USB ports and HDMI ports, are similar in that they both allow data to be passed between devices. However, network ports are different in that they are software-related rather than physical.

Different ports handle different tasks. For example, port 80 is the default for HTTP traffic and port 22 is the default for SSH. In Step 3: Update and install packages, the firewall on your server was enabled by using ufw. Since the only request you want coming in to your server is an SSH request, all other requests should be blocked by the firewall. This can be achieved with the following command:

sudo ufw allow 22

In case you were wondering, TCP (Transmission Control Protocol) is simply a standard for data tranmission for a network. It's worthwhile to spend some time to learn about the features of ufw, since that's your main protection from malicious activity on your server. For example, instead of specifying a port number, you could specify a single IP address (or a range of IP addresses) to allow an SSH request from a particular device (or range of devices). You could also block specific IP address from accessing your server. The security doesn't stop here however. Depending on how secure you want your server to be, you could set up your server so that only computers that have an SSH key pair can have access.

To port forward through your router, you'll need to access its settings; the general procedure should roughly be the same across all router manufacturers. In order to complete this step, you will need to have administrator access to your router. Login to your router's administrator page and look for services that you can add. Adding an SSH service should be one of the options. Enter 22 as the port number and enter the private IP address that you set up your server with in Step 2: Install Ubuntu Server. Be sure to save your settings!

Now that the router and the server are configured for SSH, you have one of three options for accessing your server from a different network: (1) you can ask your ISP for a public static IP address, (2) you can set up a domain name using a DDNS (Dynamic DNS) (there are free options available), or (3) use the public IP address that your server was assigned (free). Each of these choices is outlined below.

  1. Obtain a public static IP address. Since there are a limited number of unique public IP addresses available to assign to the devices connected to the internet, public IP addresses are subject to change. While the public IP address could be used anyway, it is not a feasible long term solution since the public IP address will keep changing (see option 3). One way to work around this problem is to ask your ISP for a static IP address. This will come at a monthly fee, but you will have peace of mind knowing that your public IP address will never change. Once you have your assigned static public IP address, run this command to get the address:

    dig +short myip.opendns.com @resolver1.opendns.com

    Next, try to SSH to your server from a different network.

    ssh username@server-static-public-ip
  2. Utilize a DDNS. Your second option (this is the option I chose) is to use a DDNS service like www.dynu.com or some other popular DDNS service. Many DDNS allow you to use a domain name instead of the public IP address to connect to your server. With this option, you will choose a custom domain name, and the DDNS will periodically check your router for your server's public IP address. This configuration will require you to access the administrator's page for you router to set up DDNS with your server. Setting up your router with DDNS is fairly similar across router manufacturers: locate the DDNS page (this is likely under some sort of "Advanced" tab) and specify the DDNS server (i.e. dynu, no-ip, or some other DDNS provider), the hostname (domain name), and your DDNS username and password.

    Once you have your DDNS settings adjusted for your router, try SSHing to your server from a different network in the following way:

    ssh username@myamazingserver.ddns.net
  3. Use your server's temporary public IP address. This is the easiest option for setting up (and it's free!), but it has one caveat: public IP addresses are subject to change. There are a limited number of unique IP addresses available for everyone using the internet, so your public IP address could change without you knowing. As a result, whenever the public IP address changes you'll have to manually login to your server to figure out the IP address so that you can SSH remotely. This may be a good idea for a temporary solution while you try to set up one of the first two options, but it would become too frusturating in the long run.

    You can use this command to access your server's public IP address:

    dig +short myip.opendns.com @resolver1.opendns.com

    Next, use this public IP address to SSH to your server remotely.

    ssh username@server-public-ip

    Since public IP addresses for devices on your home network are assigned by your ISP, your public IP addresses will often change in ways that are out of your control. For example, if you have a power outage (and therefore your router is disconnected from your ISP) you can expect a new set of public IP addresses for your devices. Public IP addresses can also be reassigned due to internal network changes or power outtages on the ISP's side.

Step 6: Connect using SSH keys

Although not mandatory, it's a good idea to generate a keypair as a means of authentication between the computers (clients) and the server (host). From step 5: Port forwarding, it was required that you enable port fowarding through your router and that you allow incoming requests from port 22 through the firewall. However, this opens the opportunity for entities on the internet to use brute-force attacks to determine your password; by requiring the use of SSH keys, your server will not be susceptible to these types of attacks. You can check if you already have a keypair by typing

ls ~/.ssh/

on the client machine. You should be able to find all your keys here; if you do have at least one keypair, feel free to use that. Otherwise, you can generate a new key pair using

ssh-keygen

and answering the questions that follow, including which directory you want to save your keypair (FYI: it's a bad idea to save your keypairs anywhere other than in ~/.ssh/). Once you have a keypair, run

ssh-copy-id -i ~/.ssh/your_public_key.pub username@myamazingserver.ddns.net

to share the client's public key with your server. Lastly, run

sudo nano /etc/ssh/sshd_config

Find the line that says

#PasswwordAuthentication yes

and replace it with

PasswordAuthentication no

to remove the ability to login to your server using a password. Press ctrl+O to save the changes and ctrl+X to exit nano.

You now have a working Ubuntu SSH Server that you can access from anywhere you'd like! A server like this is especially useful for backing up files from different computers you own, or running code or machine learning models that have long runtimes.

Thank you for taking the time to read this post; if you have any questions or suggestions, or if you read anything useful here, feel free to reach out to my by visiting my contact page.

Happy SSHing! πŸ™‚οΈ

Works consulted and further reading

Throughout the duration of this project, I referred to many blog posts, articles, forums, and videos to faciliate my understanding of how to set up a server. These links are great starting places for finding in-depth information on the topics I covered in this post. These referrences are listed in the order in which each respective topic in my post was investigated. References whose topics aren't explicitly discussed in my post are listed at the end.