Cloudflare Tunnels selbst hosten? So geht's mit Pangolin!

Cloudflare Tunnels selbst hosten? So geht's mit Pangolin!

Übersicht

In dem heutigen Beitrag geht es um das Tool Pangolin. Pangolin gibt uns einen super einfach zu verwendenden Reverse-Proxy, mit dem wir sämtliche Services aus unserem Homelab von außerhalb erreichbar machen können, selbst wenn wir in einem CGNAT gefangen sind oder allgemein kein Port-Forwarding betreiben können.

Das Tool ermöglicht uns einfach gesagt, das selbstständige Hosten der Funktionen, die uns Cloudflare Tunnels bietet. Denn es hat sich davon inspirieren lassen und wir sehen hier und da gewisse Ähnlichkeiten. Davon abgesehen ist die Hauptfunktion mindestens genauso einfach zu bedienen wie Cloudflare Tunnels selbst, nur eben mit dem großen Vorteil, dass wir alles komplett selbst hosten können und unsere Daten und Traffic niemals fremde Netzwerke und Server durchqueren, wie es bei Cloudflare der Fall wäre.

Daher bietet das Tool eine großartige Möglichkeit für alle, die sich nicht so sehr mit dem Routing und Co. auseinandersetzen wollen wie beispielsweise mit Netbird, aber trotzdem eine selbst gehostete Möglichkeit haben möchten, ihre Services von außen erreichbar zu machen.

Das Video zum Beitrag findet ihr hier: https://youtu.be/sXuUODTQekI


Anforderungen

Server

Um Pangolin zu betreiben, brauchen wir einen Server mit fester IP-Adresse. Das lässt sich am einfachsten und günstigsten mit einem VPS realisieren.

Meine Empfehlung sind nach wie vor die super günstigen Server von Netcup. Für Pangolin benötigen wir nur sehr sehr wenige Ressourcen, was bedeutet, wir können auf einen VPS piko G11s zurückgreifen, der uns gerade mal 1€ im Monat kostet!

Solltet ihr euch für einen Server bei Netcup entscheiden, habe ich für alle Neukunden einen 5€ Gutschein. Mit Verwendung des Gutscheins habt ihr einen kleinen Rabatt und unterstützt mich gleichzeitig dabei, weitere solcher Beiträge zu ermöglichen. Den Gutschein könnt ihr einfach im Bestellprozess angeben, anschließend werden euch automatisch 5€ von der ersten Rechnung abgezogen.

  • 5€ Gutschein-Code: 36nc17222595270
  • Günstige VPS Server bei Netcup hier *

Es handelt sich hierbei um einen Affiliate-Link

DNS

Wenn ihr euren Server und die zugehörige IP habt, müsst ihr noch entsprechende DNS-Einträge für eure gewünschte Domain vornehmen. Da wir mit Pangolin später Subdomains erstellen können, wie wir wollen, müssen wir die komplette Domain auf den Server zeigen lassen. Je nach Provider kann das folgendermaßen aussehen:

Host Typ Ziel Hinweis
* A <IP-vom-Server> Das * spricht alle Subdomains an, also *.example.de
@ A <IP-vom-Server> Das @ spricht die Base-Domain an, also example.de

Installation

Absicherung des Servers

Da der Server am Ende natürlich von außerhalb erreichbar ist, solltet ihr vor allem den SSH-Zugang entsprechend gegen Angreifer absichern. Einen Beitrag zu Fail2Ban, 2Faktor und SSH-Einstellungen findet ihr hier.

Pangolin Installations-Script

Natürlich könnten wir uns jetzt durch die ganze Dokumentation von Pangolin kämpfen und die Docker-Container von Hand einrichten, aber warum schwer, wenn es auch einfach geht?

Pangolin bietet uns ein automatisiertes Installations-Script, das die Installation mindestens genauso kinderleicht macht wie die Verwendung des Tools.

Alles, was wir also für die initiale Installation machen müssen, ist:

  1. Zum Pfad navigieren, in dem wir Pangolin installieren wollen (Beispiel: /opt/pangolin).
  2. Herunterladen des Scripts
wget -O installer "https://github.com/fosrl/pangolin/releases/download/1.0.1/installer_linux_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')" && chmod +x ./installer
  1. Ausführen des Scripts
sudo ./installer

Nun durchlaufen wir einfach das "Setup" und tragen unsere gewünschte Domain ein. Die meisten Einstellungen können wir direkt auf dem Standard belassen.

=== Basic Configuration ===
Enter your base domain (no subdomain e.g. example.com): juseclab.de
Enter the domain for the Pangolin dashboard (default: pangolin.juseclab.de):
Enter email for Let's Encrypt certificates: acme@juseclab.de
Do you want to use Gerbil to allow tunned connections (yes/no) (default: yes):

=== Admin User Configuration ===
Enter admin user email (default: admin@juseclab.de):
Create admin user password:
Confirm admin user password:

=== Security Settings ===
Disable signup without invite (yes/no) (default: yes):
Disable users from creating organizations (yes/no) (default: no):

=== Email Configuration ===
Enable email functionality (yes/no) (default: no):
Docker is not installed. Would you like to install it? (yes/no) (default: yes):

=== Starting installation ===
Would you like to install and start the containers? (yes/no) (default: yes):
Starting containers...
Using 'docker compose' command to pull containers...

=== Crowdsec Install ===
Would you like to install Crowdsec? (yes/no) (default: yes):
Stopping containers...

Installation complete!

Erster Login

Und das war auch schon die Installation! Jetzt finden wir das Pangolin-Dashboard auf der entsprechenden Domain. Dort können wir uns nun mit unserem erstellten Admin-Account anmelden.

Als nächstes nehmen wir die initiale Einrichtung vor, indem wir eine Organisation erstellen.

Wir haben nun die Möglichkeit, direkt eine neue Site hinzuzufügen. Dazu kommen wir aber gleich, daher überspringe ich das vorerst.


Aufbau

Da sich Pangolin noch in der Beta befindet, ist das Tool insgesamt recht überschaubar, aber dafür umso simpler zu nutzen und zu bedienen.

Sites

Sites sind quasi die Geräte in unserem Homelab, die wir mit dem Newt Agent bestücken, um darüber dann auf unsere Services im Homelab zugreifen zu können.

Es muss nicht auf jedem Server, auf dem ein Service läuft, ein Newt Agent installiert werden. Theoretisch reicht ein Agent für das gesamte Homelab, es muss nur sichergestellt sein, dass der Host mit dem Agent den entsprechenden Service erreichen kann.

Ressourcen

Unter dem Reiter Ressourcen passiert die eigentliche Magie. Hier haben wir die Möglichkeit, eine neue Ressource aus unserem Homelab anzulegen und mit einer Subdomain zu versehen. Außerdem können wir konfigurieren, ob die Seite einfach so erreichbar ist oder ob sich authentifiziert werden muss. Mehr dazu aber gleich.

Benutzer & Rollen

Unter diesem Reiter können weitere Benutzer angelegt werden, falls eure Freunde oder Bekannte ebenfalls Zugriff erhalten sollen.

Unter Shareable Links könnt ihr, wie der Name vermuten lässt, Links zu euren Services generieren. Dabei könnt ihr eine Gültigkeitsdauer festlegen, und in dieser Zeit kann mit diesen Links die geforderte Authentifizierung von Pangolin umgangen werden.

General

General beinhaltet die Einstellungen, hier gibt es nicht wirklich viel zu sehen.


Newt Agent

Um nun unseren ersten Service aus unserem Homelab erreichbar zu machen, brauchen wir erstmal einen Host in unserem Homelab, der den Newt Agent bekommt. Darüber kommuniziert Pangolin dann mit unserem Homelab, um die Services entsprechend erreichbar zu machen, ganz ohne Port-Forwarding.

Newt installieren

Wenn wir auf dem Dashboard den Button "Install Newt" klicken, gelangen wir zur Dokumentation zu Newt. Hier wird die Installation für verschiedene Betriebssysteme und auch Docker erklärt. Ich verwende hier als Beispiel die Variante für Linux.

Alles, was wir machen müssen, ist den Befehl auf unserem Host auszuführen, um Newt herunterzuladen.

wget -O newt "https://github.com/fosrl/newt/releases/download/1.1.1/newt_linux_amd64" && chmod +x ./newt

Falls Newt dauerhaft laufen soll, können wir das Tool auch permanent "installieren", indem wir es zu unserem PATH hinzufügen und später einen Service damit installieren.

mv ./newt /usr/local/bin/newt

Damit ist Newt auch schon installiert und einsatzbereit.


Beispiel Service

Verwenden wir nun also Pangolin, um einen simplen HTTP-Webserver in Docker, der in meinem Homelab auf einem Host läuft, von außen erreichbar zu machen.

Site hinzufügen

In Pangolin auf dem Reiter Site fügen wir jetzt mit Add Site eine neue Site hinzu. Dafür vergeben wir einen Namen und kopieren dann die Konfiguration.

Nun führen wir den kopierten Befehl auf unserem Server, auf dem Newt installiert ist, aus.

Ein Blick in das Dashboard zeigt unseren Host nun als Online an.

Newt als Service

Nach aktuellem Stand läuft Newt nur solange, bis wir die Terminal Session schließen. Wir möchten aber natürlich, dass es automatisch die ganze Zeit läuft, also erstellen wir dafür einen Service auf unserem Host.

  1. Service-Datei erstellen
sudo nano /etc/systemd/system/newt.service
  1. In die Datei kommt dann unter anderem der Befehl, den wir aktuell einfach so ausgeführt haben.
[Unit]
Description=Newt VPN Client
After=network.target

[Service]
ExecStart=/usr/local/bin/newt <euer befehl ohne "newt" am anfang>
Restart=always
User=root

[Install]
WantedBy=multi-user.target
  1. systemd neustarten und Dienst starten
sudo systemctl daemon-reexec     # systemd neu starten (manchmal nötig)
sudo systemctl daemon-reload     # neue Dienste erkennen
sudo systemctl enable newt.service    # beim Booten starten
sudo systemctl start newt.service     # jetzt starten

Der Service läuft nun dauerhaft im Hintergrund.


Ressource erstellen

Unter dem Reiter Ressourcen können wir jetzt eine neue Ressource hinzufügen. Wir geben der Ressource einen Namen, wählen unsere neue Site, als Typ nehmen wir HTTPS-Ressource und vergeben nun unsere gewünschte Subdomain.

Jetzt landen wir im Connectivity-Tab der neuen Ressource, wo wir natürlich noch unsere IP und den Port hinterlegen müssen. Da der Webserver bei mir auf demselben Host wie Newt läuft, kann ich hier localhost eintragen.

Nachdem wir das Target gespeichert haben, können wir auch schon auf unseren Service zugreifen.

Authentifizierung

Per Default wird für jeden neuen Service automatisch Platform SSO als Authentifizierung ausgewählt. Ihr könnt einfach auf die Ressource zugreifen, wenn ihr im selben Browser seid, da ihr dort bereits angemeldet seid. In einem privaten Tab sieht das Ganze dann so aus.

Ihr kommt also nur mit euren Anmeldedaten auf die Seite.

Wenn ihr das nicht wollt oder eine andere Authentifizierungsmethode haben möchtet, könnt ihr das für die Ressource unter dem Reiter Authentication anpassen.