Secure Nginx Proxy Setup

From Domoticz
(Redirected from Secure Remote Access)
Jump to: navigation, search

Please note! Domoticz now has native HTTPS / SSL support since Version 2.2563 (June 14th 2015)

This guide describes how to harden your Domoticz server for secure remote access on Linux Systems, including authenticating client devices with secure certificates (x509)

Goal

The goal is to use a hardened Nginx proxy to provide secure remote access to your Domoticz instance. Nginx is used by many of the biggest sites on the internet and many people believe its a better candidate for exposing directly to the internet than the included webserver.

Configuring your Domoticz Server behind Nginx Proxy offers the following additional capabilities over Domoticz built-in webserver.

  • Hardened SSL/TLS Configuration
  • Forced HTTPS, Ensure connections are always encrypted.
  • x509 Client Authentication. Secure Access w/out Passwords, impossible to brute force.
  • Ability to parallel proxy of other services, this will allow you to share your Certificate, IP Address and port for more than one Web service. (sorta like Virtual Hosting for SSL/TLS)
  • Ability to Embed Remote Devices in an iFrame Securely and view them from anywhere (Camera Live View Pages)
  • OS Provided Security Updates - Unattended Upgrades.

With a Proper x509 Configuration, Firewall, and SSH Keys required for access your Domoticz Server will not be susceptible to brute force attacks. This method is considered to be one of the most secure methods for remotely accessing your Domoticz Server, only authorized clients in possession of a certificate you signed are ever exposed to the Domoticz process.

This document will outline setting up and configuring a nginx proxy of varying degrees of security, It would be wise to get normal HTTPS working prior to enabling and using x509 Client Certs.

Components used

  • Domoticz (off course)
  • NGINX is a popular lightweight webserver that will proxy requests to Domoticz.
  • SSL/x509 Certs - Encryption Certs+Keys for Clients and Servers
  • Certificate Authority - The authority whom signs certificates it trusts, you can run your own or delegate this to a 3rd party.
  • OpenSSL CLI - Command line KungFu for power users.
  • XCA - Cross Platform OpenSSL GUI for Experts and Novices alike. Download Latest
  • Client Authentication (x509 Auth) - Both the client and server have cryptographic certificates that they use to validate eachother for trust.

Prerequisites

  • Debian derived Linux Server (Debian/Rasbian/Ubuntu/etc)
  • Running Domoticz installation
  • Port forwarding active from your router for TCP/80 & TCP/443

Install additional software on your Domoticz Server

Nginx

Nginx (pronounced engine-x) is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Compared to Apache it is small and uses a lot less memory.

sudo apt-get install nginx-full

OpenSSL

OpenSSL is an open-source implementation of the SSL and TLS protocols. Enables the use of certificates for encryption and authentication.

sudo apt-get install openssl

Haveged

Haveged is a Linux entropy source using the HAVEGE algorithm, this helps the speed up the random generator durring key generation. Helps the system generate entropy on servers with out the normal entropy sources (keyboard/mouse).

sudo apt-get install haveged

Firehol

OPTIONAL: Simple Firewall if you wish to lock down your Domoticz server so even local network access requires going through the proxy... may be good precaution against poor wifi security.

sudo apt-get install firehol

Create Certificate Authority

First step is to create the SSL certificates that wil be used to encrypt the HTTPS traffic. You can also buy an official SSL certificate that will be recognised by the browser and does not give you a warning. In most instances you should have access to each client device accessing your Domoticz Server, you can simply install your own Certificate Authority on these devices and they will be displayed correctly by browsers without throwing a security warning.

This guide gives you two options to create and manage your certs, XCA a Graphical interface to OpenSSL, or the basic OpenSSL CLI, choose one and safely ignore the other.

XCA

Create a New Database in XCA, and on the Certificates tab click New Certificate

Xca-create-ca1.png

Set Signature algorithm to SHA-512 and move to the Subject tab.

Xca-create-ca2.png

Click on Generate a new key and give it a 4096bit RSA and then move to the Extensions tab

Click on the Type under x509v3 Basic Constraints and choose Certification Authority and set your expiration out about 10 years so you dont get locked out. Then press OK.

ADDITIONAL FILES

To enable Strong Crypto we need to generate a dh_params file on our server, this will take a while.. go eat a cookie.

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Also need to create a CRL for revoked certs, you do not have any yet so its empty.

sudo touch /etc/ssl/ca.crl

Install your CA on Client Devices

Installing the CA Cert on all your Client Devices will allow them to display Domoticz without tossing a Certificate Error

in XCA right click on your CA Certificate and Export it into a PEM Format

For OpenSSL CLI extract your ca.crt file from your linux server, leave the keys behind.. This is a public cert and can be transmitted insecurely.

Copy the CA Cert to all your devices, Desktops, Laptops, Mobiles and install it, on most operating systems you simply double click on it and import it into your CA as "Trusted". Mobile Devices are a little harder and you may consider getting your cert signed by a 3rd party authority.

Create Server Side SSL Certificate

Next, we need to create another key. This will be used to generate an SSL certificate for use on the server. Make sure that the certificate contains the url it's going to be used at (for example domoticz.com)

This should go in the Common Name (eg, YOUR name) field. Don't include any https:// prefix.

XCA

Create a Certificate the much same way you created your CA above, except on the Source window make sure you select your CA, pay special attention to your commonName is valid, and finally on the extensions pane set your x509v3 Basic Constraint Type: not defined

Xca-create-ca4.png

Xca-create-ca5.png

Xca-create-ca3.png

Select x509v3 Subject Alternative Name', press Edit and then Add any IP Addresses, Hostnames both Long and Short that you wish to access domoticz from (ie, internal DNS)

Validate your inputs and then press OK.

Now on your linux box lets save the certs, go to Certificates" tab in XCA's Main Display, select your server cert then right click, export to clipboard. Return to the console on your server:

sudo mkdir /etc/ssl/ca

sudo nano /etc/ssl/server.crt

Then paste your cert in and save. Next your key, export it and choose export the private key unencrypted.

sudo nano /etc/ssl/private/server.key

Past the key, then save.

We have to remove the pass phrase from server.key so that it isn't required each time the web server is restarted:

sudo openssl rsa -in /etc/ssl/private/server.key -out /etc/ssl/private/server.key

If the tasks fails, probably the text in the server.key file is formatted wrong. Please verify that the last line contains the closing statement only like "-----END RSA PRIVATE KEY-----"

  Enter pass phrase for server.key:
  writing RSA key

Finally lets set permissions on our keys so only root can read them.

sudo chmod 440 /etc/ssl/private/server.key

Nginx Configuration

Now we need to use the generated certificate on our webserver and let it 'Reverse Proxy' to the Domoticz installation. This way clients from the insecure internet will connect to the Ngnix webserver with a secure connection over https. The Nginx webserver wil forward the request to Domoticz and will translate encrypt the response before sending it over https to the client.

We need to create a configuration file in /etc/nginx/sites-available and call it domoticz for example. Use vi or nano to create the file.

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

/etc/nginx/sites-available/domoticz

## Default all HTTP Traffic to HTTPS
server {
        listen                  80 default;
        server_name             your_domain_name.com;                   # Set to your FQDN
        rewrite                 ^ https://$server_name$request_uri? permanent;
}
 
## Domoticz Secure Proxy
server {
        listen                  443 default ssl;
        server_name             your_domain_name.com;                   # Set to your FQDN
 
        ssl_certificate         /etc/ssl/server.crt;
        ssl_certificate_key     /etc/ssl/private/server.key;
        ssl_dhparam             /etc/ssl/certs/dhparam.pem;
 
        ssl_session_timeout     60m;
        ssl_session_cache       shared:SSL:10m;
        ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers             EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4;
        ssl_prefer_server_ciphers on;
 
        ### UNCOMMENT BELOW FOR x509 CLIENT AUTH
        #ssl_client_certificate /etc/ssl/ca/ca.crt;
        #ssl_verify_client      optional;
        #if ($ssl_client_verify != SUCCESS) { 
        #       return 303 http://www.domoticz.com;                     # Set to your Error Page FQDN.
        #}
 
        add_header              Strict-Transport-Security max-age=63072000;
        add_header              X-Frame-Options SAMEORIGIN;
        add_header              X-Content-Type-Options nosniff;
 
        ## Domoticz
        location / {
                proxy_pass      http://127.0.0.1:8080/;
                access_log      /var/log/nginx/domoticz.access.log;
                error_log       /var/log/nginx/domoticz.error.log;
                ### UNCOMMENT BELOW FOR x509 CLIENT SSO                         
                #proxy_set_header       Authorization $ssl_client_s_dn;
                #proxy_hide_header      Authorization;
        }
 
        ### IP Camera Proxys ####
        # IPCam 1 - Give URL to Live View Page
        #location /ipcameras/cam1 {
        #       proxy_pass      http://192.168.1.100:9989/onvif/media_service/snapshot;
        #}
 
}
 
### Custom Access Denied Page for x509
#server {
#       listen                  80;
#       server_name             access-denied.your_domain_name.com;     # Set to your Error Page FQDN
#       root                    /var/www/access-denied;                 # Path to your error page
#       index                   index.html;                             # Name of your error page
#       error_page              404 /index.html;
#       error_page              400 /index.html;
#       access_log              /var/log/nginx/auth-fail.access.log;    # Logs of failed auths.
#}


Now we need to enable the configuration by creating a symbolic link in '/etc/nginx/sites-enabled'

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

sudo unlink /etc/nginx/sites-enabled/default

We also need to edit the main configuration, to increase the buffersize for allowing large urls used by domoticz

sudo nano /etc/nginx/nginx.conf

and add these lines under the existing http directive.

http {
....
 client_header_buffer_size 32k;
 large_client_header_buffers 16 32k;
....
}

Restart nginx

sudo service nginx restart

Domoticz should be available now on https://my_domain_name.com:port. To access Domoticz from the outside you have to setup port forwarding for tcp/80 and tcp/443 to your Domoticz server..

Now Nginx will listen on both http (80) and https (443) and force all connections to be secure (443). This behavior is best so you can just type your address in the bar without worrying about the prefix.

System Hardening

These Steps are optional to provide additional security and hardening.

Signed by a Pre-Trusted Authority

If you don't want to read the warnings about SSL certificate, and are unable or unwilling to install your own Certificate Authority on your devices you can get a certificate signed by an already trusted Authority. There are many paid vendors that can churn you out a 3year cert for under $20USD within 10mins or you can get a free one from StartSSL if your patient.

The whole process for getting a free StartSSL Signed Cert - written step by step - can be found here.

Client x509 Authentication

Recommended: you can setup Client Side x509 Authentication, this way Domoticz will only be available if a trusted x509 TLS certificate that YOU signed is installed on the client. Without this certificate Nginx will refuse to proxy any requests to Domoticz.

x509 Client Authentication will work fine with a server certificate signed by a 3rd party CA, Your CA you made above will still be used to sign client certs and grant them access.

TIP: Create individual certificates for each client device that will access your Domoticz Server. If the device becomes lost or stolen you can simply revoke that device's certificate

IMPORTANT: Make sure your commonName is your domoticz username, and that you provide a valid email

XCA

Follow the same steps you did to create your server certificate, this time use the HTTPS_Client Template and you can omit the SubjectAltNames.. dont forget to match your CN to your Username in Domoticz.

Export the certificate to a file, choose the export format of: PKCS#12 with Certificate chain

SECURELY Copy the resulting file to the client, and import it into the devices keystore. Use a secure connection such as USB or SFTP to transfer the file, never email it to your self.

Repeat until all your devices have there own cert installed.

Configure Nginx for x509

We need to modify the nginx configuration to accept client SSL authentication.

Edit the '/etc/nginx/sites-available/domoticz file and uncomment the config below the title and modify it as required.

#### UNCOMMENT FOR x509 CLIENT AUTH

Restart the webserver.

sudo service restart nginx

Clients connecting to the webserver without a valid SSL certificate will get a standard error or redirected to your custom error page, clients with a valid certificate will be tunneled directly to your Domoticz process.

Domoticz SSO

Introduced in version v2.4182+

Go to Setup -> Settings -> Website Protection and input the commonName of your client cert into the Username field provided, in the Password field put the emailAddress from your certificate in. Exactly the same way they appear in your client certs.

Set Authentication to Basic-Auth and Apply Settings, you should now be able to add more users via Setup -> More Options -> Edit Users using the same method. commonName = username, emailAddress= password.

User Permissions will now work and the username will be extracted from the certificate you provide, no password prompt will appear, however please note if a matching commonName/emailAddress are not found in the username/password database an Offline error message will appear.

You can still issue external json requests using Basic-Auth when directly calling the native http/https server, for example http://username:[email protected]:8080/json.html?

If you use a firewall to lock down your system and still need to run json calls from remote machines you can tunnel your requests over SSH to the loopback device, allowing easy scripting with client TLS support.

If for any reason you get locked out of your Domoticz Server, restart it with the -nowwwpwd argument.

Firehol

If you wish to force all access to Domoticz through your proxy, even on your LAN, you should install a local firewall and block access to all but your newly hardened services.. If your using x509 auth this is suggested to help prevent local attacks bypassing your security. (ie, accessing domoticz via http on port 8080)

Here is a sample firehol configuration:

/etc/firehol/firehol.conf

version 5
 
interface any world
        client all accept
 
interface eth0 lan
        server http accept
        server https accept
        server ssh accept
        protection strong

Test out your configuration:

sudo firehol try

If you were able to commit without the firewall interfering, try logging in again via SSH to double check. Then lets enable the firewall at boot:

sudo nano /etc/default/firehol

#To enable firehol at startup set START_FIREHOL=YES
START_FIREHOL=YES

Proxy iFrames for Custom Templates

If you want to use Domoticz Custom Templates and embed another device into an iFrame you will need to proxy that also. For security reasons modern browsers will not allow scripts/code to execute from an external site via an iFrame. Since we have the proxy already running we can simply proxy anything we also want to run in an iFrame so it loads from the same site as Domoticz.

In the configuration provided above is an example for setting up a proxy for an IPCamera View, modify it for your needs and copy/paste it as many times as you need. Then restart Nginx and test your proxy manually by visiting the path you specified.

If your page displayed correctly go to your Domoticz install, browse to domoticz/www/templates/ path create a file such as cam1.htmlusing this example:

<iframe frameborder="0" allowtransparency="true" src="/ipcameras/cam1" style="height: 95%; width: 100%; position: absolute; left: 0; top: 40px;"></iframe>
<!-- Adjust the positioning as needed for your theme -->

Make sure the Custom Tab is enabled in your settings page and then refresh, you should now be able to access your camera securely via HTTPS.

With a bit of testing this typically will work for other hosted services too, for example: Sonarr, NZBGet, Transmission, CouchPotato, VirturalBox, FreeNAS, etc.. now all remotely accessible with x509 auth via Domoticz, awesome!