Privates Netzwerk in der Hetzner Cloud

Lesezeit: 20 Minuten

Schon seit einem knappen Jahr nutze ich die Hetzner Cloud mit ihren Networks um dort einen essenziellen Teil meines Netzwerks zu betreiben, den ich davor lokal in Form physischer Maschinen betrieben habe. Es laufen dort mehrere Server (Linux und Windows), die über einen CHR von Mikrotik, einen virtuellen Router, mit dem Internet verbunden sind. Dieser agiert als Firewall und VPN-Gateway und läuft selbst wiederum auf einem Cloud Server.

In diesem Beitrag möchte ich die Grundzüge der Erstellung eines solchen Setups erklären.

Außerdem werde ich auf die Vor- und Nachteile gegenüber physischer Hardware eingehen und die jeweiligen Kosten vergleichen.

Inhalt

Projekt erstellen

Ein Projekt kann Server und Netzwerke beinhalten und ist von anderen Projekten vollständig getrennt. Außerdem können Projekten mehrere Nutzer zugeordnet werden. Zu Beginn erstelle ich in der Cloud Console, der Web-Management-Oberfläche, das ProjektBlog“ nachdem dieses Setup ausschließlich der Erstellung dieses Blogbeitrags dienen soll.

Netzwerk erstellen

Ich erstelle das Netzwerk 10.42.0.0/24 und nenne es network-blog. Leider unterstützen die Hetzner Cloud Networks bis dato nur IPv4, daher gehe ich in diesem Beitrag nicht auf IPv6 ein. Die Cloud Server selbst bekommen aber selbstverständlich eine öffentliche IPv4-Adresse und ein /64 IPv6-Präfix.

Dieses neu erstellte Netzwerk hat automatisch ein Gateway bekommen. Diesem wird immer die erste verwendbare IPv4-Adresse des Netzwerks zugewiesen, in diesem Fall 10.42.0.1. Leider habe ich das durch Versuche herausfinden müssen, nachdem es nur sehr wenig Dokumentation darüber gibt. Das zu wissen, ist für dieses Vorhaben jedoch unerlässlich!

Subnetz erstellen

Ein Netzwerk kann mehrere Subnetze beinhalten, es hat automatisch ein /28-Subnetz bekommen. Dieses lösche ich und erstelle stattdessen, der Einfachhheit halber, ein einziges /24:

Virtuellen Router erstellen

Cloud Server erstellen

Beim Erstellen eines Cloud Servers hat man folgende Optionen.

  1. Standort (ich wähle Helsinki)
  2. Image (ist irrelevant, weil ich das OS anschließend überschreibe)
  3. Typ (ich wähle CX11 (1vCPU, 2GB RAM, 20GB SSD))
  4. Volume (brauche ich nicht)
  5. Netzwerk (hier wähle ich das zuvor erstellte network-blog aus)
  6. Zusätzliche Features (ich aktiviere die Backups)
  7. SSH-Key (ist irrelevant, weil ich das OS anschließend überschreibe)
  8. Name (ich nenne den Server „chr„)

Mikrotik CHR installieren

CHR steht für Cloud Hosted Router und ist im Prinzip Mikrotik RouterOS für x86-Architekturen. Um das Image herunterladen zu können, muss man den Server im RESCUE-Modus booten. Ich klicke dazu auf RESCUE AKTIVIEREN & RESET und wähle linux64 als Rescue OS:

Jetzt werden Zugangsdaten angezeigt. Ich benutze SSH und verbinde mich mit der öffentliche IPv4-Adresse des Servers:

Mit folgendem Befehl lade ich das CHR-Image herunter, entpacke es und überschreibe die Festplatte damit. Ich suche die aktuelle Versionsnummer unter https://mikrotik.com/download. In meinem Fall ist das 6.46.6.

curl -L https://download.mikrotik.com/routeros/6.46.6/chr-6.46.6.img.zip
funzip chr-6.46.6.img.zip
dd if=chr-6.46.6.img of=/dev/sda bs=1M

Jetzt ist das Image auf der SSD und beim nächsten Start sollte der Server davon booten. Aber:

!!! ACHTUNG !!!

Sobald das passiert, ist der Router öffentlich erreichbar und man kann sich mit dem Standardbenutzer admin und ohne Passwort anmelden. Daher treffe ich Vorbereitungen, um mich so schnell wie möglich einloggen und das Passwort ändern zu können. Ich öffne dazu WinBox und trage die öffentliche IPv4-Adresse, den Login admin und kein Passwort ein. Außerdem bereite ich ein sicheres Passwort vor, sodass ich es dann schnell kopieren kann. Ich nehme zu Demonstrationszwecken hXktUEu4teJVsvPTLNqd.

Nachtrag

Hetzner bietet inzwischen das Feature Firewalls an. Damit kann man vor dem Neustart die erlaubten Quell-IP-Adressen auf die eigene(n) einschränken und sich den Stress ersparen.

Vielen Dank für diesen Hinweis an Leser Mathias.

Mikrotik CHR konfigurieren

Passwort ändern

Ich starte den Server jetzt neu und versuche mich sofort danach mittels WinBox zu verbinden.

reboot

In WinBox klicke ich auf System –> Users –> Rechtsklick auf admin –> Password –> neues Passwort eingeben –> OK

Jetzt kann man wieder etwas durchatmen. Dass hier wirklich jede Sekunde zählt, zeigt ein Blick in das Log. Bereits 19 Sekunden, nachdem der Router eine IPv4-Adresse bekommen hatte, wurde der erste Loginversuch unternommen. Das liegt primär daran, dass die Adressbereiche von großen Hostern wie Hetzner permanent nach ungesicherten Systemen abgescannt werden.

Wer das Passwort per SSH statt per WinBox ändern will, kann folgenden Befehl verwenden.

user set admin password=hXktUEu4teJVsvPTLNqd

Minimalkonfiguration

Die IP-Adressen in Hetzner Cloud Networks werden immer per DHCP zugewiesen. In dem hier beschriebenen Fall bekommt der erste Server, den man in ein Netzwerk einhängt, 10.42.0.2, der zweite 10.42.0.3, der dritte 10.42.0.4 usw.. Falls man die Adressen manuell auswählen möchte, kann man das in der Cloud Console laut dieser Anleitung machen. Es funktioniert NICHT, einfach im Betriebssystem eine Adresse zu vergeben!

Der Router sollte jetzt zwei Interfaces haben: ether1 ist das WAN-Interface mit öffentlicher IPv4-Adresse, ether2 ist das LAN-Interface, das mit dem virtuellen Netzwerk network-blog verbunden ist. Ich aktiviere für letzteres den DHCP-Client (IP –> DHCP Client) und bekomme umgehend die Adresse 10.42.0.2 zugewiesen. Dann benenne ich die beiden Interfaces noch sinngemäß um:

Da die Cloud Networks derzeit nur das ehemalige IPv4 mit privaten Adressen unterstützen, muss ich für die Funktion dieses Setups zumindest NAT konfigurieren. Ich nutze dazu folgenden Befehl, in der WinBox funktioniert es nach demselben Prinzip.

ip firewall nat add chain=srcnat action=masquerade out-interface=ether1-wan

Jetzt wäre der Zeitpunkt für Firewall-Konfiguration und weitere Sicherheitseinstellungen gekommen. Das ist unter https://wiki.mikrotik.com/wiki/Manual:Securing_Your_Router ausführlich beschrieben, daher gehe ich hier nicht weiter darauf ein.

An dieser Stelle würde ich auch eventuelle VPN-Tunnel konfigurieren, um den Router mit anderen Geräten oder Standorten zu verbinden, das hängt aber stark von den jeweiligen Gegebenheiten ab, weshalb ich nicht weiter darauf eingehen möchte.

Tipp: Falls man sich während der Konfiguration aussperrt, kann man sich immer noch über die Web-Konsole (Schaltfläche >_ ) auf dem Router einloggen:

Lizenz

Der CHR läuft jetzt mit einer kostenlosen Lizenz. Diese erlaubt einen maximalen Datendurchsatz von 1Mbit/s pro Interface. Sonst gibt es keine Einschränkungen. Wer mehr will, kann für kleines Geld eine Lizenz kaufen (z.B. 1Gbit/s pro Interface für einmalig 45$): https://wiki.mikrotik.com/wiki/Manual:CHR#CHR_Licensing. Im Zuge einer MTCNA-Zertifizierung bekommt man eine solche Lizenz übrigens kostenlos.

Route erstellen

Bevor ich die eigentlichen Server erstelle, füge ich dem Cloud Network network-blog noch eine Route hinzu. Diese sorgt dafür, dass sämtlicher Traffic, der das Gateway (10.42.0.1) erreicht, an den gerade erstellten Router (10.42.0.2) weitergeleitet wird.

Das Netzwerk und der Router sind soweit einsatzbereit, jetzt erstelle ich die Server.

Server 1 (Windows)

Als erstes möchte ich einen Windows-Server erstellen, nachdem es einerseits auch Software geben soll, die nicht unter vernünftigen Betriebssystemen läuft und andererseits Windows auch die komplexeste Installation in diesem Beitrag ist.

Cloud Server erstellen

Beim Erstellen des Servers wähle ich folgendes.

  1. Standort (ich wähle Helsinki)
  2. Image (ist irrelevant, weil ich das OS anschließend überschreibe)
  3. Typ (ich wähle CPX31 (4vCPU, 8GB RAM, 40GB SSD))
  4. Volume (ich nehme 30GB dazu)
  5. Netzwerk (hier wähle ich das zuvor erstellte network-blog aus)
  6. Zusätzliche Features (ich aktiviere nichts, kann man auch nachträglich machen)
  7. SSH-Key (ist irrelevant, weil ich das OS anschließend überschreibe)
  8. Name (ich nenne den Server srv1-win)

Nach der Erstellung binde ich das Installationsimage für Windows Server 2019 German ein:

Danach fahre ich den Server mit den Schaltflächen unter dem Punkt POWER herunter und starte ihn anschließend neu. Dann öffne ich die Web-Konsole, aktiviere GUI-Modus und beginne eine ganz normale Windows-Installation. Bei der Betriebssystem-Auswahl sollte man darauf achten, dass man die Variante mit Desktopdarstellung wählt, falls man eine GUI haben will:

Bei der Installationsart wähle ich Benutzerdefiniert und komme zu folgendem Bildschirm.

An dieser Stelle muss man in die Cloud Console wechseln und das Image virtio-win-0.1.171 einbinden:

Dann klickt man in der Windows-Installation auf Treiber laden –> Durchsuchen –> CD-Laufwerk (D:) virtio-win-0.1.1 –> vioscsi –> 2k19 –> amd64 und installiert diesen Treiber mit Weiter. Danach sollten Laufwerke angezeigt werden.

Jetzt binde ich in der Cloud Console wieder das zuvor verwendete Windows-Image ein.

In der Windows-Installation lösche ich alle Partitionen der SSD und installiere Windows wie üblich. Nachdem die Installation beendet ist, entferne ich das Image wieder. Windows sollte dann normal starten.

Windows konfigurieren

Nachdem Windows gestartet ist, erkennt es noch keine Netzwerkkarten. Ich binde das VirtIO-Image daher wieder ein und lasse den Geräte-Manager dort nach passenden Treibern für alle nicht erkannten Geräte suchen, was auch gelingt.

Es sollten jetzt zwei Netzwerkadapter aktiv sein. Einer mit direkter Internetanbindung, einer mit Anbindung an das virtuelle Netzwerk network-blog, welcher die IPv4-Adresse 10.42.0.2 bekommen hat. Ersteren deaktiviere ich in der GUI, nachdem ja der gesamte Verkehr über meinen CHR laufen soll.

Jetzt muss noch eine neue Default-Route zu dem CHR erstellt werden. Dazu lasse ich mir zuerst die Nummern der Interfaces anzeigen:

route print

Ich suche nach dem Red Hat VirtIO Ethernet Adapter #2, hier ist daher die Nr. 6 interessant. Diese brauche ich, um mit folgendem Befehl die Default-Route zu erstellen.

route add -p 10.42.0.1 0.0.0.0 if 6
route add -p 10.42.0.0 mask 255.255.255.0 10.42.0.1 if 6

Dieser Vorgang wird hier genauer beschrieben.

Damit die Namensauflösung klappt, trage ich noch einen öffentlichen DNS-Server ein (z.B. 9.9.9.9). Dann teste ich die Erreichbarkeit des CHR und prüfe, dass auch der Internetzugriff über diesen läuft:

Server 2 (Ubuntu)

Cloud Server erstellen

Beim Erstellen des Servers wähle ich folgendes.

  1. Standort (ich wähle Helsinki)
  2. Image (Ubuntu 20.04)
  3. Typ (ich wähle CPX11 (2vCPU, 2GB RAM, 40GB SSD))
  4. Volume (brauche ich nicht)
  5. Netzwerk (hier wähle ich das zuvor erstellte network-blog aus)
  6. Zusätzliche Features (ich aktiviere Backups)
  7. SSH-Key (benutze ich nicht, da ich mich eventuell per Konsole verbinden will)
  8. Name (ich nenne den Server srv2-ubuntu)

Ubuntu konfigurieren

Ich möchte, dass auch dieser neue Server nicht öffentlich, sondern nur aus meinem internen Netz erreichbar ist und dass er meinen virtuellen Mikrotik-Router als Gateway zum Internet verwendet. Damit ich mich nicht aussperre, benutze ich nicht SSH sondern die Web-Konsole, um mich zu verbinden.

Zuerst lasse ich mir die Interfaces anzeigen:

ip a

eth0 ist das Interface mit direktem Internetzugang, enp7s0 ist das Interface, das mit meinem Netzwerk network-blog verbunden ist. Ich benutze netplan um eth0 zu deaktivieren und um enp7s0 so zu konfigurieren, damit sämtlicher Verkehr über meinen virtuellen Router geht. Davor benenne ich die Datei noch sinngemäß um:

mv /etc/netplan/50-cloud-init.yaml /etc/netplan/my-network-conf.yaml
nano /etc/netplan/my-network-conf.yaml

Die Datei sollte danach folgenden Inhalt haben, anschließend wende ich die Konfiguration an und starte den Server neu.

network:
    version: 2
    ethernets:
        enp7s0:
            dhcp4: true
            nameservers:
              addresses: [9.9.9.9]
            routes:
              - to: 0.0.0.0/0
                via: 10.42.0.1
                on-link: true
netplan apply
reboot

netplan ist sehr empfindlich auf falsche Einrückung. Es dürfen beispielsweise keine Tabs verwendet werden, sondern nur Leerzeichen und deren Anzahl muss auch stimmen.
Sollten an dieser Stelle Fehler auftreten, liegt es wahrscheinlich an der Web-Konsole bzw. an einem falschen Tastaturlayout. Man könnte das zwar richtigstellen, nachdem aber der Server zu diesem Zeitpunkt noch öffentlich erreichbar ist, steige ich einfach kurz auf SSH um, um die Datei dort bearbeiten.

Jetzt sollte auch hier das Interface eth0 down sein, der Windows-Server sollte erreichbar sein und das Internet müsste über den CHR erreichbar sein:

ip a
ping 10.42.0.2
mtr google.com

Server 3 (Debian)

Cloud Server erstellen

Beim Erstellen des Servers wähle ich folgendes.

  1. Standort (ich wähle Helsinki)
  2. Image (Debian 10)
  3. Typ (ich wähle CPX11 (2vCPU, 2GB RAM, 40GB SSD))
  4. Volume (brauche ich nicht)
  5. Netzwerk (hier wähle ich das zuvor erstellte network-blog aus)
  6. Zusätzliche Features (ich aktiviere nichts, da man das auch nachträglich machen kann)
  7. SSH-Key (benutze ich nicht, da ich mich eventuell per Konsole verbinden will)
  8. Name (ich nenne den Server srv3-debian)

Debian konfigurieren

Wie schon bei den beiden anderen Servern möchte ich das öffentliche Interface deaktivieren und eine neue Default-Route konfigurieren. Mit ip a finde ich heraus, dass das private Interface wieder enp7s0 heißt. Die Netzwerkkonfiguration erfolgt bei Debian, wie bei Linux üblich, über die Datei /etc/network/interfaces:

nano /etc/network/interfaces

Die Datei bearbeite ich wie folgt.

# interfaces(5) file used by ifup(8) and ifdown(8)

#  loopback network interface
auto lo
iface lo inet loopback

# private network interface "network-blog"
auto enp7s0
iface enp7s0 inet dhcp
        post-up ip route add default via 10.42.0.1 dev enp7s0
        post-down ip route delete default via 10.42.0.1 dev enp7s0
        dns-nameservers 9.9.9.9

# Include files from /etc/network/interfaces.d:
# source /etc/network/interfaces.d/*.cfg

Die Zeilen nach „auto enp7s0“ habe ich hinzugefügt und die letzte Zeile mit # auskommentiert. Danach starte ich den Server neu.

reboot

Abschließend prüfe ich, dass auch diese Maschine alle anderen erreichen kann und über den CHR Internetzugriff hat.

Nachdem das funktioniert, habe ich mein primäres Ziel erreicht und mir steht ein privates Netzwerk hinter einem virtuellen Router zur Verfügung.

Kosten

Um die Kosten dieses cloudbasierten Setups mit denen physischer Rechner vergleichen zu können, mus man letzteres genauer definieren.

Ein physisches Setup könnte einerseits aus einem physischen Router und mehreren physischen Computern bestehen. Andererseits könnte man sich auch eine einzige physische Hostmaschine bauen, einen Hypervisor aufsetzen und darauf die VMs laufen lassen.

Ich gehe hier aber von einem Referenzsystem aus, wie ich es tatsächlich betrieben habe, bevor ich die Hetzner Cloud entdeckte:

  • 1x Router: Mikrotik RB3011
  • 1x Windows-Server: Ryzen 3 3100, 8GB, 360GB SSD
  • 2x Raspberry Pi

Folgend eine grobe Zusammenstellung der Kosten über zwei Jahre in € (Stromkosten werden mit 0,30€/kWh angenommen):

Kosten des physischen Setups

Und hier die Kosten des in diesem Beitrag beschriebenen Setups über zwei Jahre in €:

Kosten des Cloud-Setups

Bei der Hetzner Cloud werden die Server stundenweise abgerechnet. Der bei der Erstellung angezeigte Preis bezieht sich auf ein Monat. Erstellt man einen Server also nur zu Testzwecken für ein paar Stunden, so kostet das meist nur Centbeträge.

Außerdem stehen als Zusatzfunktionen Volumes, Backups und Snapshots zur Verfügung. Backups zu aktivieren kostet beispielsweise 20% des Serverpreises und beinhaltet 7 Backups, die täglich automatisch erstellt werden und auch manuell gestartet werden können.

Am Ende des Beitrags steht mein Empfehlungslink, über den du 20€ Guthaben für die Hetzner Cloud bekommst.

Auf den ersten Blick ist das Cloud-Setup bereits günstiger, wobei die Hardware üblicherweise nicht schon nach zwei Jahren ersetzt werden muss, womit die Kosten insgesamt sehr ähnlich ausfallen dürften.

Würde man jedoch die Kosten für eine Internetanbindung, die der der Hetzner Cloud entspricht in die Berechnung miteinbeziehen, wäre die konventionelle Lösung schon deutlich teurer.

Bedenkt man auch noch die nicht existenten Backupstrategien, den Wartungsaufwand, die thermische Last und nicht zuletzt die Geräuschentwicklung physischer Computer, so beginnen die Vorteile dieser weiter dahinzuschmelzen. Ganz besonders deutlich würde das bei Betriebsdauern jenseits von zwei Jahren, wenn ein Tausch von Lüftern, SSDs oder Speicherkarten anstehen würde.

Die entscheidenden Kriterien für die Entscheidung, auf Cloud-Systeme zu setzen waren in meinem Fall aber diese:

  1. Die Flexibilität, Server an- und auszuknipsen oder größer bzw. kleiner zu machen, wie ich es gerade für nützlich halte.
  2. Snapshots erstellen zu können und vertrauenswürdige Backups zur Verfügung zu haben, wann auch immer ich welche benötige.
  3. Die Internetanbindung der Hetzner Cloud. An meinem üblichen Aufenthaltsort bekomme ich von Magenta 500/50 Mbit/s für ca. 50€/Monat. Bei Hetzner ist die Lizenz meines CHR mit 1Gbit/s (synchron!) das Limit. Von Peering will ich gar nicht erst reden.

Am Ende ist es ein ganzer Haufen Peace of Mind, der mich zu einem sehr zufriedenen Cloud-User macht.


Wenn du Feedback loswerden möchtest, nutze bitte das Kontaktformular.

Falls dir mein Beitrag weitergeholfen hat, würde ich mich sehr über einen kleinen Kaffee freuen. Oder du nutzt einen meiner Empfehlungslinks und sparst dir damit etwas Geld: Tesla (500€ Rabatt), Hetzner Cloud (20€ Guthaben), Ufodrive (30€ Rabatt). Außerdem habe ich eine Wunschliste bei Amazon.


4 Replies to “Privates Netzwerk in der Hetzner Cloud”

Comments are closed.