How to secure your website with an Nginx Reverse-Proxy and Acmetool/Let’s Encrypt

Share

Assuming you want to secure your website from the outside environment, I will show you how to properly do that using a reverse-proxy and a http to https redirector on a fresh Debian 8.
logoLet’s start by downloading nginx

apt-get install -y nginx

After which, you should create a new configuration for your reverse-proxy.

sudo nano /etc/nginx/sites-available/reverse

And add the following code in it, modify it accordingly so it will suit your needs

server {
        listen 443 ssl;
        server_name example.com;
        #ssl_certificate 
        #ssl_certificate_key 
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        ssl_session_tickets off; # Requires nginx >= 1.5.9
        ssl_stapling on; # Requires nginx >= 1.3.7
        ssl_stapling_verify on; # Requires nginx => 1.3.7
        location / {
             proxy_set_header        Host $host;
             proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;
             proxy_pass http://192.168.x.x;
        }
}

As you can see I’ve commented the ssl_certificate and ssl_certificate_key lines, for now. We will return to that after we install acmetool. I have to mention that you have to change example.com with your domain and the proxy_pass should point to the IP of your website, webserver, app, etc.
Exit and save the file, and run the following command to activate the virtual host.

sudo ln -s /etc/nginx/sites-available/reverse /etc/nginx/sites-enabled/reverse

To avoid having a conflict between Nginx and acmetool (acmetool requires port 80), we have delete, or modify /etc/nginx/sites-enabled/default. You can delete it by running the command sudo rm /etc/nginx/sites-enabled/default or you can edit it like this:

nano /etc/nginx/sites-enabled/default

find the following lines:

server {
        	listen 80 default_server;
        	listen [::]:80 default_server;

and edit them to look like this:

server {
        	listen 8080 default_server;
        	listen [::]:8080 default_server;

This way nginx will not interfere with acmetool. Don’t worry acmetool has a redirector function that will automatically redirect you from port 80 to port 443 (from http to https).
We will leave nginx as it is for now and we will install and configure Acmetool, so that we can acquire a ssl certificate. To install acmetool we have to run the following commands:

echo 'deb http://ppa.launchpad.net/hlandau/rhea/ubuntu xenial main' > /etc/apt/sources.list.d/rhea.list
	apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9862409EF124EC763B84972FF5AC9651EDB58DFA
	apt-get update
	apt-get install acmetool

Now that we have acmetool installed we just have initialize it and run some commands to enable the redirector and request a certificate.
Run the quickstart wizard, this will set up your let’s encrypt account, will set your renewal cronjob, etc.

sudo acmetool quickstart

This is the result of the command:

————————- Select ACME Server ———————–
Please choose an ACME server from which to request certificates. Your
principal choices are the Let’s Encrypt Live Server, and the Let’s
Encrypt Staging Server.

You can use the Let’s Encrypt Live Server to get real certificates.

The Let’s Encrypt Staging Server does not issue publically trusted
certificates. It is useful for development purposes, as it has far
higher rate limits than the live server.

  1. Let’s Encrypt (Live) – I want live certificates
  2. Let’s Encrypt (Staging) – I want test certificates
  3. Enter an ACME server URL

We will choose (and press) number 1, we want after all live certificates for a live website.
Next, this screen will appear, we will select (and press) number 3, because we want automatic redirection to https.

—————– Select Challenge Conveyance Method —————
acmetool needs to be able to convey challenge responses to the ACME
server in order to prove its control of the domains for which you
issue certificates. These authorizations expire rapidly, as do
ACME-issued certificates (Let’s Encrypt certificates have a 90 day
lifetime), thus it is essential that the completion of these
challenges is a) automated and b) functioning properly. There are
several options by which challenges can be facilitated:

WEBROOT: The webroot option installs challenge files to a given
directory. You must configure your web server so that the files will
be available at . For
example, if your webroot is “/var/www”, specifying a webroot of
“/var/www/.well-known/acme-challenge” is likely to work well. The
directory will be created automatically if it does not already exist.

PROXY: The proxy option requires you to configure your web server to
proxy requests for paths under /.well-known/acme-challenge/ to a
special web server running on port 402, which will serve challenges
appropriately.

REDIRECTOR: The redirector option runs a special web server daemon on
port 80. This means that you cannot run your own web server on port
80. The redirector redirects all HTTP requests to the equivalent HTTPS
URL, so this is useful if you want to enforce use of HTTPS. You will
need to configure your web server to not listen on port 80, and you
will need to configure your system to run “acmetool redirector” as a
daemon. If your system uses systemd, an appropriate unit file can
automatically be installed.

LISTEN: Directly listen on port 80 or 443, whichever is available, in
order to complete challenges. This is useful only for development
purposes.

STATELESS: Some web servers can be configured to respond to challenges
themselves. This removes any need for interaction with acmetool. See
documentation for web server support.

HOOK: Programmatic challenge provisioning. Advanced users only. Please
see documentation.

  1. WEBROOT – Place challenges in a directory
  2. PROXY – I’ll proxy challenge requests to an HTTP server
  3. REDIRECTOR – I want to use acmetool’s redirect-to-HTTPS functionality
  4. LISTEN – Listen on port 80 or 443 (only useful for development purposes)
  5. STATELESS – I will configure my web server with my account key
  6. HOOK – I will write scripts to provision challenges

>

 

We have to agree to the terms of service so we press Y

—————– Terms of Service Agreement Required ————–
You must agree to the terms of service at the following URL to continue:

https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf

Do you agree to the terms of service set out in the above document?

Do you agree to the Terms of Service? [Yn]

And now we have to set up and email for the let’s encrypt account, this way if something goes wrong and the certificates are not renewed, you will be notified by email in the moment that there are 19 day left until your certificate expires.

———————- E. Mail Address Required ——————–
Please enter an e. mail address where you can be reached. Although
entering an e. mail address is optional, it is highly recommended.

E. mail address:

The next step is to install acmetool-redirector, it will be installed as a service so if you want to restart/stop/start it, you should run service acmetool-redirector start/stop/restart. For now, just press Y.

————— Install Redirector as systemd Service? ————-
Would you like acmetool to automatically install the redirector as a systemd service?

The service name will be acmetool-redirector.

Continue? [Yn]

The next screen is just to inform you if acmetool-redirector has been installed/started successfully.

—————- systemd Service Installation Complete ————-
acmetool-redirector has been installed as a systemd service.

The acmetool-redirector service was successfully started.

Press Return to continue.

Just hit Enter and a new screen appears. On this step it asks you if you want to install auto-renewal cronjob. I recommend you press Y, but you can also press N if you want to setup the cronjob yourself.

——————– Install auto-renewal cronjob? —————–
Would you like to install a cronjob to renew certificates automatically? This is recommended.

Continue? [Yn]

And we are finished, the configuration is complete.

————————- Quickstart Complete ———————-
The quickstart process is complete.

Ensure your chosen challenge conveyance method is configured properly
before attempting to request certificates. You can find more
information about how to configure your system for each method in the
acmetool documentation:
https://github.com/hlandau/acme/blob/master/_doc/WSCONFIG.md

To request a certificate, run:

$ sudo acmetool want example.com www.example.com

If the certificate is successfully obtained, it will be placed in
/var/lib/acme/live/example.com/{cert,chain,fullchain,privkey}.

To request a certificate you have to run the command mentioned above. Be aware that for this to work your reverse proxy server needs to have a public IP.

sudo acmetool want example.com 

If the request is successful you have to edit the nginx reverse proxy configuration to set to commented lines we talked about earlier. So the configuration will look something like this:

server {
        listen 443 ssl;
        server_name example.com;
        #ssl_certificate /var/lib/acme/live/example.com/fullchain;
        #ssl_certificate_key /var/lib/acme/live/example/com/privkey; 
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        ssl_session_tickets off; # Requires nginx >= 1.5.9
        ssl_stapling on; # Requires nginx >= 1.3.7
        ssl_stapling_verify on; # Requires nginx => 1.3.7
        location / {
             proxy_set_header        Host $host;
             proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;
             proxy_pass http://192.168.x.x;
        }
}

Restart your nginx server and you should have a working reverse-proxy.

And that’s it, feel free to comment down bellow if you encounter any errors or if you have any questions.

By continuing to use the site, you agree to the use of cookies. More information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close