Teil 2: Öffentlich mit opnSense Firewall / HAProxy / Let's Encrypt Zertifikat

Ziele

Der Betrieb eines Plex Media Servers mit einem Let's Encrypt Zertifikat und HAProxy ist auf der OPNsense Firewall schön übersichtlich dargestellt und es sind nur folgende Schritte nötig, um das Ziel dieses 2. Teils zu erreichen:

Dennoch: Diese Ausbaustufe ist zwar nun für den öffentlichen Betrieb geeignet, muss aber regelmäßig nun aktualisiert und gepflegt werden. Nichts ist schlimmer als eine veraltete und damit angreifbare Installation.

Letzte Aktualisierung:

  • 20.08.2023: Automatisierung für HAProxy erweitert
  • 11.12.2022: Initiales Dokument

Vorbedingung für öffentlichen Betrieb

  • Plex aus dem ersten Teil ist installiert und bereit.
  • Eine eigene Subdamain Domain mit fester IP oder Alias auf DyDNS Adresse ist verfügbar.
  • opnSense Firewall
    • Wichtig! Die Adminoberfläche wurde von Port 443 auf 4433 umgelegt.
    • Mit den instalierten Plugins os-haproxy und os-acme-client.
    • Der Zugriff auf TCP Port 443 ist an der WAN Schnittstelle erlaubt/freigegeben.
    • Intern sollte der EXTERNERHOSTNAME auf die IP der OPNsense gesetzt werden (damit auch interne Aufrufe an den HAProxy geleitet werden).

Screenshot%202022-10-30%20124502

Begrifflichkeiten

  • EXTERNERHOSTNAME = Der extern erreichbare Hostname
  • ACCOUNTNAME = Name des Let's Encrypt Accounts
  • EMAILADRRESSE = Email Adresse des Let's Encrypt Accounts
  • PLEXTIP = IP Adresse des lokalen Plex Media Servers
  • PLEXHOSTNAME = Hostname des lokalen Plex Media Servers

Diagramm

Damit sieht das Setup so aus:

                                                                  ┌─────────────────────────────┐
                  ┌─────────────────────┐                         │ TrueNAS                     │
                  │ OPNsense            │                         │   192.168.178.100           │
                  │   192.168.178.1     │                         │ ┌─────────────────────────┐ │
                  │                     │                         │ │ Plex                    │ │
WAN: 0.0.0.0:80  ─┼─► acme.sh:80        │                         │ │                         │ │
                  │                     │                         │ │   192.168.178.102       │ │
                  │                     │                         │ │                         │ │
WAN: 0.0.0.0:443 ─┼─► HAProxy:443 ──────┼─ 192.168.178.102:32400 ─┼─┼─► plexmediaserver       │ │
                  │                     │                         │ │       ▲                 │ │                    
                  │                     │                         │ │       │                 │ │
                  │                     │     LAN: 0.0.0.0:32400 ─┼─┼───────┘                 │ │
                  │                     │                         │ └─────────────────────────┘ │
                  └─────────────────────┘                         └─────────────────────────────┘

Plex

Konfigration anpassen

Damit Plex auch mit den externen Adressen und dem richtigen Port arbeitet, sind ein paar Anpassungen in der Plex Webseite nötig. Dazu wird http://PLEXHOSTNAME:32400/web , wie bereits im 1. Teil eingerichtet, aufgerufen.

  • Unter "Einstellungen - PLEXHOSTNAME" gibt es den Menüpunkt "Fernzugriff". Dort aktivieren wir erstmal die "Erweiterten Optionen", damit alle Optionen sichtbar werden. Dann wird der Punkt "Fernzugriff" aktiviert und bei "Öffentlichen Port manuell definieren" wird der Port 443 eingetragen.
  • Unter "Einstellungen - PLEXHOSTNAME" gibt es weiter den Menüpunkt "Netzwerk" mit der Option "Eigene URLs für den Zugriff auf diesen Server". Dort tragen wir unseren EXTERNERHOSTNAME ein (z.B. https://plex.domain.de:443 ). "Aktiviere Relay" darüber wird deaktiviert.

Lets Encrypt Zertifikate

OPNsense ist mit dem ACME Client Plugin (os-acme-client) in der Lage Let's Encrypt Zertifikate zu erstellen und auch automatisch zu erneuern. Der Riesenvorteil ist, das wir eine zentrale Zertifikatsverwaltung haben, nicht mühselig auf den internen Zielsystemen jeweils eine eigene Verwaltung benötigen und keine NAT oder anderen Firewall Einstellungen vornehmen müssen.

Services: ACME Client

Settings

Um ein Zertifikat für die eigene Domain zu erhalten sind nur wenige Schritte unter "Services - ACME Client" notwendig. Hierfür wechseln wir in den Bereich "Services / ACME Client / Settings" der OPNsense und setzen folgende Haken:

Enable Plugin: JA  
Auto Renewal: JA  

Hierdurch wird das Plugin aktiviert und die automatische Erneuerung der Zertifikate festgelegt.

Screenshot%202022-10-30%20123726

Accounts:

Danach wechseln wir in den Bereich "Services / ACME Client / Accounts" und erstellen mit dem "+"-Zeichen einen neuen Account.

Enabled: JA  
Name: ACCOUNTNAME  
E-Mail Address: EMAILADRRESSE  
ACME CA: Let's Encrypt [default]  

Der Account muss einmalig registriert werden. Ganz rechts gibt es dazu den Knopf "Register Account". Bei Erfolg wird der Account dann bei Status mit "OK (registered)" gekennzeichnet.

Screenshot%202022-10-30%20131719

Challenge Types

Im Anschluss legen wir fest, wie die Überprüfung (Challenge) stattfinden soll. Dies geschieht im Bereich "Services / ACME Client / Challenge Types". Auch hier erzeugen wir durch Betätigung des "+"-Zeichens eine neue Challenge mit den folgenden Einstellungen:

Enabled: JA  
Name: PLEXHOSTNAME  
Challenge Type: HTTP-01  
HTTP Service: OPNsense Web Service (automatic port forward)  
Interface: WAN  

Automations

Unter "Services / ACME Client / Automations" wird ein neuer Eintrag erstellt.

Name: Restart HAProxy
Run Command: Restart HAProxy

Certificates

Im letzten Schritt geht es an die Erstellung des Zertifikates. Hierfür wechseln wir nach "Services / ACME Client / Certificates" und erstellen erneut einen neuen Eintrag durch das "+"-Zeichen. Im Feld "ACME Account" wählen wir den soeben erstellen Account aus, in dem Feld "Challange Type" die erstellte Challange. Die übrigen Einstellungen wählen wir wie folgt:

Enabled: JA  
Common Name: EXTERNERHOSTNAME  
ACME Account: ACCOUNTNAME (aus Accounts)  
Challenge Type: PLEXHOSTNAME (aus Challenge Types)  
Key Length: ec-384  
Automations: Restart HAProxy  

Damit sind alle Einstellungen vorgenommen und das Zertifikat kann ganz rechts mit dem Knopf "Issue or renew certificate" erstellt werden. Bei Erfolg (das dauert ein paar Minuten) wird das Zertifikat bei "Last ACME Status" mit "OK" gekennzeichnet.

Screenshot%202022-10-30%20132151

Fertig! Die Erneuerung des Zertifikates erfolgt nun gemäß den Einstellungen alle 90 Tage vollautomatisch.

HAProxy

HAProxy nimmt von außen die Aufrufe für den Port 443 entgegen, verschlüsselt die Verbindung und leitet diese dann an den internen Plex Server auf Port 32400 weiter. Das schöne ist, das auch hier die Verwaltung wieder zentral stattfindet, die Zertifikate ohne Aufwand von Let's Encrypt genutzt und mehrere Dienste gleichzeitig auf Port 443 bereitgestellt werden können. Unterschieden wird über den aufgerufenen externen Hostnamen. Damit ist es möglich das z.B https://plex.domain.de an Plex und https://domain.de zur eigentlichen Webseite geleitet wird, obwohl beide eigentlich Port 443 auf der gleiche externen IP Adresse benötigen.
Hier in dem Fall wird kein NAT oder freigegeben Port 32400 benötigt. Je weniger offene Ports auf der Firewall existieren, desto geringer ist die Angriffsfläche.

Aufgabenstellung des HAProxy ist hier:

  • Externen Zugriff erlauben für die URL https://EXTERNERHOSTNAME
  • HTTPS härten und unanfälliger für schwache Verschlüsselungen machen

Der Prozess ist: Public Service (EXTERNERHOSTNAME:443) ─► Condition ─► Rule ─► Pool ─► PLEXHOSTNAME:3000

Um nun eine Weiterleitung der EXTERNERHOSTNAME auf den interen Vaultwarden zu erhalten, sind nur wenige Schritte unter "Services - HAProxy" notwendig: Im ersten Schritt definieren wir unter "Services / HAProxy / Settings" in der Lasche "Real Servers" einen Server. Dies geschieht wieder jeweils durch Betätigung der "+"-Schaltfläche.

Services: HAProxy

Settings

Enable HAProxy: YES

Screenshot%202022-10-30%20134041

Real Servers:

Beginnen wir mit dem "Plex", dieser erhält die folgenden Einträge:

Name: server_HOSTNAME  
Description: IP Adresse des lokalen Vaultwarden Servers  
Type: static  
FQDN or IP: PLEXIP  
Port: 32400  

Virtual Services: Backend Pools

Im zweiten Schritt erstellen wir die "Backend Pools", dies erledigen wir unter "Services / HAProxy / Settings" in der Lasche "Virtual Services" den Eintrag "Backend Pools".

Name: pool_HOSTNAME  
Description: Pool an lokalen Plex Server (hier gibts nur einen)  
Servers: server_HOSTNAME  

Rules & Checks: Conditions

Nun hinterlegen wir das Regelwerk, welche bestimmen, welche eingehenden Verbindungen an welchen Service weitergeleitet werden. Hierfür wählen wir unter "Services / HAProxy / Settings" in der Lasche "Rules & Checks" den Eintrag "Conditions" aus und erstellen zwei Bedingungen:

Name: plex host check  
Description: Prüfung ob der **EXTERNERHOSTNAME** aufgerufen wurde  
Condition type: Host matches  
Path Regex: EXTERNERHOSTNAME  

Rules & Checks: Rules

Diese Bedingungen werden durch eine Regel überprüft. Regeln erzeugen wir wie folgt unter "Services / HAProxy / Settings" in der Lasche "Rules & Checks" im Eintrag "Rules" durch die Schaltfläche "+":

Name: plex host rule  
Description: Externen Zugriff auf **EXTERNERHOSTNAME** an den richten Server (im Pool) weiterleiten  
Select conditions: plex host check  
Execute function: Use specified Backend Pool  
Use backend pool: pool_HOSTNAME  

Virtual Services: Public Services

Abschließend erstellen wir einen "Public Services" unter "Services / HAProxy / Settings" in der Lasche "Virtual Services" den Eintrag "Public Services"

Name: service_https  
Description: Server auf Port 443 der alle externen Anfragen entgegennimmt  
Listen Addresses: 0.0.0.0:443
Default Backend Pool: none  
Certificates: EXTERNERHOSTNAME (ACME Client)  
Default certificate: EXTERNERHOSTNAME (ACME Client)  
Cipher List: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384  
Cipher Suites: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256  
Enable HSTS: YES  
HSTS includeSubDomains: YES  
Select Rules: plex host rule  

Mit "Apply" wird die Konfiguration geschrieben und der HAProxy Dienst gestartet.

Bitte daran denken den Port 443 in der Firewall zu erlauben.

Damit ist nun von außen der Zugriff auf den Plex Media Server eingerichtet und erlaubt.

Plex Public

Bitte folgendes Testen:

  • Der externe Aufruf https://EXTERNERHOSTNAME/web öffnet die Plex Anmeldemaske - OK!
  • Der externe Aufruf https://app.plex.tv/desktop/#!/ öffnet die Plex Anmeldemaske und kann auf die Inhalte zugreifen - OK!
  • Der interne Aufruf https://EXTERNERHOSTNAME/web öffnet die Plex Anmeldemaske - OK!
  • Der interne Aufruf http://PLEXHOSTNAME:34200/web öffnet die Plex Anmeldemaske - OK!

Voilá