Die ganze Welt auf eine IPv4 oder wie man mit einer Adresse auskommen kann

Nachdem ich jetzt schon mehrfach gebeten wurde aufzuzeigen wie denn die Kameras (die nur IPv4 können, Schrottchinacams halt dafür sind die billig ) im Internet erreichbar sind obwohl sie nur private IPv4 Adressen aus dem Freifunknetz haben, habe ich mir überlegt einfach mal aufzuzeigen wie weit man eine IPv4 Adresse missbrauchen kann. Ich hab bei Hetzner nur 2 Adressen, eine für den Host, die zweite für diverse Services wie z.b. die Webcams oder auch diesen Blog hier .

Webseiten

Fangen wir erstmal mit Webseiten an. Wie bereits gesagt läuft dieser Blog aber auch viele weitere WordPress und andere Seiten auf verschiedenen LXC Containern auf meinen Hetznerserver. Diese LXC Container haben alle nur eine IPv6 Adresse aber keine IPv4 weil soviele kann ich mir armer Schlucker natürlich nicht leisten. Dazu gibt es den sogenannten natserver der eine IPv6 und eine IPv4 Adresse bekommt. Auf dem Natserver nutze ich Caddy2 als Reverseproxy der auch gleich die ganze Zertifikatgeschichte mit Letsencrypt übernimmt. Dort wird dann einfach intern auf die IPv6 des LXC Containers wo die Webseiten laufen weitergeleitet. Da das ganze intern bleibt, verzichte ich an diesem Punkt auch auf SSL. Eine Caddyfile sieht z.b. für WordPress so aus:

network.cdresel.de {
        reverse_proxy xxxx.dresel.systems:80 {
		header_up Host {host}
		header_up X-Real-IP {remote_host}
		header_up X-Forwarded-For {remote_host}
		header_up X-Forwarded-Proto {scheme}
        }
}

Allerdings gibt es auch “dumme Tools” die nicht damit klar kommen, wenn sie hinter dem Reverseproxy kein SSL machen man von vorne aber mit SSL rein kommt (hier z.b. librenms). Da wird also auch das backend mit einem selbstsignierten Zertifikat ausgeliefert und die Caddyfile musste man dann ein wenig anpassen, damit auch das selbstsignierte Zertifikat akzeptiert wird (Achtung! Es wird ignoriert, NICHT überprüft!):

librenms.dresel.systems {
	reverse_proxy xxxx.dresel.systems:443 {
 		transport http {
			tls_insecure_skip_verify
		}
	}
}

und ganz einfache Webseiten, wie z.b. das zerobin geht dann noch viel einfacher:

zerobin.fff.community {
	reverse_proxy rev.zerobin.dresel.systems:80
}

Weiterhin läuft im Brunnenhäuschen auch ein ADSB Empfänger, hier mach ich dann ganz böse Sachen. Dieser ADSB Empfänger hat IPv6 und nur eine private IPv4 da er im Freifunknetz hängt und es dort keine öffentliche IPv4 Adressen gibt, sehr wohl aber öffentliche IPv6. Damit er Dualstack aus dem ganzen Internet erreichbar ist, nutze ich hier ebenfalls den Caddyserver:

adsb.dresel.systems {
	reverse_proxy rev.adsb.dresel.systems:80 
}

Das böse daran ist, das der Traffic nach dem Reverseproxy diesmal quer durch das ganze Internet (beim Korrekturlesen musste ich eben über “das ganze Internet” lachen, weil ich es aber so witzig fand lass ich es jetzt stehen ;)) ohne Verschlüssung(!!) geschickt wird. Da auf dem ADSB Empfänger keine privaten Daten wie Passwort o.ä. übertragen werden, lebe ich einfach damit. Für den Enduser sieht es also aus als wäre alles sicher, ist es aber absolut nicht. Ich will damit noch aufzeigen, man sollte sehr genau wissen, was man hinter dem Reverseproxy so treibt und das dort durchaus Daten unverschlüsselt auch quer durch das Internet übertragen werden können obwohl man als Enduser ein grünes Schloss (seit wann ist das im Firefox eigentlich grau? Ok anderes Thema) sieht.

Und das alles läuft nun auf einer einzigen IPv4 Adresse (ja auch alles auf einer einzigen IPv6 Adresse, da auch dies durch den Reverseproxy geht, es sind alle genannten Seiten von außen Dualstack). Weitere Vorteile sind:

  • Das ganze ist extrem flexibel, weiteren LXC Container dazu geklickt, dort einen http(s) Service installieren, Reverseproxy erweitern, config neu laden, fertig.
  • Auch wenn (z.b. bei ADSB Empfänger) man irgendwo eine Seite hat die schon modern ist und nur IPv6 hat, kann man sie hinter den Reverseproxy klemmen und hat Dualstack, dabei natürlich an die Crypto hinter den Reverseproxy denken und auch das es die Wege lang macht und u.U. die Latenz erhöht.
  • Backupstrategie ist mittlerweile einfach nur noch, die ganzen LXC Container sichern. Da ist alles drin was wichtig ist.

Aber hey, das ist ja jetzt nur http(s) man kann doch bestimmt noch weitere lustige Sachen machen. Jetzt kommen wir endlich zu den Webcams.

Webcam mit öffentlicher Adresse erreichbar machen

Diese Webcams hängen im Freifunknetz und haben dort eine private IPv4 Adresse. Diese ist natürlich aus dem Internet nicht erreichbar. Daher wurde auch der natserver mit ins Freifunknetz gehangen und er kann somit private IPv4 Adressen aus dem Freifunknetz erreichen, das ganze sieht so aus:

christiand@natserver:~$ traceroute 10.50.140.101
traceroute to 10.50.140.101 (10.50.140.101), 30 hops max, 60 byte packets
 1  10.83.227.161 (10.83.227.161)  0.077 ms  0.057 ms  0.038 ms
 2  fff-gw-cdhome.fff.community (10.50.138.1)  8.500 ms  8.488 ms  8.535 ms
 3  hh.gw.fff.community (10.50.130.1)  19.717 ms  19.733 ms  19.957 ms
 4  fff-gw-th.fff.community (10.50.141.1)  19.953 ms  19.939 ms  23.449 ms
 5  fff-gw-knobl.fff.community (10.50.140.1)  35.452 ms  35.621 ms  35.430 ms
 6  10.50.140.101 (10.50.140.101)  35.583 ms  35.193 ms  35.176 ms
christiand@natserver:~$ 

so und jetzt kommt die Magie. Ein Freifunkkollege hat mir da zum Glück ein wenig an den iptables rules geholfen (Danke!) ich habs alleine erstmal nicht hinbekommen aber mittlerweile verstanden.

	iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 555 -j DNAT --to-destination 10.50.140.101:554
	iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 10.83.227.165

Hilfe was ist das? Ok ich versuche es mal zu erklären:

Die erste rule nimmt alle Pakete die auf -i eth0 rein kommen noch vor der Routingentscheidung -A PREROUTING, mit dem Protokoll -p tcp auf –dport 555 (destionation Port). Also alles was die öffentliche 188.40.122.107 IP auf Port 555 erreicht wird diese rule durchlaufen. Danach machen wir -j DNAT (Destionation NAT) und schreiben das Ziel um auf 10.50.140.101 port 554. Also die Pakete erhalten als neues Ziel nun 10.50.141.101 auf Port 554. Dahinter läuft auf der Kamera der rtsp Stream. Da der natserver diese IP erreichen kann, werden die Pakete also an die Kamera weitergeleitet.

Jetzt haben wir aber noch ein Problem. Die Kamera muss ja die Pakete auch wieder zu uns zurück finden. Sie würde versuchen die Pakete direkt an die IP zu senden, der die Kamera aufruft (also z.b. eure öffentliche Telekom/Vodafone/whatever IP). Da im Freifunknetz diese aber auf die default route fällt, wäre der Rückweg irgendwo ganz wo anders, das äh klappt nicht äh… Begründung uff, klappt halt nicht 😉 (Gerne jemand in den Kommentaren auflösen, dann bearbeite ich das hier nochmal, vielleicht fällt es mir auch später selbst wieder ein)

Also sollten wir dafür sorgen, das die Pakete auch wieder zu uns zurück finden. Dies wird mit der zweiten rule erledigt. Dazu muss ich sagen, eth2 ist das Interface das ins Freifunk fällt (also wo oben auch mein gezeigter traceroute raus fällt). Hier wird nach der Routingentscheidung -A POSTROUTING alles was -o eth2 verlässt die Sourceadresse -j SNAT überschrieben mit –to-source 10.83.227.165 was die IP des natservers ist. Somit wird also eure Telekom/Vodafone/whatever IP durch 10.83.227.165 ersetzt und die Kamera schickt ihre Pakete auch wieder zu meinem LXC zurück, wo sie dann wieder durch das wissen im conntrack das diese Pakete zu eurer Verbindung gehören auch wieder zu euch zurück geschickt werden.

Das war schon die ganze Magie und ich hoffe ich hab es irgendwie halbwegs verständlich erklärt. Zumindest hab ich es mal probiert und mein bestes getan. Wenn irgendwas unklar ist, fragt einfach dann erkläre ich das gerne noch tiefergehend. Indem man eingehend den Port ändert kann man so auch ganz viele Webcams hinter einer IP probieren, so gibt es hier aktuell zwei Stück [1] [2]. Zugegeben irgendwann gehen einen die Ports aus, aber so viele Webcams habe ich aktuell nicht vor zu verbauen und vielleicht lernen diese Chinadinger ja doch noch irgendwann IPv6.

Schreibe einen Kommentar

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