Mit dem DSM Update der Synology auf Version 6 ist es jetzt möglich Zertifikate von Let's Encrypt kostenfrei abzurufen und diese zum Beispiel für den Reverse Proxy zu nutzen. Das ist relativ unkompliziert, mit der grafischen Oberfläche des DSM zu erledigen. Möchte man aber zum Beispiel den Reverse Proxy die Authentifikation eines dahinterliegenden Webdienstes übernehmen lassen und gleichzeitig noch SSL nutzen, ist die Konfiguration nicht mehr mit Bordmitteln des DSM zu bewerkstelligen. In der folgenden Notiz beschreibe ich die Konfiguration des Reverse Proxy mit Authentifikation auf Basis des NGINX Server. Im zweiten Schritt binde ich das Zertifikat von Let's Encrypt in die Konfiguration ein.

Grundsätzliche Voraussetzung für die Nutzung des Reverse Proxy im heimischen Netzwerk ist, dass die Ports 80 und/oder 443 für die Synology auch von extern erreichbar sind. Bei einem Lancom Router zum Beispiel heißt diese Einstellung "Inverses  Maskieren". Ebenso sollte man prüfen, ob die Firewall der Synology diese Ports nicht blockt.

Zuerst melde ich mich mit Rootrechten an der Konsole der Synology an und erstelle die Konfigurationsdatei für den nginx Reverse Proxy. Diese wird, wie andere Konfigurationsdateien des nginx im Ordner /usr/local/etc/nginx/sites-enabled gespeichert. Ich habe die Konfigurationsdatei nach der vollständigen Domainadresse benannt.

vi /usr/local/etc/nginx/sites-enabled/subdomain.domain.de.conf


Für den normalen Seitenaufruf mit Authentifizierung reicht folgender Inhalt. In der letzten Zeile der Konfigurationsdatei wird hinter proxy_pass die <IP> und der <Port> des internen Webdienstes eingetragen der unter der externen Domain erreicht werden soll. Das Zertifikat ist hier noch nicht eingebunden. 

server {
listen 80;

server_name <externer Domainname>;

location / {
return 301 https://<externer Domainname>$request_uri;
}
}

server {
# listen 443 ssl spdy;
listen 443 ssl http2;
server_name <externer Domainname>;

location / {
proxy_set_header Authorization "";
auth_basic "Protected";
auth_basic_user_file /etc/nginx/basic_auth;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_intercept_errors on;
proxy_http_version 1.1;
proxy_pass http://<IP>:<Port>;
}
}

 

Seit der NGINX Server Version 1.9.5 ist das SPDY Modul durch das HTTP/2 Modul ersetzt worden (1). Hier muss die Konfiguration entsprechend der installierten NGINX Version angepasst werden. 

nginx -v


Danach muss die basic_auth Datei mit dem <Benutzernamen> und dem dazugehörigen <Passwort> erstellt werden. Ist in der Datei basic_auth schon ein Benutzer vorhanden, lässt man einfach das -c beim Erstellen des Benutzers weg.

htpasswd -c /etc/nginx/basic_auth <Benutzername>


Danach sollte man in jedem Fall die Konfiguration testen.

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Zeigt der Test keine Fehler an, kann der Nginx mit der neuen Konfiguration neu gestartet werden.

synoservicectl --restart nginx

Beim nächsten Aufruf der externen Domain sollte jetzt die Authentifikationsabfrage des Reverse Proxy erschienen. Nach der Eingabe des oben gewählten Benutzernamens und des Passworts wird der interne Webdienst aufgerufen.

Wer die Zugriffe auf die Authentifikation des NGINX Reverse Proxy loggen möchte kann dies mit dem Setting access_log einrichten. 

access_log   /var/log/nginx/<name>.log;


Einbinden des Zertifikates

Das über das Webinterface des DSM abgerufene Zertifikat kann jetzt in die Konfigurationsdatei eingetragen werden. Das Zertifikat wird beim erstellen im Pfad /usr/syno/etc/certificate/_archive/<zufälliger Name> gespeichert. Wenn mehrere Zertifikate unter /_archive/ gespeichert sind erkennt man sein gerade abgerufenes Zertifikat sehr gut am Datum des Dateiordners. Man kann natürlich auch danach suchen lassen.

grep -rnwi /usr/syno/etc/certificate/_archive -e <text>
/usr/syno/etc/certificate/_archive/<zufälliger Name>/renew.json:3: "domains" : "Domainname; AlternativerName",

In diesem Ordner findet man auch die Datei renew.json. Diese kann man leicht mit einem Editor öffnen und den Inhalt prüfen ob der gewählte Ordner der richtige ist. In dieser Datei steht im Klartext die Domain für die das Zertifikat ausgestellt ist.

Die beiden Dateien aus diesem Ordner fullchain.pem und privkey.pem werden dann inklusive dem kompletten Dateipfad in die Konfigurationsdatei eingetragen. 

 

Die Konfigurationsdatei sollte dann in etwa folgenden Inhalt haben.

server {
listen 80;

server_name <externer Domainname>;

#LetsEncrypt
location ^~ /.well-known/acme-challenge {
root /var/lib/letsencrypt;
default_type text/plain;
}

location / {
return 301 https://<externer Domainname>$request_uri;
}

}

server {
# listen 443 ssl spdy;
listen 443 ssl http2;
server_name <externer Domainname>;
# LetsEncrypt certificates
ssl_certificate /usr/syno/etc/certificate/_archive/<zufälliger Name>/fullchain.pem;
ssl_certificate_key /usr/syno/etc/certificate/_archive/<zufälliger Name>/privkey.pem;
access_log   /var/log/nginx/<name>.log;
location / {
proxy_set_header Authorization "";
auth_basic "Protected";
auth_basic_user_file /etc/nginx/basic_auth;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_intercept_errors on;
proxy_http_version 1.1;
proxy_pass http://<IP>:<Port>;
}
}

 

Nach dem Neustart des NGINX Server wird die Domain mit einem gültigen Zertifikat aufgerufen und es erscheint die Abfrage für Benutzername und Passwort.. 

Eine sehr ausführliche Beschreibung der einzelnen Settings und der Konfiguration des NGINX findet man zum Beispiel hier: (1) https://www.sherbers.de/howto/nginx/

Da Let's Encrypt die Zertifikate nur für drei Monate ausstellt empfiehlt es sich, die Zertifikate automatisch durch einen Cronjob verlängern zu lassen. Dazu legt man im Aufgabenplaner eine neue "Geplante Aufgabe" -> "Benutzerdefiniertes Script" mit folgenden Parametern an.

Vorgang:
<Name>

Benutzer:
root

Zeitlan:
Täglich/Einmal pro Tag

Benutzerdefiniertes Script: 
/usr/syno/sbin/syno-letsencrypt renew-all

 

Im Bild sieht man noch die Ausgabe in eine Datei. Das macht das Debuggen in Fehlerfall einfacher. (/usr/syno/sbin/syno-letsencrypt renew-all -v /var/log/renew_cert.log)

Kommentare powered by CComment