If you’ve been following the previous steps of this guide, you should have a secure, freshly updated installation of Ubuntu Server which you can access from another computer on the network using SSH. If that’s the case, you can safely unplug the keyboard and monitor from your server – you won’t be needing them. If you’re running your server behind a router (e.g., on a home network), chances are your server won’t be accessible from the outside world. This section explains how to make your server available to the public Internet so you can access it from home or while on the go.
Note: For security reasons, please read through this entire post before implementing any of the steps. Accessing your server over an unencrypted public connection could result in someone stealing your passwords!
There are some security and accessibility considerations to take in mind before opening your server to the Internet. To fully understand how these considerations apply, we’ll need a better understanding of how IP addresses work in a practical sense. I briefly mentioned IP addresses while introducing SSH, and this post expands on that discussion.
IP Addresses and Basic Routing
Computers are networked using a protocol known as the Internet Protocol, or IP. Individual computers are identified using their IP address, which consists of four groups of numbers separated by periods (e.g., 192.168.1.1). To simplify, when a computer wants to speak to another computer, it sends a packet that includes the IP address as well as the desired port. That packet is accepted by the computer that is assigned the IP address and rejected by computers that don’t.
Where IP addressing gets confusing is when routers are thrown into the mix. Routers – home routers in particular – often combine multiple computers under a single public-facing IP address. This feature is known as Network Address Translation (NAT) and is the bane of beginner server administrators everywhere.
The IP Problem
NAT is a workaround to an oversight that occurred long before the Internet grew to the size it is today. When the current version of IP (IPv4) was introduced, it provided several billion usable addresses for computers around the globe. When the Internet was only a few thousand users large, this was more than acceptable. However, this is no longer the case – IP addresses are running out, and service providers are rushing to adopt a newer revision (IPv6) in order to increase the pool of available addresses.
In the meantime, NAT attempts to resolve this problem by routing traffic destined for a single IP address to any one of several “underlying” computers. If you compare your server’s IP address to a website that checks your actual IP address, such as IP Chicken, you might get drastically different results. Why? Because your server’s IP address is assigned by your router, whereas your Internet-facing IP address is assigned by your Internet Service Provider (ISP). Your ISP hands you one IP address which is recognized by the Internet, yet your computers use a separate IP addresses which is only recognized by the other computers and devices on the network. From now on, this guide will refer to the IP address on your local network as your internal IP address and your Internet IP address as your public IP address.
Accessing Your Server From the Internet
In order to make our server accessible to the outside world, we have to tell our router how to send traffic through NAT. We can do so by specifying the server’s IP address and the port number of the desired application. Any incoming traffic destined for that port number will be pushed through the NAT to our server through a process called port forwarding. To do this, you’ll have to log in to your router’s interface through a web browser on your computer. This process will vary depending on your router and network configuration, though many home routers provide a web-based configuration interface available through 192.168.1.1. Check with your ISP or router manufacturer for more details if you get stuck.
A sample administration screen for a Linksys router is shown here:
Using the configuration below, the computer with the internal IP address of 192.168.1.17 is set to receive all incoming requests for port 80, 443, and a non-standard SSH port:
When you’re comfortable navigating the administration screen, I suggest setting your server’s IP address to a static IP. By default, your router will assign a random IP address when it detects a new device or when a certain amount of time passes. To prevent your server from generating a dynamic IP address, you can “lock in” your current IP address to prevent it from changing in the future. Again, this varies by router: in the administration screen image above, this can be found under “DHCP Reservation”.
Now that you’ve made the changes to your router, it’s time to test. Using the IP address from IP Chicken, open your SSH program. Replace the previous IP address with the new IP address, and try to connect. If all goes well, it should work exactly the same as if you tried connecting using your server’s original IP address. Traffic on your SSH port will be forwarded through the NAT straight to your server.
You may run into an issue where you can’t access your public IP from inside of your network. This is a common issue and is explained below under the NAT Loopback subsection.
The Demilitarized Zone
As the name implies, the demilitarized zone (DMZ) is a no-man’s-land designed to separate an Internet-facing computer from other computers on the local network. Many home routers offer a variation of DMZ known as a DMZ host. The DMZ host prevents you from having to set individual forwarding rules by placing the server front and center: connections from the Internet are first directed to the server, then to NAT. For security purposes, avoid using a DMZ host and manually set forwarding rules instead.
Unfortunately, navigating IP addresses and NAT tables is a stopping point for many first-time server administrators. Understanding the basics of IP addressing, routing, and NAT is incredibly helpful when you begin installing and enabling services. When you understand how to configure your firewall and your router, you’ll have no problem getting your server to communicate to the outside world.
Connecting to a computer on the same network using your public IP address requires your router to support a feature known as NAT loopback. NAT loopback lets your router redirect packets that originate from the internal network, but are destined for your public IP address. If your router doesn’t support NAT loopback, then you’ll have to specifically use your server’s local address when accessing your server from the same network.
Using NAT and firewalls, you can now access your server from the Internet. However, IP addresses aren’t particularly human-friendly, and having to memorize a series of numbers each time you want to access your server isn’t the greatest option. Additionally, most residential IP addresses are dynamic instead of static, meaning your IP address could change at some point in the future based on your ISP’s practices. This is where the Domain Name System (DNS) comes into play.
DNS maps human-friendly names, such as Google.com, Yahoo.com, and Microsoft.com, to machine-friendly IP addresses. DNS also lets you overcome the issue of dynamic addresses by mapping a single domain name to one or more IP addresses. There’s a lot more to DNS that can’t be covered in this guide, but for our purposes we’ll use DNS to access our server using a name instead of a number.
There are two steps to getting started with DNS: registering a domain name and mapping the domain name to your public IP address.
Domain Name Registration
Each domain name begins with registration. Domain names are managed by registrars who maintain records on the owners of different domain names. Registering a domain name essentially buys you the rights to use a domain name for a period of 1 or more years, after which the domain name returns to the pool of available names. Your domain name uniquely identifies your space on the Internet, so be sure to pick one that’s memorable.
My personal recommendation for a domain registrar is Namecheap. After opening Namecheap’s website, type in the domain name you want, and Namecheap will guide you through the process of purchasing and registering the domain name. The domain name system is managed entirely through registrars, meaning you don’t have to make any changes to your server.
If your server is on a residential network, chances are your IP address will change over time. When your IP address changes, your domain name will continue to resolve to the old IP addresses, breaking any links to your server. To prevent this, Namecheap provides a feature known as dynamic DNS, which is a way for your server to communicate any IP address changes directly to Namecheap. This link provides additional information on how to set up a dynamic DNS service on your server.
Web Server Security With TLS/SSL
Right now, your web server is sending traffic over an unsecured connection. While this is reasonable for internal networks, sending unencrypted data over the Internet is extremely dangerous. The solution is to encrypt web traffic using a protocol known as the Transport Layer Security (TLS) protocol, which is more popularly known as the Secure Sockets Layer (SSL) protocol.
Overview of SSL and Public-Key Cryptography
The concept behind SSL can be confusing for beginners. Imagine you want to mail a package to your friend, but you don’t want anyone else to open it. You ask your friend if there’s any way you can secure your package so that only she can open it, so she provides you with a box and an open padlock. The box is the container for the message, and the padlock is used to lock it. Your friend is the only person with the key for the padlock, making it impossible for anyone else – including you – to open the box once it’s been locked. You put your package inside the box, lock it, and send it back to your friend. Once she receives it, she opens the padlock with her key and has access to your package.
This concept is known as public-key cryptography, and it’s the backbone for secure communication over the web. The recipient of a message has a private key which it keeps securely stored, and a public key which it shares with others. The sender uses the recipient’s public key to encrypt a message that only the recipient can decode, making it extremely difficult for other users to intercept and decode the message without the private key.
The “public key” that SSL uses comes in the form of a certificate. Certificates are used for two purposes: to encrypt messages traveling to and from the website, and to validate the owner of the domain. Web browsers will allow you to view the details of a certificate through a padlock icon displayed next to the URL.
SSL certificates are distributed by vendors who validate and approve requests for certificates. Most certificates cost money to cover the expense of validating ownership of the website, with more expensive certificates providing higher levels of validation. However, basic, personal use SSL certificates are available for free through StartSSL. Namecheap also provides certificates for as low as $8 per year.
I can’t stress the importance of accessing websites over HTTPS instead of HTTP. Logging into a service such as ownCloud through an unencrypted connection makes it possible for other users to intercept your username and password and gain access to your data. SSL is a requirement for the modern web, and any frustration in learning SSL is far more welcoming than having your personal files (or even your identity) stolen.
Configuring Apache for SSL
Your certificate vendor will provide specific instructions on installing a certificate in Apache. The first step regardless of vendor is to enable the ssl module:
sudo a2enmod ssl
Because SSL listens on a different port (443 instead of 80), Apache splits its configuration into a separate VirtualHost. VirtualHosts let you split up Apache’s configuration across different websites hosted on your server: technically, even though we’re using the same domain name, our secure site is different than our insecure site, so it requires a different configuration file. To enable a VirtualHost for SSL, we have to use the following command:
sudo a2ensite default-ssl
This will create a configuration file for all SSL connections in Apache as /etc/apache2/sites-enabled/default-ssl.conf.
When you’re ready to test your SSL installation, open port 443 in your firewall. Try navigating to your server using your internal IP address, e.g. “https://<server’s internal IP>.” If successful, your browser will warn you about an untrusted connection. This is good – the browser recognizes that the certificate doesn’t match the domain name, and is warning you about the inconsistency:
However, you should have no problem accessing your website from its public IP address.
For additional information on IP addresses and domain names, see the Beginner’s Guides resource from ICANN. For additional information on SSL, see Ubuntu’s official guide to OpenSSL and this SSL guide from DigitalOcean, a popular Virtual Private Server (VPS) provider.