In der Standardkonfiguration werden die Administrationsoberfläche Foris und LuCI des Turris Omnia unverschlüsselt per HTTP angeboten. Für einen sicheren Zugriff bei der Administration sollte HTTPS aktiviert werden, damit Foris und LuCI per SSL/TLS abgerufen werden.
1| SSL/TLS aktivieren
Zunächst muss SSL/TLS in der lighttpd-Konfiguration aktiviert werden. Dies passiert am besten in der Datei /etc/lighttpd/conf.d/ssl-enable.conf:
# This settings enables https with CA signed certificate $SERVER["socket"] == ":443" { ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/server.pem" ssl.ca-file = "/etc/lighttpd/ca.pem" ssl.use-sslv2 = "disable" ssl.use-sslv3 = "disable" ssl.cipher-list = "EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA" ssl.honor-cipher-order = "enable" setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=15768000") # six months # use this only if all subdomains support HTTPS! # setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=15768000; includeSubDomains") } $SERVER["socket"] == "[::]:443" { ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/server.pem" ssl.ca-file = "/etc/lighttpd/ca.pem" ssl.use-sslv2 = "disable" ssl.use-sslv3 = "disable" ssl.cipher-list = "EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA" ssl.honor-cipher-order = "enable" setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=15768000") # six months # use this only if all subdomains support HTTPS! # setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=15768000; includeSubDomains") }
Mit dieser Konfiguration werden gleichzeitig mehrere SSL-Einstellungen für den IPv4 und IPv6-Listener vorgenommen:
- Die SSL-Engine wird aktiviert.
- Es werden die Pfade sosohl zum Server-Zertifikate (inkl. Schlüssel) und zu den CA-Zertifikaten angegeben (s.u.)
- Die Unterstützung von veralteten SSL-Versionen wird deaktiviert
- Die Cipher-Liste wird eingeschränkt gemäß den Empfehlungen von bettercrypto.org
- Die Reihenfolge in der Cipher-Liste wird berücksichtigt
- Es wird ein HSTS-Header gesetzt
Damit sollte eine halbwegs sichere SSL-Konfiguration umgesetzt sein.
2| Zertifikate und Schlüssel erzeugen
Wird eine private CA mit XCA verwaltet (siehe Artikel ‘Private CA erstellen’), kann sich wie im Abschnitt ‘4| Server-Zertifikat erstellen’ beschrieben ein Server-Zertifikat erstellen. Dazu wird zunächst der private Schlüssel aus XCA im PEM-Format in die Zwischenablage kopiert und die Datei /etc/lighttpd/server.pem eingefügt (siehe Zeilen 4 und 17 in /etc/lighttpd/conf.d/ssl-enable.conf). Am Ende der gleichen Datei muss auch noch das Server-Zertifikat eingefügt werden. Die folgenden Bilder zeigen den Export-Vorgang und den Aufbau der Datei:
Für die Datei mit dem Schlüssel sollten die Berechtigungen möglichst restriktiv vergeben werden, damit der private Schlüssel möglichst von niemanden gelesen werden kann:
chmod 600 /etc/lighttpd/server.pem
Danach müssen auch noch die Zertifikate der CAs exportiert werden. Bei mir sind das die Zertifikate der Zwischen-CA und der Root CA. Diese müssen in die Datei /etc/ca.pem eingetragen werden, wobei das Zertifikat der Zwischen-CA am Anfang der Datei eingefügt wird und das Zertifikat der Root-CA an das Ende der Datei kommt.
3| Weiterleitung von HTTP auf HTTPS einrichten
Da es gelegentlich vorkommt, dass man das https:// vergisst wird zusätzlich auch eine Weiterleitung von HTTP auf HTTPS einrichten. Dazu muss zunächst lighttpd-Modul mod_redirect installiert werden:
opkg update opkg install lighttpd-mod-redirect
Anschließend wird die Konfiguration in der Datei /etc/lighttpd/lighttpd.conf angepasst:
server.modules = ( ) server.document-root = "/www" server.upload-dirs = ( "/tmp" ) server.errorlog = "/var/log/lighttpd/error.log" server.pid-file = "/var/run/lighttpd.pid" #server.username = "http" #server.groupname = "www-data" index-file.names = ( "index.php", "index.html", "index.htm", "default.htm", "index.lighttpd.html" ) static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" ) # listen on IPv6 (IPv4 Listener wird per Default gestartet) $SERVER["socket"] == "[::]:80" { } # Weiterleitung aug https aktivieren: $HTTP["scheme"] == "http" { # capture vhost name with regex condition -> %0 in redirect pattern # must be the most inner block to the redirect rule $HTTP["host"] =~ ".*" { url.redirect = (".*" => "https://%0$0") } # Set the environment variable properly setenv.add-environment = ( "HTTPS" => "on" ) } include "/etc/lighttpd/mime.conf" include_shell "cat /etc/lighttpd/modules.d/*.load" include_shell "cat /etc/lighttpd/conf.d/*.conf"
Das Modul mod_redirect wird bei der Installation (s.o.) automatisch aktiviert. Daher muss es in der Konfiguration nicht explizit angegeben werden.
Jetzt kann der Server neu gestartet werden:
# /etc/init.d/lighttpd restart Syntax OK /usr/lib/lighttpd/mod_alias.so /usr/lib/lighttpd/mod_cgi.so
Wenn alles gut läuft ist anschließend ein lighttpd-Listener sowohl für IPv4 als auch für IPv6 auf Port 80 und 443 gestartet:
# netstat -tulpen Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name [...] tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 9877/lighttpd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 9877/lighttpd [...] tcp 0 0 :::443 :::* LISTEN 9877/lighttpd tcp 0 0 :::80 :::* LISTEN 9877/lighttpd [...]
4| SSL/TLS Verbindung überprüfen
Nach den Änderungen sollte im Browser bei der Verbindung ein grünes Schloss angezeigt werden (siehe Screenshot).
Wer ganz sicher gehen will kann abschließend mit nmap überprüfen welche Cipher-Suiten unterstützt werden:
$ nmap --script +ssl-enum-ciphers -n -p 443 192.168.1.1 Starting Nmap 7.40 ( https://nmap.org ) at 2016-12-20 23:37 Eur Nmap scan report for 192.168.1.1 Host is up (0.00s latency). PORT STATE SERVICE 443/tcp open https | ssl-enum-ciphers: | TLSv1.0: | ciphers: | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (dh 1024) of lower strength than certificate key | Key exchange (secp256r1) of lower strength than certificate key | TLSv1.1: | ciphers: | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (dh 1024) of lower strength than certificate key | Key exchange (secp256r1) of lower strength than certificate key | TLSv1.2: | ciphers: | TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (dh 1024) of lower strength than certificate key | Key exchange (secp256r1) of lower strength than certificate key |_ least strength: A