[HOW-TO] QNAP Apache Reverse Proxy with SSL using Let's Encrypt (for apps like SickRage, Couchpotato, NZBGet, Sonarr)
Posted: Mon Nov 19, 2018 3:21 am
Hey fellow QNAP'ers,
I've perused countless guides here on the QNAP forums detailing how to set up reverse proxies for web apps like SickRage, Couchpotato, NZBGet, etc.. using QNAP's apache so that you could access the app via a directory root on your domain such as mycooldomain.com/sickrage. However, none of them could help me get this all working using HTTPS/SSL and specifically with a Let's Encrypt SSL cert/key, which is legit and free if you own a domain name.
This guide will show you how to get it done using QNAP's built-in Apache web server. You will need to know how to access your QNAP via SSH (bash shell) and how to use a text editor such as nano in order to create your own customized apache configuration file and save it to your QNAP web directory. You should also have git and python 2.7 installed, either via QNAP's App store or via Entware (opkg), as we will be using a really useful QNAP shell script from GitHub in order to automatically set up our free Let's Encrypt SSL certificate/key. In addition to those app dependencies, having some basic unix command-line skills will be very helpful so that you can navigate the innards of your QNAP using a terminal (Putty, etc) and performing some commands that I have outlined below. If you have no idea what I'm talking about by this point, then you are most likely not going to be able to follow this guide...Anyway, here we go:
NOW YOU ARE FINALLY DONE! Your secured web apps should look like this in a Chrome browser now:
The trick to all of this was to figure out that the Let's Encrypt Github script installed the key and cert in "/etc/stunnel/" where QNAP's Apache web server looks.
If you ever need to edit your customized.conf file, make sure to also restart the QNAP web server using the "/etc/init.d/Qthttpd.sh restart" command as shown above.
Let me know if you run into any issues--I must have been trying to get this to work for a week before I finally put all the puzzle pieces together, so don't be discouraged if somewhere along the way you got lost or if something doesn't work. I basically took 2 or 3 other guides here on the QNAP forums and pieced them all together to get my finalized SSL-enabled customized QNAP Apache web server with Reverse Proxy webroots for all of my Usenet web apps. This should work for Sonarr, Radarr, CouchPotato, SickRage, SickChill, Medusa, Tautulli, NZBGet, Sabnzbd, Ombi, Transmission, NZBHydra, and many more. The best part about it is that we let QNAP's Apache handle the proxying and the SSL so that each individual app does not need to be configured with SSL at all. Like I stated previously, the only setting you will probably need to change is the webroot (/nzbget, /taututlli, etc.) in each app's config page.
If you run into any issues, and I'm sure you will at some point, PLEASE do not hesitate to post about it. Provide some logs or error messages and I will do my best to help you sort through it. Good luck!
NOTE: The Let's Encrypt cert expires after 90 days I believe, so all you need to do is run the "renew_certificate.sh" script in your "qnap-letsencrypt" directory that you ran earlier from the GitHub page in order to renew the SSL cert. The GitHub page also describes setting up a cronjob to do this automatically so you don't have to do it yourself, but choose whatever method you want.
Cheers!!
I've perused countless guides here on the QNAP forums detailing how to set up reverse proxies for web apps like SickRage, Couchpotato, NZBGet, etc.. using QNAP's apache so that you could access the app via a directory root on your domain such as mycooldomain.com/sickrage. However, none of them could help me get this all working using HTTPS/SSL and specifically with a Let's Encrypt SSL cert/key, which is legit and free if you own a domain name.
This guide will show you how to get it done using QNAP's built-in Apache web server. You will need to know how to access your QNAP via SSH (bash shell) and how to use a text editor such as nano in order to create your own customized apache configuration file and save it to your QNAP web directory. You should also have git and python 2.7 installed, either via QNAP's App store or via Entware (opkg), as we will be using a really useful QNAP shell script from GitHub in order to automatically set up our free Let's Encrypt SSL certificate/key. In addition to those app dependencies, having some basic unix command-line skills will be very helpful so that you can navigate the innards of your QNAP using a terminal (Putty, etc) and performing some commands that I have outlined below. If you have no idea what I'm talking about by this point, then you are most likely not going to be able to follow this guide...Anyway, here we go:
- Firstly, you will want to enable the Apache Web Server if you haven't already done so via your QNAP's Settings in Control Panel > Web Server, as shown below:
I've set it up using port 80 as the default HTTP port and 443 as the default HTTPS port (which is standard and these are the ports my guide follows throughout). Make sure this is set up and enabled before you do anything else!
- Now, you will want to set up your Let's Encrypt certificates using Yannik's qnap-letsencrypt shell script that is hosted on github here: https://github.com/Yannik/qnap-letsencrypt. There, you will find a step-by-step guide on how to install the Let's Encrypt certificate and keys onto your QNAP. You will need to have a valid domain name in order to do this, such as mycooldomain.com, otherwise, why are you trying to install a Let's Encrypt cert to begin with?... I ended up git cloning the "qnap-letsencrypt" folder into my web root directory "/share/Web", so you should probably do the same so you can easily find it later on down the road if you need to re-run the bash scripts.
- If all of that went well, then you are half-way there! You have just installed Let's Encrypt SSL certificates and keys on your QNAP and the GitHub script should have configured the built-in QNAP Apache web server to work with the Let's Encrypt cert. All of this should have gone smoothly without any errors, otherwise you will have to go back and make sure the "qnap-letsencrypt" scripts work properly or the rest of the guide is useless!
The next steps involve setting up a customized Apache configuration file and defining Virtual Servers in order to get the reverse proxies up and running for all your web apps. The great part about this is after you're done, you DO NOT need to enable HTTPS/SSL on any of your apps individually. Apache will handle the SSL and your apps are none the wiser. Everything will be defined and set up using one configuration file and any changes or additions you need to make (such as adding another app) will be done using this customized.conf file.
- Open up nano or a text editor of you choice and paste the following into it:
Code: Select all
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so
<VirtualHost *:443>
RequestHeader set X-Apache-Proxy "https"
ServerName domain.com
SSLEngine On
SSLProxyEngine On
SSLHonorCipherOrder on
SSLCipherSuite EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:!MD5
SSLProtocol All -SSLv2 -SSLv3
SSLCertificateFile "/etc/stunnel/stunnel.pem"
SSLCertificateChainFile "/etc/stunnel/uca.pem"
ProxyPreserveHost On
ProxyRequests Off
ProxyVia Off
<Location /sickchill>
Order deny,allow
ProxyPass http://127.0.0.1:8081/sickchill
ProxyPassReverse http://127.0.0.1:8081/sickchill
</Location>
<Location /nzbget>
Order deny,allow
ProxyPass http://127.0.0.1:6789/nzbget
ProxyPassReverse http://127.0.0.1:6789/nzbget
</Location>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
DocumentRoot "/share/Web"
<Directory "/share/Web">
Options FollowSymLinks MultiViews
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName domain.com
Redirect / https://domain.com/
</VirtualHost>
OK! So this is where the magic happens. You can save this file as customized.conf in your web root directory. For my QNAP, this directory is "/share/Web", but it may be different for you (doubtful if you are using QNAP's Apache). If for some reason you defined your web root directory to be somewhere else, you can save the customized.conf file there instead and also edit the customized.conf file near the bottom where it defines the DocumentRoot and Directory as "/share/Web" and change it to your root directory. You will also want to change "domain.com" throughout the customized.conf file to your specific domain name as well.
- The areas that you see where I have the <Location> tags are where the reverse proxy magic happens. I have 2 apps configured here: SickChill (a fork of SickRage) and NZBGet. You can just copy and paste that entire section and add as many as you want, or remove sections as you please. This is where the reverse proxy magic happens:
Code: Select all
<Location /sickchill>
Order deny,allow
ProxyPass http://127.0.0.1:8081/sickchill
ProxyPassReverse http://127.0.0.1:8081/sickchill
</Location>
You can replace "http://127.0.0.1:8081/sickchill" (twice) with wherever your app resides on your system. For me, my SickChill app is on the same machine as the web server (QNAP), so I have the IP as 127.0.0.1, but if your app is on a different machine you can just use that internal IP (192.168.x.x for example). The port # for my Sickchill installation is 8081, so you can also change that to whatever port you have your app configured for. After that comes the webroot "/sickchill". I've decided to go with that but you can make it whatever you want. Just keep in mind that for certain apps like CouchPotato, SickRage, Tautulli, Radarr, etc you will need to specify the webroot in their settings somewhere, so make sure you use the same webroot here as you set up in each app's configuration/settings page. NZBGet does not require you to specify a webroot, but I used "/nzbget". Keep in mind to change the webroot in the URL as well as on the first line in the <Location /sickchill> tag. You will use this webroot to access your web app's UI later on.
- After you are done editing your customized.conf and saving it to your web root directory, there is just one more step that you will need to perform in order to get your QNAP's apache to read it. You will need to Include this customized.conf file in your Apache's main configuration file. For me it is found at '/etc/config/apache/apache.conf'. So all you have to do is SSH into your QNAP (if you aren't already in) and just nano the apache.conf file, as so:
Code: Select all
nano /etc/config/apache/apache.conf
Then, scroll to the very bottom and paste this new line at the very end:
Code: Select all
Include /share/Web/customized.conf
Remember, my customized.conf was saved in my web root directory "/share/Web", so if you saved your customized file somewhere else, make sure to change the path above.
- After the file is saved (Ctrl-o, Enter in nano), you will just need to restart the QNAP HTTP server by performing this command in your shell:
Code: Select all
/etc/init.d/Qthttpd.sh restart
This will restart the QNAP Apache web server and read your customized configuration file as well as load the Apache modules we included at the beginning of our .conf file. Now you can go to https://domain.com/sickchill or wherever you specified your web app to be, and you should see a nice little lock in the URL bar with a valid Let's Encrypt cert!!! Also, remember that you do NOT need to port forward any ports from your web apps on your router such as 6789, or 8081, or 5050, etc. The only ports that need to be forwarded to your QNAP IP is port 80 and port 443 which are the HTTP/HTTPS ports. The customized.conf is also set up to redirect any HTTP (non-secure) traffic automatically to HTTPS, so even if you try going to http://domain.com/sickchill, it should automatically re-direct you to the HTTPS page with the secure lock.
The main thing to remember here is that Apache is handling all the security and traffic to and from your browser and server, wherever on the internet you may be. This is definitely the safest way to configure all of this, as opposed to opening up dozens of ports and relying on each web app to provide you with security. Apache is literally designed to handle this type of thing, so proxying everything through that is the smartest way to do it, especially using SSL encryption
NOW YOU ARE FINALLY DONE! Your secured web apps should look like this in a Chrome browser now:
The trick to all of this was to figure out that the Let's Encrypt Github script installed the key and cert in "/etc/stunnel/" where QNAP's Apache web server looks.
If you ever need to edit your customized.conf file, make sure to also restart the QNAP web server using the "/etc/init.d/Qthttpd.sh restart" command as shown above.
Let me know if you run into any issues--I must have been trying to get this to work for a week before I finally put all the puzzle pieces together, so don't be discouraged if somewhere along the way you got lost or if something doesn't work. I basically took 2 or 3 other guides here on the QNAP forums and pieced them all together to get my finalized SSL-enabled customized QNAP Apache web server with Reverse Proxy webroots for all of my Usenet web apps. This should work for Sonarr, Radarr, CouchPotato, SickRage, SickChill, Medusa, Tautulli, NZBGet, Sabnzbd, Ombi, Transmission, NZBHydra, and many more. The best part about it is that we let QNAP's Apache handle the proxying and the SSL so that each individual app does not need to be configured with SSL at all. Like I stated previously, the only setting you will probably need to change is the webroot (/nzbget, /taututlli, etc.) in each app's config page.
If you run into any issues, and I'm sure you will at some point, PLEASE do not hesitate to post about it. Provide some logs or error messages and I will do my best to help you sort through it. Good luck!
NOTE: The Let's Encrypt cert expires after 90 days I believe, so all you need to do is run the "renew_certificate.sh" script in your "qnap-letsencrypt" directory that you ran earlier from the GitHub page in order to renew the SSL cert. The GitHub page also describes setting up a cronjob to do this automatically so you don't have to do it yourself, but choose whatever method you want.
Cheers!!