Disclaimer:
-I'm making this guide simply to help other people, i just put together multiple guides found on the internet (which i'll post below). This is meant to be as easy as it gets for a newbie to get NGINX to reverse proxy using https.
-What is a reverese proxy:
https://en.wikipedia.org/wiki/Reverse_proxy
-Using certbot with nginx:
https://hypatiasoftware.org/2016/07/06/httpsssl-made-easy-with-certbot/
-Thank you for the guide, not only i used it, i stole the template to write this one:
https://forums.freenas.org/index.php?threads/how-to-nextcloud-10-w-apache-php-and-mariadb.46111/
-Certbot instructions:
https://certbot.eff.org/all-instructions/#freebsd-nginx
The Goal:
The ultimate goal is to have one domain and redirect the requests simply using "mydomain.com/cloud ; mydomain.com/couchpotato ; /sickrage; etc. "
In order to do so, we will have to get NGINX up and running, use certbot to obtain a certificate, set up nginx to use this certificate, set up nginx to redirect to the appropriate jails. Keep in mind that having a reverse proxy allow you to have some kind of "shield" before jails using simple http, and gives all those jails (in our case but those could ultimately be other servers) anonymity.
Getting Started -
General Assumptions:
- You know how the get a domain
- You are using FreeNAS 9.10.2-RELEASE with FreeBSD Jail Template "------"
- Your FreeNAS is connected to the internet, and your jails are properly configured.
- You know how to use nano.
Specifics:
My Build:
ASRock E3C224
Xeon e3-1231v3
16GB Crucial (2x8gb) ECC DDR3-1600
x6 3TB Western Digital Red
Let's Begin
Creating the Jail
Create Jail
Jails > Add Jail
- Jail Name: nginx_reverse
- Template: "------"
- IPv4 Address: 192.168.1.99
- Leave all else default
SSH to your Jail
Open bitvise/putty or whatever you're using to SSH to you Freenas machine:
- Let's find our Jail
jls
- Select the Jail we created earlier
jexec n. of the jail tcsh
Install the pkg we need
- Get it ready with everything we need
pkg update && pkg upgrade
- Install nano, NGINX, git and python
pkg install nano nginx git python
Get Certbot and get you certs
- Clone Certbot
git clone https://github.com/certbot/certbot.git
- Now let's obtain our Certificate, Certbot will automatically install any system dependencies and create a Python Virtual Environment to manage any Python packages it requires. Remeber that nothing has to be using ports 80 and 443 during the next step and that they have to be open for our jail!
cd certbot
./letsencrypt-auto --debug certonly --standalone -d example.com -d www.example.com
change those to your domain and/or delete the one you're not using, for example i didn't need www.example.com , so i just deleted -d www.example.com.
Generate your own strong and unique Diffie-Hellman (DH) Key
cd /usr/local/etc/ssl/
openssl dhparam -out dhparams.pem 4096
Create ssl_common.conf
- We are going to store all our security settings in this file. I am no expert and i find the following settings to simply work. I'll be more than happy to edit the whole guide, if necessary, to adapt it to a more clean and secure way.
cd /usr/local/etc/nginx/
nano ssl_common.conf
- Simply copy and paste all the following but remember to modify the domain name!
Code:
# Thanks to https://cipherli.st/ for providing a great reference! Please check out their site
# to make sure your SSL Configuration is up to date with current standards! Be aware that in this
# example we use a slightly liberal cipherlist to allow for older browsers on older devices, Eg.
# IE8, android 2.4, etc
# Enable Perfect Forward Secrecy (PFS)
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Disable SSLv2 and SSLv3 (BEAST and POODLE attacks)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Enable our strong DH Key
ssl_dhparam /usr/local/etc/ssl/dhparams.pem;
# Cipher-list for PFS.
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_ecdh_curve secp384r1;
# Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
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
resolver 8.8.8.8 4.4.4.4 valid=300s;
resolver_timeout 5s;
# HSTS Support
add_header Strict-Transport-Security "max-age=63072000;includeSubdomains; preload";
# These headers can break applications, be careful!
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
Setup NGINX
- We need to enter the conf file of NGINX and set it up to use all of this.
nano nginx.conf
- Modify the bit after http to look something like this ( we are going to setup the "proxy_setup.conf" after this step ). Always remember to change the domain name.
Code:
listen 443 ssl;
server_name example.com;
include ssl_common.conf;
include proxy_setup.conf;
- Create the proxy_setup.conf
nano proxy_setup.conf
- Here it is very easy for you to understand what you have to do, i'm going to post examples but those are not going to work with you. You will have to switch the bits to what are your actual Jails local IPs and what you want the proxy_pass to be.
Code:
location /sabnzbd {
proxy_pass http://192.168.192.200:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /sonarr {
proxy_pass http://192.168.192.202:8989;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /couchpotato {
proxy_pass http://192.168.192.201:5050;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /headphones {
proxy_pass http://192.168.192.203:8181;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Check that everything is working
service nginx onestart
- Now everything should be up and running. Check if it is, going to example.com/sonarr. You should see https being used.
service nginx onestop
sysrc nginx_enable=YES
service nginx start
EXTRA
Keep in mind you will have to tweak a few things in sickrage (for example) to make it work. In my case changing the webroot or the base URL did the trick just fine since NGINX was "breaking" the URLs without that set.
Another advice: when changing the proxy setup file, use the command
service nginx reload
, this way you will avoid downtime in case you made mistakes, since nginx won't load the new file but keep using the old (and working) one.
Renew your certificate
- -OPTIONAL- I don't like using vi as an editor, therefore i'm going to switch to nano for crontab as well
setenv VISUAL /usr/local/bin/nano
crontab -e
Code:
30 1 * * 1 ./certbot/letsencrypt-auto renew --pre-hook "service nginx stop" --post-hook "service nginx start"
Test SSL Labs, you should now see an A+!