SSL for your Server - SEPIA-Framework/sepia-docs GitHub Wiki

What is SSL / TLS and why do I need it?

Transport Layer Security (TLS) better known under its old name Secure Sockets Layer (SSL) is a cryptographic protocol created to provide secure communication over a computer network. This means it takes care that the data you transfer from one device to another is not readable as clear text for any attacker.
As soon as you open your server to the public (e.g. to access SEPIA on the go on your mobile) you should definitely use encryption, but there is another reason to use it, even if you stay in your local network.

Troubles with Microphone or Server Access

Modern browsers consider websites/web-apps without proper SSL certificate (no HTTPS) as "insecure" and will block access to certain features like microphone, GPS and notifications. In addition any secure website will block access to insecure URLs (HTTP, WS, ...) which can be tricky to handle when your SEPIA servers run in your local private network without SSL protection.

Possible quick fixes for browser issues

The "insecure origin" rule described above has one exception: The local addresses http://localhost and http://127.0.0.1 are considered "secure" because they belong to the same machine that runs the website/web-app and the browser. This means:

  • If you just need a secure client you can host the client data directly on the machine that runs the browser (there are browser plugins like '200 OK' and a million other ways to do this).
  • If your client needs to connect to other insecure local servers run a reverse-proxy and define local URLs for all your servers (this can later be used for self-signed SSL certificates or a "real" solution as described below).

Some browsers might also allow you to define certain origins as secure.

The recommended way is to use self-signed certificates on your SEPIA-Home server via NGINX (see below). The "professional" way is generally more secure and will avoid complaints about your self-signed certificates, but will open up the risk of attacks from outside since your server is public.

Securing your server (basic)

Self-signed certificates will work perfectly fine but your browser and some clients like Android apps may complain that they are insecure because they are not signed by an official authority. The browser will allow you to use them anyway if you click on ignore and you can properly import them on most devices as well ;-)

  • Linux: Open your SEPIA-Home folder (~/SEPIA) and run bash setup-nginx.sh. Install NGINX if not done already, then use the option "self-signed SSL" and follow the instructions.

Securing your server (professionally)

To make your server available to the outside world you need a domain and a SSL certificate. Here you will find some ideas and support to get started. Also make sure that you have setup your network router with port-forwarding as described here: router port-forwarding.

Prelude: Protecting against brute-force login attempts and DDoS attacks

When using a public server it is recommended to implement a rate limit via your proxy. A good article about it including examples can be found HERE for Nginx. Basically a rate limit prevents that users or potential attackers can send too many requests in a short time interval eventually guessing a user's password or crashing the server.

In addition to the proxy controlled rate limit there is a native SEPIA security layer that can be set up using the property called protected_accounts_list in the core settings (see SEPIA Control HUB 'Core Settings' page). It lets you define specific accounts that will be temporarily blocked (~15-30min) after too many failed login attempts in a short time interval (NOTE: the Admin and Assistant account are protected by default). Here is an example of how you would protect the two accounts 'uid1007' and 'uid1009': protected_accounts_list=[uid1007;;[email protected], uid1029;;[email protected]]. Note that user ID and email address need to be given as a combined string like this: 'id;;email'.

SSL with DuckDNS and Let's Encrypt (currently Linux only)

The easiest way to secure your SEPIA-Home server is to obtain a free domain via the dynamic DNS service DuckDNS and get free SSL certificate from Let's Encrypt.
The Advantage of using DuckDNS is that you can do a DNS challenge to prove your domain ownership to Let's Encrypt meaning that you don't have to setup any complicated access to your server from the outside world (technically you just add a TXT record to your DNS zone which can be done via the DuckDNS API).

1) Setup DuckDNS and get your Let's Encrypt certificate

  • Get an account at https://www.duckdns.org/ (free, e.g. via GitHub account)
  • Define your domain (e.g. https://my-fancy-sepia-server.duckdns.org) in your DuckDNS settings
  • Write down the access token given by DuckDNS
  • Open your SEPIA-Home installation and start the setup script (setup.sh for Linux)
  • Choose: 'Setup dynamic DNS with DuckDNS' and enter your DuckDNS domain and access token
  • Open the ~/SEPIA/letsencrypt folder and start the run-certbot-duckdns.sh script
  • Enter a valid E-mail address to get important updates from Let's Encrypt (e.g. when to renew your certificate)
  • If you see no critical errors you should find your new SSL certificate at ~/SEPIA/letsencrypt/config/[your-domain-name]/...
  • Continue with step 2a if you use the SEPIA reverse-proxy or 2b if you use NGINX

2a) Setup the SEPIA reverse-proxy to use your SSL certificate

  • Run ~/SEPIA/letsencrypt/copy-cert-to-keystore.sh to convert the Let's Encrypt certificate to Java-compatible version
  • Make sure your proxy settings are pointing to the correct SSL files (see properties file of SEPIA-Proxy) and run the proxy with SSL support

2b) Setup NGINX to use your SSL certificate (recommended for long-running servers)

  • Run ~/SEPIA/setup-nginx.sh
  • Select 1 to install NGINX if not already done
  • Select 3 to 'Set up NGINX with Let's Encrypt SSL certificate'
  • For experienced users: Check the config-file created during setup to make sure everything worked as advertised. The script should've restarted NGINX as well for you.

Finalize

  • Restart your SEPIA-Home server to activate the DuckDNS worker that will keep your new DuckDNS domain in sync with your network's IP address
  • Todo: set up correct Let's Encrypt renewal script (e.g. via cronjob)

If you use the default proxy settings set by SEPIA your server should be available via one of the following links:

https://[my-duck-dns-domain]:20726/sepia/assist/app/index.html
host name for server:
https://[my-duck-dns-domain]:20726/sepia

or (if all your SSL traffic on port 443 for this domain is redirected to [your-server-ip]:20726):

https://[my-duck-dns-domain]/sepia/assist/app/index.html
host name for server:
https://[my-duck-dns-domain]/sepia

Done :-)

Importing self-signed SSL certificates into SEPIA

Sometimes you have other devices in your network that are using self-signed certificates for SLL/HTTPS. This is a perfectly valid method to securing your communication but you need to tell your SEPIA server to trust them or it will refuse to connect to those URLs. This is done by importing the self-signed SSL certificate into the "Trust-Store" of Java.

To import an self-signed certificate you can use a little helper script located at: ~/SEPIA/scripts/import_SSL_cert_java.sh
There are a few more import scripts you can try. Sometimes bash import_SSL_cert_from_page.sh might already be enough (will import the SSL cert. into the general store).

Example

The general usage of the script is: bash import_SSL_cert_java.sh [REMOTE_ADR] [TRUSTSTORE] [PASSWD] where the last two arguments are optional and should be skipped at first try.
Importing a self-signed certificate from the local domain "https://myserver.local:8087":

cd ~/SEPIA/scripts
bash import_SSL_cert_java.sh "https://myserver.local:8087"

Look out for error messages. If you see something related to "Truststore" your Java seems to be using an non-default path for it. If you can't find the correct settings feel free to ask for help in the issues section.