Home network security – Part 2: HTTPS and TLS hardening

Home network security – Part 2: HTTPS and TLS hardening

In May, we showed you the basic configuration of our Turris Omnia. The Omnia is a Czech router which runs open-source software and is mostly made of open hardware components. In this article, we configure the Omnia to use HTTPS-only and harden its TLS configuration.

Contents

  1. The defaults
  2. Requirements
  3. Step by step from HTTP to hardened HTTPS
  4. Summary
  5. Sources

Always stay in the loop!
Subscribe to our RSS/Atom feeds.

The defaults

By default, our Turris Omnia is reachable via port 80 (HTTP) and 22 (SSH). HTTP is unencrypted. This means that other devices in our network can monitor and read the network traffic between a computer and the Omnia. Furthermore, we can’t be sure that we are really connected with our Omnia when connecting to 192.168.1.1. There is no cryptographic proof.

The solution: Get a certificate, enable HTTPS (port 443) and disable HTTP. Currently, Turris OS shows you a warning that you should enable HTTPS. You can enable this configuration which uses a Turris certificate and not so strict TLS cipher suites.

Subsequently, we want to use our own certificate and only strong cipher suites. If you don’t own a Turris Omnia, you can still try to find according guides for your home router.

Requirements

This time, we need:

  • our Turris Omnia which is connected with our computer and the internet
  • an SSH client on our computer
  • time (if you want to use DHE instead of ECDHE)
  • tools like nmap, sslyze or sslscan

Step by step from HTTP to hardened HTTPS

Our plan is really straightforward: Our Omnia runs lighttpd for HTTP/HTTPS connections. We have to generate a certificate, change the configuration of lighttpd and restart our router.

Be aware: It is possible that you misconfigure lighttpd. Then you will be unable to connect to your Omnia via HTTP/HTTPS. However, you can always fall back to SSH which remains unaffected by the following guide.

Step 1: Connect via SSH

The first step is to establish an SSH connection between your computer and your Omnia. This requires that you installed an SSH client on your device (if you use Linux, it is very likely that you have it installed). Windows users can use PuTTY. The password is the “advanced password” which you can configure separately in Turris OS.

The simple command here is: $ ssh root@[turris router ip].

Step 2: Generate strong DH parameters

The next step is to generate strong DH (Diffie–Hellman) parameters for key exchange. You only need this if you want to use cipher suites with DHE (Diffie–Hellman key exchange). An alternative is ECDHE (Elliptic-curve Diffie–Hellman key exchange). We recommend that you try to use ECDHE only. ECDHE is faster and require less resources.

Generating the following DH parameters can take several hours!

For DHE cipher suites only:

1
2
3
#! /bin/bash
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

Step 3: Generate your certificate

Now we have to create a new folder:

1
2
3
#! /bin/bash
mkdir -p /etc/lighttpd/certs
cd /etc/lighttpd/certs

After that, we have to generate our own certificate:

1
2
#! /bin/bash
openssl req -newkey rsa:4096 -x509 -keyout self-signed-cert.pem -out self-signed-cert.pem -days 365 -nodes

This generates a 4096 bit strong RSA certificate (rsa:4096) which is valid for one year (-days 365). We recommend to use the IP address of your Omnia as “Common Name (e.g. server FQDN or YOUR name)”.

Step 4: Harden your TLS configuration

We generated our RSA certificate. Now we configure TLS. Simply using the defaults here results in a warning when we test our connection:

Warning that DH and EC parameters are too weak

The result shows that we use weak DH parameters and a weak elliptic curve. There are also several cipher suites without DHE/ECDHE. Let’s change this:

1
2
3
4
5
6
#! /bin/bash
# Set read permissions for root only
chmod 400 lighttpd.pem

# Change TLS configuration of lighttpd
vi ../conf.d/ssl-enable.conf

We are using Vim here. If you never used it before, read some beginner’s guides or use your favorite command line editor.

After opening the ssl-enable.conf, we change the configuration to:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$SERVER["socket"] == ":443" {
        ssl.engine = "enable"
        #ssl.pemfile = "/etc/lighttpd-self-signed.pem"
        ssl.pemfile = "/etc/lighttpd/certs/self-signed-cert.pem"
        ssl.honor-cipher-order = "enable"
        ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH"
        ssl.use-compression = "disable"
        setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=63072000; includeSubDomains; preload", "X-     Frame-Options" => "DENY", "X-Content-Type-Options" => "nosniff" )
        ssl.use-sslv2 = "disable"
        ssl.use-sslv3 = "disable"
        # For ECDHE users:
        ssl.ec-curve = "secp521r1"
        # For DHE users:
        ssl.dh-file = "/etc/ssl/certs/dhparam.pem"
}

$SERVER["socket"] == "[::]:443" {
        ssl.engine  = "enable"
        #ssl.pemfile = "/etc/lighttpd-self-signed.pem"
        ssl.pemfile = "/etc/lighttpd/certs/self-signed-cert.pem"
        ssl.honor-cipher-order = "enable"
        ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH"
        ssl.use-compression = "disable"
        setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=63072000; includeSubDomains; preload", "X-     Frame-Options" => "DENY", "X-Content-Type-Options" => "nosniff" )
        ssl.use-sslv2 = "disable"
        ssl.use-sslv3 = "disable"
        # For ECDHE users:
        ssl.ec-curve = "secp521r1"
        # For DHE users:
        ssl.dh-file = "/etc/ssl/certs/dhparam.pem"
}

## Redirect HTTP to HTTPS
$HTTP["scheme"] == "http" {
        $HTTP["host"] =~ ".*" {
                url.redirect = (".*" => "https://%0$0")
        }
        setenv.add-environment = ( "HTTPS" => "on" )
}

Step 5: Restart and test your connection

After saving, we can restart lighttpd: $ /etc/init.d/lighttpd restart. Try to connect to your Omnia using your web browser. Your router should change the connection to HTTPS.

  • Errors like “NET::ERR_CERT_AUTHORITY_INVALID” or “MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT” are normal: We are using a self-signed certificate here. Self-signed certificates are always untrusted by our web browsers. This is normal behavior.
  • If you can’t connect, try to use secp384r1 instead of secp521r1 in your ssl-enable.conf. This elliptic curve is weaker but strong enough for our purposes.

You can validate your configuration using nmap, sslyze and/or sslscan:

  • $ nmap --script +ssl-enum-ciphers -n -p 443 [turris omnia ip]
  • $ sslyze --regular [turris omnia ip]
  • $ sslscan [turris omnia ip]

Our result is shown in the following screenshot:

Our final TLS configuration

This article is part of the "Home network security" series.
Read other articles of this series.

Summary

This configuration example enables HTTPS-only and enforces strong TLS cipher suites. One weak point remains: We are using our own, untrusted certificate. However, this is sufficient for our purposes. Moreover, you can also try to configure an ECDSA certificate instead of our RSA certificate.

One of the next parts of this series will be about improving the security of your SSH connection to the router.

In part 3a, you can read about using your Turris Omnia as network-attached storage which is a big plus for privacy.

Sources