Now that you know how to use your shiny new Linux server, it’s time to make it accessible over the network. After all, the client-server model mentioned earlier doesn’t work very well if the client and the server are the same machine. This part of the guide explains how to set up your server to communicate safely with other devices.
The moment a computer connects to any network, it becomes vulnerable to attack. Hackers attempt to gain access to systems by exploiting processes that communicate over the network, particularly remote administration processes. Preventing unauthorized access is not always foolproof, but there are ways to make yourself less vulnerable. One of the first and best strategies is to use a firewall.
Packets and Ports
While the idea behind a firewall requires some background knowledge in networking, the basic concept is this: your computer sends messages over a network by splitting the message into small bits called packets. Each packet contains information on its source and destination. Your computer will let you send packets from different programs simultaneously, so it needs some way of knowing which packet is associated with which program. This is done by shuttling the packets through a logical (i.e. entirely software-based) node called a port.
When a program wants to communicate over a network, it attaches itself to a port. Imagine your computer is a harbor for ships that are carrying packets to and from other harbors. Before a ship can make port, it has to provide a dock number to the harbor master. If the ship is at the wrong harbor, or if the dock is no longer accepting deliveries, then the ship is refused entry into the harbor. Likewise, your computer has several thousand ports that different programs can bind to. If a packet is sent to the wrong port, the program listening on that port won’t know what to do with it. Worse, the program might misinterpret the packet and execute malicious code. Firewalls work by shutting down the ports that aren’t in use while explicitly opening the ports that need to be open.
Most firewalls will block traffic that originates from the Internet, while allowing traffic that originates from your computer to flow freely. This is why you can browse the web from your laptop or desktop even if you have a firewall installed and activated. Think of it like going over your neighbor’s house: if you walk up to your neighbor’s door and knock, they may or may not let you in. However, if your neighbor calls and invites you over, your chances of entering are much more likely.
As an example, most web traffic flows over port 80, while secure web traffic flows over port 443. As you read this blog, your computer is communicating with port 443 on the web server. The web server was explicitly configured to allow incoming connections over port 443, allowing you to read this post without having to reconfigure your firewall.
Configuring the Firewall
Linux comes with a powerful, verbose firewall management program known as iptables. While iptables is extremely flexible, it’s also extremely complicated and far beyond the scope of this guide. As an alternative, Ubuntu provides the Uncomplicated FireWall (ufw) package, which is a simple, straightforward tool for managing iptables. ufw translates simple commands into iptables rules, which iptables uses to determine how to handle a packet.
First, make sure ufw is enabled by running the following command:
sudo ufw enable
You can view the current status of ufw by typing the following command. For now, it should simply show that ufw is active:
sudo ufw status
sudo ufw allow <port number>
This will open the specified port, allowing other computers on the network to speak with the application running on that port.
Updating Your Server
Although our server is protected by the firewall, there’s a far greater risk lurking deep inside the system: outdated software. Running old programs can have a huge impact on the security and stability of your system, as later versions frequently introduce bugfixes and improved features. Before we get started on remote access, you should know how to keep your server installation up to date.
Repositories and Packages
The software model for Ubuntu may be a bit different than what you’re used to. Instead of downloading programs individually from different websites, Linux distributions manage and maintain software through collections known as repositories. Repositories contain packages, which, as the name implies, are programs that are packaged for a particular repository. Repositories are managed by maintainers, who retrieve programs from their source and package them for repositories. If that’s confusing, look at it this way: your supermarket is a repository for food. The staff – the maintainers – ensure the shelves are stocked with fresh food acquired from the distributor. Instead of having to track down each distributor and drive all over the city, you can simply go to the supermarket and pick and choose what food you want. Not bad, considering the service is entirely free.
Interacting with Repositories and Downloading Software
In Ubuntu, your primary tool for managing software is apt-get. Apt-get is a program for installing, reviewing, removing, and updating software on your server. A typical command for installing a package looks like this:
sudo apt-get install <package name>
Likewise, removing a package looks like this:
sudo apt-get remove <package name>
Your computer stores a list of repositories along with as their available packages. Over time, this list becomes outdated as packages are added, removed, and updated to the main repositories. Occasionally, you’ll have to update your repository list, which you can do using the following command:
sudo apt-get update
Then, when you’re ready to synchronize your installed software with the software available on the repository, you can use upgrade to bring your entire system up-to-date:
sudo apt-get upgrade
If apt mentions that packages have been kept back, you’ll have to use the “dist-upgrade” parameter in place of “upgrade”. This reflects a concept known as dependencies, where one package relies on another in order to run properly. The idea of dependencies is to reduce the amount of duplicated code on your system, making it easier to administrate while reducing the need for storage space. “Upgrade” will only upgrade existing packages, while “dist-upgrade” will upgrade and install any dependencies that are introduced by an upgrade.
The power of the repository system is that, unlike Windows, you no longer have to navigate to different websites or install workarounds in order to download new software. You also no longer have to respond to several dozen prompts for updating individual programs. Just run the previous two commands and you’re good to go.
Most updates are done in-place, but if you update a critical component of the system, such as the kernel, your server may prompt you to reboot. You can do so by using the following command:
Remote Access Using SSH
Secure SHell (SSH) is one of the most popular methods of remote access and administration. SSH allows you to access a terminal on a computer using a terminal on another computer. SSH uses encryption to mask the communication between the two computers, making it difficult if not impossible for an attacker to intercept or hijack your session. The most popular implementation of SSH is OpenSSH, which we included as part of the installation process.
By default, SSH listens on port 22. There’s a lot of malicious software that scans the Internet attempting to connect to SSH on its default port, so my suggestion is to change it. In your head, pick a number between 1024 and 65,535 (this is the range of available ports on most computers) that you can easily remember. If you think you’ll have trouble remembering, write it down.
In order to change the default settings for SSH, we need to change its configuration file. The common directory for system-wide configuration files is /etc, which frequently contains subdirectories for program or service-specific files. OpenSSH stores its configuration files in /etc/ssh, so we’ll make that our active directory:
Once inside, ls shows us that there are several files including moduli, ssh_config, sshd_config, and many key and pub files. Ubuntu Server comes with nano, a terminal-friendly text editor, which you can use to read and modify text-based files. Since this is a system-wide configuration file, it’s beyond our user’s permission to change. But since we have sudo at our disposal, we can run nano as the root user and make changes:
sudo nano sshd_config
Services and Daemons
Why are we editing sshd_config and not ssh_config? OpenSSH is split into two components: the SSH server and the SSH client. The SSH server is a process that runs continuously in the background, listening for incoming connections. Processes like these are referred to as daemons; “sshd”, therefore, is short for “SSH daemon”.
The difference between daemons and services is explained more clearly here. In short, services can be controlled while they’re running, whereas daemons are entirely non-interactive.
Navigation in Nano
You can use the arrow keys, Page Down, Page Up, Home, and End keys to navigate in nano. The key combinations listed along the bottom of the terminal are accessed using CTRL+<key>; for instance, CTRL+o allows you to save while CTRL-x allows you to quit. Test this by using CTRL+o without making any changes.
Use CTRL+w to enter search mode, type “port”, and press Enter. This should bring you to a line that reads “Port 22”. Change this number to the number you thought of. We also want to explicitly prevent the root user from being able to log in. Press CTRL+w, type “permitrootlogin”, then press enter. If that line says “PermitRootLogin yes” or “PermitRootLogin without-password”, change it to say “PermitRootLogin no”. Then press CTRL+o to save and CTRL+x to exit.
Restarting the SSH Service
There’s a good chance the SSH service is already running. Since we changed it’s configuration, we have to give the service a chance to read and apply the new configuration. The service command lets you easily manipulate services from a centralized interface. For instance, to restart the SSH service, simply type:
sudo service ssh restart
One last step: even though SSH is listening on the new port, your firewall is blocking outside programs from accessing that port. You can open the port to outside access by specifying a new rule in UFW:
sudo ufw allow <port number>
And now your server will accept incoming SSH connections! You can test this out by downloading an SSH utility for Windows, or by using the terminal in Linux or OS X, and connecting to your server using its IP address and port number. If you don’t know your server’s IP address, use the ifconfig utility to find out:
ifconfig will list all of your server’s network adapters and active IP addresses. Look for the value of “inet addr” to find out your server’s address. In this case, the server’s address is 10.0.2.15. If the connection still fails, make sure you specify the new port number when trying to connect, otherwise UFW will deny the connection.
The next section will explain how to start installing services and hosting websites.