Webseite mit öffentlicher IP auf Homeserver hosten Variante #1

Webseiten im Homelab zu hosten ist das Ziel. 

Wozu das Ganze, wo liegen die Vorteile, warum nicht einfach die Homepage bei einem Provider hosten oder eine R2R-Lösung?
Einerseits ist da natürlich der technische Anspruch eine individuelle Lösung zu haben, anderseits stellt dies für mich Hobby und Weiterbildung in Einem dar. Die Funktionsweise, Konfiguration und Abhängigkeit der einzelnen Komponenten zu verstehen ist viel interessanter als ein Fertigprodukt.

Hier geht es zum ausführlichen Artikel:

Direkte Vorteile:
- Ressourcen im Homelab sind günstiger (viele VMs, Storage, RAM, Snapshots)
- einfache/schnelle Backups und Restores
- beliebig viele Snapshots
- mehr Performance/€

Nachteile:
- Verfügbarkeit (DSL, Hardware mit wenig Redundanz)
- Bandbreite
- dynamische IP - schlechtere Erreichbarkeit, DNS, Suchmaschinen-Ranking 

Dieser Artikel beschreibt eine erste Methode, um den Nachteil der dynamischen IP und DNS zu lösen. Diesen Artikel liest du quasi über diese Lösung. Die Bandbreite des DSL Anschlusses stellt heutzutage meistens kein Problem mehr dar. Meine Lösung lässt sich sogar für WLAN-Provider und LTE-Zugänge einsetzten, welche noch nicht einmal eine öffentlich erreichbare dynamische IP haben. 

Die Lösung besteht daraus bei einem Provider eine Firewall-Appliance (Mikrotik CHR) mit einer festen IP/öffentlicher DNS Verwaltung zu hosten und diese als zentralen Einwahlpunkt für den eigenen Mikrotik VPN-Router zu verwenden. Die sich daraus ergebenden Möglichkeiten sind natürlich viel umfangreicher. Den Aufbau der VPN Lösung beschreibe ich noch in einem extra Artikel ausführlicher. Eine bestehende VPN Standortvernetzung inkl. funktionierenden Routing für IP-Bereiche/Netzwerke für die jeweiligen Standorte mit Mikrotik-Komponenten wird für dieses Szenario als gegeben angenommen/vorausgesetzt. Hier geht es um das Routing und die spezielle zusätzliche Konfiguration der Mikrotiks. Die VM mit dem Webserver / Zertifikate / HTTPs / Reverseproxy etc. soll hier auch nicht weiter vertieft werden. Wichtig für mich war, dass der Webserver sowohl über das Internet als auch über seine LAN-Adresse erreichbar ist. Ich möchte ja auch via SSH zugreifen können, ohne dies über das Internet freizugeben. 
Meist behilft man sich hier mit Dyn-DNS und einem Portforwarding auf der Fritzbox. Das hatte mir zu viele Nachteile (Suchmasch.Ranking, Portforwarding, verzögerte Adressaktualisierung).

Die Mikrotik-Installation beim Cloud-Provider erfolgt dabei virtuel mit einer Mikrotik Cloud Hosted Router Installation / Appliance, folgend als Mikrotik CHR abgekürzt. Der Einfachheit beschränkt sich der gesamte Beitrag auf IP v4. 

Tipp am Rande - wenn man diese Lösung nutzt und sich nicht "us878324823xxxx.myfritz.net" z.B. für seine Nextcloud merken möchte, kann einen DNS-Record z.B. "nextcloud.meinehomepage.de" auf den "us878324823x.myfritz.net" Eintrag mappen. Dafür braucht es aber eine registrierte Domain und einen DNS-Provider der dies anbietet. 

Die untenstehende Grafik verdeutlicht den Unterschied beim Zugriff:

 

Rahmenbedingungen:

Mikrotik CHR:
- public IP: stat. DHCP vom Cloud Provider (natürlich immer die gleiche vertraglich zugesicherte IP)
- interne IP (Tunnel IP): 192.168.171.1

Mikrotik On-Premise (Homelab):
- public IP: DHCP von vorgelagerten ISP-Router (Fritzbox)
- interne IP (Tunnel IP): 192.168.171.2

Webserver On-Premise (Homelab):
- interne IP: 10.10.180.25
- Gateway/DNS: 10.10.180.1

Konfiguration der beiden Router und des lokalen Webservers:

Mikrotik CHR:

Portforwarding:

/ip firewall nat
/ip firewall nat> add chain=dstnat action=dst-nat to-addresses=10.10.180.24 to-ports=80 protocol=tcp dst-address=[publ.IP CHR] dst-port=80 log=no log-prefix="" 
/ip firewall nat> add chain=dstnat action=dst-nat to-addresses=10.10.180.24 to-ports=443 protocol=tcp dst-address=[publ.IP CHR] dst-port=443 log=no log-prefix=""

Firewall:

/ip firewall filter
/ip firewall filter> add chain=forward action=accept connection-state=established log=no log-prefix="" 
/ip firewall filter> add chain=forward action=accept connection-state=related log=no log-prefix=""
/ip firewall filter> add chain=forward action=accept protocol=tcp dst-address=10.10.180.24 dst-port=443,80 log=no log-prefix=""

 

Mikrotik On-Premise:

Portforwarding: nicht notwendig

Firewall:

/ip firewall filter
/ip firewall filter> add chain=forward action=accept connection-state=established log=no log-prefix="" 
/ip firewall filter> add chain=forward action=accept connection-state=related log=no log-prefix=""
/ip firewall filter> add chain=forward action=accept protocol=tcp dst-address=192.168.180.24 in-interface=[Name des VPN Interface] dst-port=80,443 log=no log-prefix=""

Routing:

/ip firewall address-list
/ip firewall address-list> add address=10.10.182.24 list=webserver-via-chr-routen
/ip firewall address-list> add address=10.10.0.0/16 list=lokale-netze
/ip firewall address-list> add address=192.168.5.0/24 list=lokale-netze

/ip firewall mangle
/ip firewall mangle> add chain=prerouting action=mark-routing new-routing-mark=web-over-chr passthrough=yes src-address-list=webserver-via-chr-routen dst-address-list=!lokale-netze

/ip route
/ip route> add dst-address=0.0.0.0/0 gateway=192.168.171.1 check-gateway=ping type=unicast distance=1 scope=30 target-scope=10 routing-mark=web-over-chr

Funktionsweise:

Zunächst erstellen wir Adresslisten. Eine Liste ist quasi ein Tag/Objekt. Man kann x Listen mit gleichen Namen und verschiedenen Adressen anlegen und diese so als Objekt in Firewall-Regeln verwenden. Bsp: Liste "webserver-via-chr-routen" 5x mit verschiedenen IP-Adressen. Im Firewall-Regelwerk kann ich nun statt mit "Dst. Address" mit Advanced/"Dst. Address List" arbeiten und alle Objekte (Listen) werden gleich behandelt. Wir benötigen zwei Adress-Listen (x) - eine für die Webserver "webserver-via-chr-routen" und eine welche die internen IP-Netzwerke "lokale-netze" auflistet. 

Über "Mangle" markieren wir nun alle Pakete welche der Liste/Objekte mit dem Namen "webserver-via-chr-routen" entsprechen, aber mit Ausnahme (!) der lokalen Zieladressen (auch hier wieder eine Liste "lokale-netze"), mit der Routing-Markierung (Routing Mark) "web-over-chr".

Als letztes erstellen wir eine extra default-Route (0.0.0.0/24) und verwenden als Gateway die Remote Tunnel-Adresse des Mikrotik CHR (192.168.171.1).

Spricht der Webserver nun eine Adresse an welche nicht zu den "lokale-netze" gehört (Internet) bzw. antwortet auf eine Anfrage wird so die Extra-Routing-Regel verwendet und das Paket via des Routers beim Cloud Provider geroutet. 

Tipp am Rande: Das kann man auch verwenden, wenn z.B. der eigene Internet Provider (ISP) Ports/Dienste beschränkt, aber VPN ignoriert. Bsp: Geoblocking eines Streaminganbieters. Hier müssen dann nur noch auf dem lokalen Mikrotik und dem beim Cloudprovider entsprechende die Firewall-Regeln ergänzt werden, welche den Zugriff von Innen nach Außen zulassen. 

Webserver On-Premise:

Hier war mir wichtig, dass dieser keine besondere Konfigurationsanpassung benötigt. D.h. es gibt keine extra gesetzten Routen, Firewall etc. Der Server hat ausschließlich seine IP aus dem 10.10.182.0/24 er Netz. Als Gateway und DNS Server ist der lokale Mikrotikrouter eingetragen und kümmert sich um alles. Der Webserver selbst hat keinen Ausgehenden Internetzugang, er antwortet nur auf die Webseitenrequests. Seine eigenen Updates bezieht er über eine Proxyserverkonfiguration (läuft auf Mikrotik - wer hätte es gedacht). 

Diese Lösung funktioniert bei mir seit über einem Jahr problemlos. Man muss sich aber bewusst sein, dass die Verfügbarkeit der Webseite die Funktion aller Komponenten voraussetzt. (CHR, VDSL, Fritzbox, lokaler Mikrotik, VPN-Tunnel, DNS). Einen Schönheitsfehler hat es jedoch, auf dem CHR sieht man im Log (ja nach Einstellung der Firewall und Logging) immer wieder vermeintlich geblockte Pakete (SYN,ACK) (ACK,RST). Dabei handelt es sich u.a. um geschlossene Sessions. Eine Funktionseinschränkung kann ich nicht feststellen. 

Dennoch werde ich perspektivisch auf Variante 2 - siehe Artikel "Webseite mit öffentlicher IP auf Homeserver hosten Variante #1" umstellen.