Easily configure nginx for reverse proxying

nginx is a web server and reverse proxy, meaning you can use it to expose your servers to the world. Here's how to configure it for reverse proxying.

Easily configure nginx for reverse proxying

nginx ("engine x") is a web server and reverse proxy, meaning you can use it to expose your servers to the world. Here's how to configure it for reverse proxying.

If you're using a fresh Linux install, the first step is to install nginx. With the default package manager, install the nginx package. For example, on Debian-based system, you'd run:

$ sudo apt-get install nginx

If your sistem already has Apache installed, you're gonna have to remove it by running:

$ sudo apt-get remove --purge apache2 apache2-utils

and, optionally (if you don't care about the config files):

$ sudo rm -rf /etc/apache2

Next step, identify your server's port. For example, if you're running a Ghost instance, the default port is 2368. Be sure to remember it or write that down, because we'll need it soon.

Now, navigate to /etc/nginx/sites-available and create a configuration file. Name it whatever, just end it with .conf. Next, use your favorite text editor to edit that file and insert this text:

server {
  return 403;
}

server {
  listen 80;
  server_name my.doma.in;

  location / {
    proxy_set_header   X-Forwarded-For $remote_addr;
    proxy_set_header   Host $http_host;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection upgrade;
    proxy_set_header   Accept-Encoding gzip;
    proxy_pass "http://127.0.0.1:PORT";
  }
}

The listen instruction tells the server to listen for incoming connections on port 80. Then, we instruct the server to only do that if the domain is included in server_name; change the values accordingly. You can include multiple, space-separated domains. Next, we define the reverse proxy. The X-Forwarded-For identifies the IP address before proxying, and the Host identifies the target. The other three headers are included for websocket support, so you can remove them if you don't need them. Finally, we specify that the proxy should pass everything to localhost on port PORT (the one you got before). Everything is wrapped inside a server block, to denote a server.

The first server block is actually to stop the requests from reaching your server from other domains. It's a "catch-all"-style server.

To enable a server, you have to create a symlink to it in the /etc/nginx/sites-enabled directory:

$ sudo ln -s /etc/nginx/sites-available/FILE.conf /etc/nginx/sites-enabled/

Now, enable nginx with sudo systemctl start nginx and connect to your machine. It will load your server, but you'll notice a "Not Secure" warning nect to the URL. To fix that, we'll use LetsEncrypt to create a certificate and Certbot to manage it.

Certbot is a snap, which is a cross-distro package. To install snaps, you must install snapd. Once you're done, install Certbot with:

# Install the certbot snap...
$ sudo snap install --classic certbot

# and make it executable
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Then, to obtain a certificate, it's as simple as running

$ sudo certbot --nginx

which will open an interactive menu that'll let you select the website(s) you'd like to enable HTTPS on.

When you're back aat the command line, take a look at your website and ensure that you get redirected to the HTTPS version automatically. If so, congrats!

The last step is actually to try automatic renewals. To do that, simply run:

$ sudo certbot renew --dry-run

and confirm that it goes well.