The way to an own clowd (part 3) - Connecting to the outside

Last Thursday I wrote about a key component of your own cloud: the database server.

Today it’s about the next important building block: your own HTTP server.

In your own cloud, it takes on several tasks at once. On the one hand, it can – quite classically – deliver static web pages. But even more interesting: It ensures that all the services covered in this series are accessible from the outside, securely and conveniently.

This is called a reverse proxy. The best suited for this is NGINX.

In the open source world, NGINX is one of the most popular reverse proxies. It is fast, flexible and relatively easy to configure. And to make your cloud securely accessible, there’s the free tool certbot, which can create free SSL certificates.

Connecting to the outside

After logging in to the server, you first execute the following commands to install NGINX:

sudo apt update && sudo apt upgrade -y

sudo apt install nginx

If the installation was successful, the NGINX server starts automatically.

If this does not happen, you can check the status of the service with the following command:

sudo systemctl status nginx

After the installation, you should definitely check that ports 80 and 443 are not open.

The reason: At the beginning, the server should not yet provide HTTP pages to the outside.

You can check whether the ports are open with a reload and a subsequent status check of ufw:

sudo ufw reload

sudo ufw status

If the ports are open, it is recommended to explicitly close them:

sudo ufw deny 80

sudo ufw deny 443

sudo ufw reload

What makes a real cloud? It is accessible from the outside – not just in your own home network.

Since the Internet basically works with IP addresses, it is recommended to use a permanent domain.

The easiest way is through a classic domain provider like Strato, United Domains, or Host Europe. This is especially worthwhile if you have a static (i.e. permanent) IP address. In this case, you enter the IP once in the DNS settings of your provider – and everything runs permanently and stably.

However, if the Internet connection only offers a dynamic IP address (which changes e.g. every 24 hours, as is common with many home connections), you need a so-called DynDNS service such as no-ip.com. It automatically ensures that a domain always points to the current IP of the connection.

As soon as the domain is set up and points to your own cloud server, you can proceed with installing the SSL certificate.

As already mentioned: The easiest way to get free SSL certificates is with certbot, which you can conveniently install via the Debian package manager:

sudo apt install certbot

For Let’s Encrypt to work, you need a public domain pointing to the server (see above). Example: cloud.my-name.eu

The easiest way to check if the domain is set up correctly is with a ping:

ping cloud.my-name.eu

Before requesting the certificate, NGINX must be stopped briefly and port 80 opened – because certbot temporarily starts its own web server to perform domain verification:

sudo systemctl stop nginx

sudo ufw allow 80

sudo ufw reload

Now you can request the certificate:

sudo certbot certonly -d cloud.my-name.eu

After successful issuance, you will find the important certificate files at:

  • /etc/letsencrypt/live/cloud.my-name.eu/fullchain.pem
  • /etc/letsencrypt/live/cloud.my-name.eu/privkey.pem

If everything worked, you can close port 80 again and restart NGINX:

sudo ufw deny 80

sudo ufw reload

sudo systemctl start nginx

To keep all certificates always up to date, it is worth setting up an automatic cron job for renewal.

You can do this with

sudo crontab -e

by adding the following line:

0 0,12 * * *    certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

This way the job takes care of the renewal automatically via certbot – and NGINX is cleanly stopped and restarted.

Finally, you create the configuration file for the domain. To do this, open a new file:

sudo nano /etc/nginx/sites-available/cloud.my-name.eu

Then enter the following content:

server {
    listen 443 ssl;
    server_name cloud.my-name.eu;

    ssl_certificate /etc/letsencrypt/live/cloud.my-name.eu/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.my-name.eu/privkey.pem;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    location / {
        try_files \$uri \$uri/ =404;
    }
}

# Automatic redirect from HTTP to HTTPS
server {
    listen 80;
    server_name cloud.my-name.eu;

    return 301 https://\$host\$request_uri;
}

Now save the content and close the editor.

Now link the configuration so that NGINX can use it:

sudo ln -s /etc/nginx/sites-available/cloud.my-name.eu /etc/nginx/sites-enabled/

You should also make sure that the default configuration is deactivated:

sudo rm /etc/nginx/sites-enabled/default

For a quick test, open port 443 and restart NGINX:

sudo ufw allow 443

sudo ufw reload

sudo systemctl restart nginx

If everything worked, you should see the default page in the browser at https://cloud.my-name.eu.

Finally, this port should be closed again:

sudo ufw deny 443

sudo ufw reload

Quick & Dirty

# Prepare system & NGINX
sudo apt update && sudo apt upgrade -y
sudo apt install nginx certbot -y

# Set up domain and test with:
ping cloud.my-name.eu

# Get SSL certificate
sudo systemctl stop nginx
sudo ufw allow 80 && sudo ufw reload
sudo certbot certonly -d cloud.my-name.eu
sudo ufw deny 80 && sudo ufw reload
sudo systemctl start nginx

# Set up automatic renewal
sudo crontab -e
# Insert the following line:
# 0 0,12 * * *    certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

# Create NGINX config
sudo nano /etc/nginx/sites-available/cloud.my-name.eu
# Example content:
# ---------------------------------------------------
# server {
#     listen 443 ssl;
#     server_name cloud.my-name.eu;
#
#     ssl_certificate /etc/letsencrypt/live/cloud.my-name.eu/fullchain.pem;
#     ssl_certificate_key /etc/letsencrypt/live/cloud.my-name.eu/privkey.pem;
#
#     root /var/www/html;
#     index index.html index.htm index.nginx-debian.html;
#
#     location / {
#         try_files \$uri \$uri/ =404;
#     }
# }
#
# server {
#     listen 80;
#     server_name cloud.my-name.eu;
#     return 301 https://\$host\$request_uri;
# }
# ---------------------------------------------------

# Activate NGINX site
sudo ln -s /etc/nginx/sites-available/cloud.my-name.eu /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default

# Restart NGINX
sudo systemctl restart nginx