nginx mit Cloudflare Proxy¶
Wird der Reverse Proxy nur hinter Cloudflare erreichbar gemacht, können Origin Server Zertifikate verwendet werden. Solche werden zwar vom Browser als ungültig angesehen, dies ist jedoch, aufgrund des vorgeschalteten Cloudflare Proxies, irrelevant. Da diese Zertifikate von Cloudflare selbst ausgestellt werden, können die TLS Einstellungen der Domain dennoch auf "Full (Strict)" gesetzt werden:
Die Ausstellung der Zertifikate über das Cloudflare Dashboard kann den folgenden Screenshots entnommen werden:
Die entstehenden Privaten Schlüssel und Zertifikate werden im Verzeichnis /etc/ssl/
auf dem Server gespeichert.
Anschließend wird nginx auf dem Server installiert
apt install nginx-full
Authenticated Origin Pulls¶
Um zu verhindern, das direkte Anfragen an den Webserver gestellt werden können (ohne über Cloudflare Proxy zu gehen) kann der nginx so konfiguriert werden, dass ein mTLS Zertifikat benötigt wird, welches von der "Cloudflare Origin Pull CA" signiert wurde.
wget -O /etc/ssl/cloudflare_ca.crt \
https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem
In jedem nginx Virtual-Host müssen dafür folgende Zeilen zum Server Block hinzugefügt werden:
server {
# ...
# only allow cloudflare to connect to your nginx
ssl_client_certificate /etc/ssl/cloudflare_ca.crt;
ssl_verify_client on;
# ...
}
Die Einrichtung bei Cloudflare ist in deren Dokumentation beschreiben:
IPv6 Adresse pro Virtual-Host¶
Sofern geplant ist, jedem Virtual Host eine eigene IPv6 Adresse zu geben empfielt sich den nginx systemd-Service um einige Sekunden zu verzögern, sodass sichergestellt werden kann, dass das System die IPv6 Adressen der Netzwerkschnittstelle bereits hinzugefügt hat. Dieses Verfahren wurde auch hier beschrieben.
Dazu muss in der Datei /lib/systemd/system/nginx.service
vor der ersten ExecStartPre
Zeile folgendes hinzugefügt werden:
# make sure the additional ipv6 addresses (which have been added with post-up)
# are already on the interface (only required for enabled nginx service on system boot)
ExecStartPre=/bin/sleep 5
Konfiguration für neue Dienste¶
Folgende Schritte sind notwendig, um ein neues HTTP Routing zu konfigurieren:
-
Dienst aufsetzen.
-
Port-Binding von Dienst auf IPv6 Localhost (
::1
) des Hosts. -
Optional: Sofern für die gewünschte Domain noch kein Zertifikat existiert, dieses Ausstellen.
-
Optional: Eigene IPv6 Adresse für Virtual Host konfigurieren.
-
nginx Virtual-Host konfigurieren und aktivieren.
-
Konfiguration testen und nginx neu laden.
Dienst aufsetzen¶
Zum Aufsetzen des Dienstes muss lediglich die jeweilige Docker-Compose Datei kopiert, ggf. angepasst und ausgeführt werden.
Port-Binding von Dienst auf IPv6 Localhost (::1
) des Hosts¶
Die Containerdefinition muss einen entsprechenden Eintrag erhalten, sodass der Port auf dem der Container den Dienst bereitstellt, auf dem Hostsystem lokal verfügbar ist. Dabei darf natürlich nur die linke Seite (hier 8081) verändert werden.
ports:
- "[::1]:8081:80"
Optional: Sofern für die gewünschte Domain noch kein Zertifikat existiert, dieses Ausstellen.¶
siehe oben!
Optional: Eigene IPv6 Adresse für Virtual Host konfigurieren¶
Sofern eine eigene IPv6 Adresse für diesen Dienst verwendet werden soll, wird diese der entsprechenden Netzwerkschnittstelle hinzugefügt, sodass diese in nginx verwendet werden kann.
# /etc/network/interfaces
# ...
iface eth0 inet6 static
# ipv6 address of the host
address 2001:db8:1234:5678::1/64
gateway 2001:db8::1
# service.domain.de
post-up ip -6 a add 2001:db8:1234:5678:5eca:dc9d:fd4e:6564/64 dev eth0
Da Ubuntu netplan
zum Konfigurieren der Netzwerkeschnittstellen verwendet, muss die entsprechende Konfiguration im
Verzeichnis /etc/netplan
angepasst werden.
Die Konfigurationsdatei sollte ungefähr wie folgt aussehen:
network:
version: 2
renderer: networkd
ethernets:
enp1s0:
addresses:
- 10.10.10.2/24
- 2001:db8::5/64
dhcp4: no
routes:
- to: 0.0.0.0/0
via: 10.10.10.1
- to: ::/0
via: 2001:db8::1
nameservers:
addresses: [10.10.10.1, 1.1.1.1, 2001:470:20::2]
addresses
Abschnitt die neue IPv6 Adresse wie
folgt hinzu:
addresses:
...
- 2001:db8:4a:90a:d8d5:dbf4:fd80:8f80
nginx Virtual-Host konfigurieren und aktivieren¶
Anschließend wird die Virtual Host Konfiguration unter dem Pfad
/etc/nginx/sites-available/domain
angelegt. Dabei müssen hauptsächlich die
mit Pfeil markierten Zeilen beachtet werden.
# https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=modern&openssl=1.1.1d&guideline=5.6
server {
server_name service.domain.de; # <---
listen [::]:443 ssl http2; # <---
ssl_certificate /etc/ssl/domain.de.pem;
ssl_certificate_key /etc/ssl/domain.de.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# only allow cloudflare to connect to your nginx
ssl_client_certificate /etc/ssl/cloudflare_ca.crt;
ssl_verify_client on;
location / {
proxy_pass http://[::1]:8081/; # <---
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Konfiguration aktivieren, testen und anwenden.¶
Nun muss noch der Link zu /etc/nginx/sites-enabled/
angelegt werden,
bevor die Konfiguration von nginx getestet werden kann und anschließend
nginx neu geladen werden kann, sofern der Test keine Fehler ergeben hat:
ln -s /etc/nginx/sites-available/service.domain.de \
/etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx