NGINX Reverse Proxy mit Let’s Encrypt und Cloudflare

Da mir dieses „ständige“ ändern der TXT-Records im DNS einfach zu mühsam ist, habe ich meine Homelab Domain zu Cloudflare als DNS-Provider umgezogen. Normalerweise betreibe ich ja alle anderen Domains unter eigenen Nameservern allerdings ist mir ein direktes Plugins für PowerDNS nicht bekannt.

Für einen Umzug der Nameserver ist dies entsprechend bei dem Unternehmen umzusetzen bei dem ihr auch eure Domain gehostet habt. In meinem Fall ist das Netcup (übrigens sehr zu empfehlen). Bis die Umstellung schlussendlich vollzogen ist, kann es bis zu 48 Stunden dauern. Geduld ist also hier gefragt.

Mein reverse Proxy läuft unter Debian 9 (alias Stretch). Auf diesem installieren wir als erstes NGINX aus den offiziellen Paketquellen. Die Debian Pakete sind meist etwas veraltet und ich hätte gerne bei solchen Anwendungen immer die neusten Sicherheitsupdates eingespielt. Zudem arbeite ich in diesem Fall als root, solltet ihr als „normaler“ User arbeiten, ist vor die Befehle ein sudo zu setzen.

NGINX Installation

wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key

Die Paketquellen müssen noch in eine apt-Datei hinzugefügt werden. Ich lege mir, der Übersichtlichkeit halber, eine neue an und editiere nicht die vorhandenen.

nano /etc/apt/sources.list.d/nginx.list

Dort fügt ihr folgende Zeilen ein:

deb http://nginx.org/packages/debian/ stretch nginx
deb-src http://nginx.org/packages/debian/ stretch nginx

Anschließend aktuallisieren wir die Paketquellen und installieren NGINX.

apt update && apt install nginx -y

Da wir es später eh noch brauchen, werden wir direkt noch die Deffie Hellmann Signatur anlegen. Hierzu wechseln wir ins SSL Verzeichnis des Systems

cd /etc/ssl/certs

Anschließend erstellen wir die PEM-Datei

openssl dhparam -out dhparams.pem 2048

Let’s Encrypt Zertifikate

Um die Let’s encrypt Zertifikate auch anfordern zu können, werden wir noch Certbot installieren. Hier bedienen wir uns der Backports Paketquellen von Debian. Diese müssen ebenfalls noch hinzugefügt werden. Ich nehme hierfür die backports.list

deb http://ftp.debian.org/debian stretch-backports main

Auch jetzt aktuallisieren wir wieder die Paketquellen und installieren die notwendigen Pakete

apt install python-certbot-nginx python-certbot-dns-cloudflare -y -t stretch-backports

Die Authentifizierung gegen Cloudflare erfolgt mittels Email-Adresse und API-Key. Letzteren bekommt ihr in eurer Accountverwaltung von Cloudflare. Wir legen uns einen Ordner an in dem wir dann schlussendlich eine Datei setzen werden die unsere Zugangsdaten beherbergt.

mkdir -p ~/.secrets/certbot

In diesem Ordner erstellen wir dann die Datei cloudflare.ini in die folgender Inhalt kommt:

# Cloudflare API credentials used by Certbot
dns_cloudflare_email = cloudflare@example.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567

Natürlich müsst ihr die zwei Werte entsprechend euren Zugangsdaten anpassen. Anschließend schrenken wir noch die Rechte auf die Datei ein

chmod 600 ~/.secrets/certbot/cloudflare.ini

Wenn eure Domain vollständig umgezogen ist, könnt ihr mit folgendem Befehl nun ein Wildcard Zertifikat von Let’s encrypt anfordern

certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -i nginx -d "*.example.com" -d example.com --server https://acme-v02.a
pi.letsencrypt.org/directory

Natürlich müsst ihr noch die Domain auf eure gewählte umschreiben. Ist alles richtig konfiguriert und hat Cloudflare das DNS Setup schon vollständig übernommen, wird nun das Zertifikat ausgestellt.

NGINX Reverse Proxy

Als letztes kümmern wir uns darum die Weiterleitung einer Anfrage an den externen Webserver weiter zu reichen. Unter der aktuellen Debian Version speichert NGINX seine Konfigurationsdateien unter

/etc/nginx/conf.d

Entsprechend legen wir dort eine neue Datei an. Ich benennen diese Dateien immer nach der eigentlichen Domain, sodass für mich eine schnelle Zuordnung der Konfigurationsdateien möglich ist.

Die Konfiguration im Detail ist nicht von mir, sondern von diesem GIST aus abgeleitet. Ich habe nur ein paar Abänderungen vorgenommen, dass diese auf mein System passen.

server {
   listen 80;
   server_name www.example.com example.com
   return 301 https://$host$request_uri;
}

# SSL configuration
server {
  listen 443 ssl;
 server_name www.example.com example.com;
   ssl_certificate      /etc/letsencrypt/live/www.example.com/fullchain.pem;
   ssl_certificate_key  /etc/letsencrypt/live/www.example.com/privkey.pem;
  
   # Improve HTTPS performance with session resumption
   ssl_session_cache shared:SSL:10m;
   ssl_session_timeout 5m;

   # Enable server-side protection against BEAST attacks
   ssl_prefer_server_ciphers on;
   ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
  
   # Disable SSLv3
   ssl_protocols TLSv1.2;

   # Diffie-Hellman parameter for DHE ciphersuites
   # $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
   ssl_dhparam /etc/ssl/certs/dhparams.pem;

   # Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security)
   add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";  

   # Enable OCSP stapling (http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox)
   ssl_stapling on;
   ssl_stapling_verify on;
   ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
   resolver 8.8.8.8 8.8.4.4 valid=300s;
   resolver_timeout 5s;

# Required for LE certificate enrollment using certbot
   location '/.well-known/acme-challenge' {
        default_type "text/plain";
        root /var/www/html;
   }
   location / {
        proxy_pass http://{IPDEINESWEBSERVERS};
   }
}

Anschließend testen wir die Konfiguration mittels

nginx -t

Sollte alles in Ordnung sein, starten wir NGINX neu und gehen somit mit unserer neuen Konfiguration live.

systemctl restart nginx

Wenn alles korrekt gelaufen ist, könnt ihr nun eure Webseite, geschützt durch das Zertifikat, erreichen. Sollte das nicht der Fall sein, könnt ihr im error.log entsprechende Fehler finden und diese bereinigen.

8 Kommentare

  1. Ist das richtig
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/www.wetter-ockenheim.de/fullchain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    oder ehr das

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    LG Jack

    • Der Kommentar darf drin bleiben. Ich wollte eigentlich das GIST noch verlinkt haben. Ich schreibe ja, dass ich es übernommen haben. 🙂

  2. Pingback: Traefik as Reverse Proxy in Docker – Startupbeaver

  3. Hallo TEQQY, vielen Dank für echt tollen Tuts.

    Ich hatte bisher einen Reverse Proxy auf Apachen Basis, möchte mein Notebook jetzt aber gegen einen Raspberry Pi 4 austauschen und dort dann auf NGINX setzen. Was ich bei der Cloudflare Lösung noch nicht verstanden habe, ist der Let’s Encrypt Part.

    Wenn ich das mit Cloudflare richtig verstanden habe, dann lenke ich ja meine DNS Anfragen, welche normal bei meinem Provider landen, auf Cloudflare um. Somit können die Ihre ganzen Prüfungen usw. vorgeschaltet laufen lassen.

    Jetzt habe ich ja z.B. am Tag X folgende 2 Subdomain via Let’s Encrypt eingerichtet.

    1.) sub1.fqdn.tld
    2.) sub2.fqdn.tld

    dann wegen mir 1 Woche später noch

    3.) sub3.fqdn.tld

    Ich gehe mal davon aus, das die SSL Zertifikat immer noch auf meinem NGINX „greifen“ und intern weiterleiten.

    Wie spielt hier jetzt aber Cloudflare in Verbindung mit Let’s Encrypt zusammen. Vielleicht kannst Du mir das anhand eines Beispiel bildhaft machen.

    Vielen Dank
    Gruß H-BLOGX

    • Hallo H-BLOGX
      in meinem Fall wird Cloudflare eigentlich nur interessant da LE eine API hat welche die automatische Wildcardverlängerung und -aktivierung via Cloudflare ermöglicht. Es gibt ja noch andere DNS Provider die funktionieren würden. Sobald du ein Wildcard Zertifikat hat, spielt es keine Rolle mehr wieviele Subdomains du hast.
      Je nach dem kannst du auch eine Wildcard-Weiterleitung von allen Subdomains auf dein Server machen. Dann brauchst du keine eigenen Subdomains mehr anlegen sondern konfiguriert im NGINX einfach die, die wirklich angenommen werden sollen.

      Wenn du bei CF die DDoS Protection einschaltest schieben die sich zwischen dem Aufrufer der Seite und deinem Server. Jeglicher Traffik geht dann über die Seite von CF!

  4. Erst einmal vielen Dank für deine Anleitungen. Ich versuche mich gerade an einem Reverse Proxy für Bitwarden und Nextcloud. Hierzu würde ich gerne diese Anleitung nutzen.
    Den DNS habe ich ebenalls auf Cloudflare gewechselt, damit hierüber die Wildcard aktualisiert werden kann.

    Die Anleitung basiert auf Debian. Wie würden die Befehle für Ubuntu lauten?
    Über eine Hilfe wäre ich dankbar, bin noch Linux-Neuling.

    „deb“ http://nginx.org/packages/debian/ stretch nginx
    „deb-src“ http://nginx.org/packages/debian/ stretch nginx

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.