This post explains how to setup a ssl certificates for a reverse proxy.
The example I have used is running ubiqiti’s self hosted UNMS network manager (see https://help.ui.com/hc/en-us/articles/115012196527-UNMS-Installation-Guide)
- FreeBSD 11.4
- nginx 1.18
- certbot 1.50 (uses python 3 (3.7.9)
Lets encrypt is a free service that allows people to automatically create 90 day ssl certificates. It uses a small piece of code (https://certbot.eff.org/)on the webserver to place a request file in a known location and then calls an api on the Letsencrypt system’s which fetches the request and returns the certificates. For simplicity the certbot client needs to be run on the server where the certificate needs to be installed, in our case the nginx reverse proxy.
To solve this the configuration of nginx needs to be setup to allow files created by certbot to be directly accessible from the letsencrypt servers. nginx needs to listen both on ssl (80) and non ssl (443) ports to handle both the requests that Letsencrypt sends and the https website we wish to serve too. non ssl URL’s other than the let’s encrypt ones should be passed through to the back end web server for redirects if appropriate. lets encrypt uses the following url path – http://server.example.com/.well-known/acme-challenge/
server {
listen 80;
server_name unms.example.com;
access_log logs/unms-access.log;
error_log logs/unms-error.log;
location ^~ /.well-known/acme-challenge/ { # for urls that match .well-known/acme-challenge
default_type "text/plain"; #
root /usr/local/www/nginx; # serve files from here.
} #
location / { # Else pass as instructed below
proxy_pass http://unms.mydomain.com:80/; #Backend server redirects to SSL
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection
}
}
server {
listen 443 ssl;
server_name unms.example.com;
ssl_certificate /usr/local/etc/letsencrypt/live/unms.example.com/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/unms.example.com/privkey.pem;
ssl_session_timeout 5m;
access_log logs/ssl-access-unms.log;
error_log logs/ssl-error-unms.log;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
#ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2;
ssl_session_cache shared:SSL:10m;
#ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.2;
#ssl_ciphers RC4:HIGH:!aNULL:!MD5;
#ssl_prefer_server_ciphers on;
keepalive_timeout 60;
client_max_body_size 60M;
ssl_session_cache shared:SSL:10m;
location / {
proxy_pass https://unms.mydomain.com:443;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Using certbot to request and get the certificate. The first time certbot is run there are some terms to accept, but only the first time.
certbot --webroot --webroot-path /usr/local/www/nginx -d server.example.com -m myname@mydomain.org certonly
Links to references I’ve used to create this page
https://help.ui.com/hc/en-us/articles/115015690207-UNMS-Reverse-Proxy