VNC durch den Router tunneln!

Das Netzwerk ist ja schon eine tolle Sache. Rein theoretisch kann man von überall auf seinen Computer zugreifen, Daten entnehmen, an Projekten arbeiten, Wartung durchführen, oder was auch immer. Die Möglichkeiten scheinen schier endlos!

Was aber, wenn man von aussen gar keinen Zugriff auf den heimischen Rechner bekommt, da der Router das nicht zulassen will?

Einige werden schon vor dem Problem gestanden haben! Da bin ich mir ziemlich sicher!

Lösungswege gibt es da viele. So kann man zum Beispiel, wenn man mit Git arbeitet, einfach auf einem externen Server seine Projekte auslagern und greift dann dort zu. Das funktioniert ausgezeichnet und ich mache das genauso.

Nächste Möglichkeit, wenn man ja schon einen Server zur Hand hat, man baut sich ein VPN auf. Auch das habe ich bei mir so realisiert. Funktioniert ebenfalls ganz ausgezeichnet!

So. Nun ist man aber bei Kollege XYZ und auf einmal steht man vor einer Aufgabe. Sagen wir mal, der will mittels Qemu eine virtuelle Maschine in Betrieb nehmen, aber irgendwie will das einfach nicht funktionieren. Man selbst weiss aber, zuhause hat man sich schon ein Start-Skript gebastelt, welches hervorragend funktioniert. Das Problem ist nur, dass ist eben zuhause und nicht hier. Dummerweise ist Kollege XYZ nicht im eigenen VPN und das ist auch gut so. Vielleicht hat man zuhause ja zum Beispiel Bilder gespeichert, welche jene Person nicht sehen soll? Ergo, der soll nicht ins VPN.

Wie toll wäre es denn, wenn man trotzdem eine Möglichkeit hätte, auf den heimischen Rechner zuzugreifen?

Genau hier setzen wir an. Ziel der Mission ist es, einen heischen VNC über das Internet zugänglich zu machen. Ohne VPN! Ich habe mich dabei bewusst für VNC entschieden und nicht für SSH, da man damit dann noch andere Spielchen machen kann. Ihr werdet sehen!

Versuchsaufbau

Ich will versuchen, den VNC auf meinem Raspberry Pi über meinen Laptop zu erreichen. Den Laptop nehme ich dabei aus dem heimischen Netz und lasse ihn mittels Hotspot über mein Handy eine Verbindung aufbauen.

Ziel soll es sein, den VNC über eine Domain zu erreichen. Also zum Beispiel raspi.tld:5901. Ihr werdet verstehen, warum ich hier nicht die wirkliche Adresse angebe.

Installation

Wie man einen VNC installiert und einrichtet, habe ich schon im Artikel TigerVNC (ab 1.11.0) beschrieben, da gehe ich also nicht mehr drauf ein.

Hier soll es einzig darum gehen, wie man den entsprechenden Tunnel aufbauen muss. Dazu installiert man … na ja … Linux. In allen mir geläufigen Distributionen ist von Start an alles dabei, was man dafür braucht. Ergo, installieren muss man hier nichts!

Der Pi stellt mir dabei ein Bein. Natürlich. Bei dem war autossh nicht installiert, was ich erst beim schreiben dieses Artikels gemerkt habe.. Das geht aber simpel mit:

sudo pacman -S autossh

Zumindest unter Arch. Wie ihr das in eurer Distribution, falls es doch nicht vorhanden sein sollte, installiert, dürftet ihr ja selbst wissen.

Auf dem Pi und meinem Laptop läuft jeweils Arch, auf dem Server Gentoo.

Raspberry einrichten

Versteift euch jetzt nicht darauf, dass ich hier mit einem Raspberry arbeite. Für mich bietet sich das im Moment aus Gründen einfach an. Ihr könnte das natürlich auf jedem in eurem Netzwerk befindlichen, Linux betriebenem Rechner machen!

Da haben wir ihn auch schon. Im linken Terminal werde ich alle Arbeiten am Raspberry Pi durchführen, der bei mir piserver heisst, da ich recht viel mit dem kleinen Kerl mache. Im rechten Terminal arbeite ich dann auf dem Server.

Schritt 1: Hinsetzen!

Ja, ich weiss. Kaum einer wird vor der Arbeit dumm vor seinem PC stehen. Warum ich das trotzdem immer wieder schreibe, werde ich irgendwann einmal enthüllen!

Schritt 2: Die Schlüssel für SSH

Dieser Schritt ist optional. Wer das nicht durchführen will, der muss eben jedes Mal das Passwort eingeben. Hier geht es also wirklich nur darum, dem Server den Pi bekannt zu machen, damit der Server weiss, den da kenne ich, der darf rein.

Wer natürlich schon seinen heimischen Rechner mittels Keys dem Server bekannt gemacht hat, der kann diesen Schritt ebenfalls überspringen. Aber, wem sag ich das?

Wir wollen natürlich nicht irgendeinen dahergelaufenen Schlüssel. Der soll schon was bringen, also darf er auf RSA basieren und 4096 Bit haben. Soll ja nicht irgendwer da unerlaubt einbrechen können.

Das funktioniert sehr einfach.

ssh-keygen -t rsa -b 4096

Das war ja schon erfreulich einfach. Man wird nach einem Zielverzeichnis gefragt, nach einem Passwort und der Passwort Wiederholung. Das kann man einfach alles mit Enter durchreichen.

Schockierend aber wahr, dass war es schon auf dem Pi. Ergo, wer seinen Schlüssel schon generiert und an den Server geschickt hat, der muss auf dem Rechner zuhause gar nichts machen! Oder auch jene, die lieber ein Passwort eingeben. Auch die haben auf dem heimischen Rechner keine Arbeit!

Server einrichten

Schritt 1

Siehe oben.

Schritt 2: ssh konfigurieren

Von Werk aus will SSH aber nicht zulassen, was wir da vorhaben. Grund dafür sind Sicherheitsaspekte. Keine Tür öffnen, die man eigentlich nicht braucht.

So, wir wollen das aber jetzt haben, also müssen wir folgende Datei als Root editieren:

sudo nano /etc/ssh/sshd_config

Hier müssen nun folgende drei Zeilen auskommentiert werden. Bei Bedarf kann man sie auch einfach kopieren und ganz unten hinzufügen.

#GatewayPorts no

wird zu

GatewayPorts yes
#ClientAliveInterval 0

wird zu

ClientAliveInterval 60
#ClientAliveCountMax 3

wird zu

ClientAliveCountMax 2

Oder eben für die Faulen:

GatewayPorts yes
ClientAliveInterval 60
ClientAliveCountMax 2

Einfach ans Ende kopieren.

Das wird dann gespeichert.

Schritt 3: sshd neu starten

Ich denke zwar, die Meisten werden das ohnehin gleich getan haben, aber wer es vielleicht nicht wissen sollte, nachdem man an der sshd_config etwas verändert hat, sind diese Änderungen erst nach einem Neustart von sshd wirksam. Das ist aber glücklicherweise sehr einfach.

sudo systemctl restart sshd

Jetzt kann man sich noch anschauen, dass man auch keinen Mist gemacht hat und sshd auch wieder sauber läuft.

sudo systemctl status sshd

Japp, läuft alles!

Schritt 4: Den öffentlichen Schlüssel vom Pi bekannt machen

In diesem Schritt dürfte klar werden, warum ein solches Layout der beiden Terminals ein Vorteil ist.

Man könnte nun auf diverse Wege den Key auf den Server schicken. Über sshfs, über die Kopierfunktion von ssh, über FTP, was weiss ich. Es geht aber auch viel einfacher!

Der öffentliche Schlüssel ist nichts weiter als eine Ansammlung von Zeichen. Schauen wir es uns doch einfach mal auf dem Pi an.

cat .ssh/id_rsa.pub

Das ist tatsächlich alles! Verwechselt das aber bitte nicht mit eurem privaten Schlüssel, der bleibt mal schön geheim! Den Text markieren wir jetzt und kopieren ihn in die Zwischenablage. Strg+c funktioniert in den Meisten Terminal-Emulatoren nicht, da muss man also mit der rechten Mousetaste ans Werk.

Hat man das, öffnet man einfach, zum Beispiel mit Nano, auf dem Server die notwendige Datei:

nano .ssh/authorized_keys

Hier kopiert man dann einfach die Zwischenablage wieder ein.

Noch speichern und man ist fertig! Geht eigentlich wirklich sehr einfach und schnell.

Den Tunnel aufbauen

Optional:

Gerade, wenn man alles zum ersten Mal konfiguriert, empfiehlt es sich, dem Server ein bisschen auf die Finger zu schauen. Klappt denn alles, was man da so gemacht hat? Wird der richtige Port geöffnet? Wird überhaupt ein Port geöffnet?

Ich empfehle deshalb folgendes auf dem Server auszuführen:

watch "netstat -tulpn"

Das sieht dann so aus. Verzeiht, wenn ich einige Teile unkenntlich gemacht habe. Man weiss ja nie, wer aus welcher Information etwas negatives extrahieren kann.

Aber gut, wenn das läuft, können wir den Tunnel ja mal vom Pi aus aufbauen.

ssh -N -R 5901:localhost:5901 diabolus@raspi.tld

Was genau macht das jetzt? Wichtig ist die Option -R, da die für den Tunnel zuständig ist.

Die nächste, wichtige Option ist 5901:localhost:5901. Damit sagen wir dem Server, er soll den Port 5901 auf der Rechten Seite bei sich auf den Port 5901 vom Pi mappen. Hier könnte man auch schreiben:

5901:localhost:6789

Dann müsste man mit dem VNC auf Port 6789 gehen und käme dennoch auf dem Port 5901 vom Pi raus. Das kann ja recht praktisch sein!

Der letzte Parameter diabolus@raspi.tld ist der normale Zugang zum Server. So wie ihr normalerweise auch auf den Server gelangt. Hab ihr auf dem PC zuhause und dem Server den gleichen Benutzer, könnt ihr den auch weglassen. Also dann einfach nur raspi.tld.

Feuern wir das mal ab und schauen, was passiert!

Tada, da ist ja unser Tunnel! Hat soweit also alles funktioniert. Oder? Finden wir es doch heraus!

Auf dem Laptop gebe ich jetzt einfach folgendes ein. Der ist über den Hotspot meines Handys verbunden und hängt nicht im heimischen Netz!

vncviewer raspi.tld:5901

Freude schöner Götterfunke …

Hat ja super geklappt! Ich kann nun also von Aussen mühelos auf meinen VNC vom Pi zugreifen, damit arbeiten usw. Ohne, dass auf dem fernen Rechner mehr installiert ist, als nur ein VNC-Viewer! Kein VPN, kein gar nichts!

Okay. Man könnte jetzt hier kritisch anführen:

Und wenn auf dem entfernten Rechner kein VNC ist?

Das ist natürlich richtig. Aber, man kann es ja nicht nur mit VNC machen! Vielleicht arbeitet man ja an einem streng geheimen Projekt, dessen Daten nicht auf irgendeiner Festplatte auf irgendeinem Host-Anbieter liegt!

Vielleicht ist man ja ein Autor, so wie ich, und hat seinen neusten Bestseller auf einem Gitlab zuhause liegen und will es nun einem guten Freund zur Korrektur übergeben. Ja, man könnte es auch ausdrucken, auf Stick ziehen, oder was auch immer. Denkt mir nicht immer alles kaputt, sondern überlegt euch selbst Szenarien!

Ausserdem sind wir ja noch gar nicht fertig!

Autossh

Schauen wir uns doch noch einmal diesen Screenshot an:

Einem geübten Anwender dürfte dabei etwas beim Pi auffallen.

Richtig! Der hängt in seinem Kommando fest! Schliessen wir das Terminal, verschwindet auch der Tunnel und das wollen wir ja wahrscheinlich nicht!

Die Lösung hier heisst autossh. Im Prinzip ganz einfach ssh, mit ein paar Zusatzoptionen. Starten wir den Tunnel doch mal mit folgendem Kommando:

autossh -M 0 -f -o ConnectTimeout=10 -o ServerAliveInterval=60 -o ServerAliveCountMax=2 -N -R 5901:localhost:5901 diabolus@raspi.tld

Ja da schau her! Der Tunnel ist da und trotzdem könnte man jetzt die Verbindung zum Pi beenden, ohne dass der Tunnel verloren geht. Total toll!

Btw. Auf dem Pi musste ich autossh tatsächlich nachinstallieren. Auf meinem Desktop war es direkt dabei. Komisch. Also falls jemand autossh nicht drauf haben sollte, einfach nachinstallieren.

Ein Service muss her!

Nun gut. Soweit ist das ja alles schon ganz toll! Es hat aber einen kleinen Schönheitsfehler. Der Tunnel ist weg, wenn der Pi neu gestartet wird. Das kommt bei mir zwar nur selten vor, da der immer läuft, aber da ist ja noch die Geschichte mit den Updates. Ist da ein neuer Kernel dabei, soll der ja auch benutzt werden, was dann doch ein Neustart erfordert.

Der umständliche Weg wäre, man könnte autossh dann nach dem Neustart ausführen. Geht, ist auch in Ordnung. Aber hier schlägt der böse Murphy mit seinem dummen Gesetz wieder zu. Es kann also sein, dass man 1000x ein Update durchführt und jedes Mal brav autossh wieder gestartet hat. Dann kommt dieser eine Fall, wo man es vergisst, unterwegs ist und der Tunnel ist weg, obwohl man ihn gerade da brauchen würde.

Um das zu umgehen, habe ich ein bisschen rum gebastelt. Es gibt sicherlich einige Wege, wie man das lösen kann, ich bevorzuge jedoch, wenn alles schön einheitlich ist. Was würde da also näher liegen, als einen Service für den Tunnel bereitzustellen?

Damit das nicht jeder selber bauen muss, habe ich hier mal etwas zum kopieren und einfügen für euch.

[Unit]
Description=einen Tunnel für VNC
After=network-online.target
Wants=network-online.target

[Service]
Environment="LC_ALL=C.UTF-8"
Environment="LANG=C.UTF-8"
Type=simple
User=<benutzer>
ExecStart=/usr/bin/autossh -M 0 -o "ConnectTimeout=10" -o "ServerAliveInterval=60" -o "ServerAliveCountMax=2" -N -R 5901:localhost:5901 <benutzer>@<server>

[Install]
WantedBy=multi-user.target

So einfach kommt ihr mir aber nicht damit durch! Denn überall wo <benutzer> und <server> steht, müsst ihr natürlich eure Benutzer und euren Server eintragen!

So. Das kommt dann zum Beispiel in die Datei vnctunnel.service.

sudo nano /etc/systemd/system/vnctunnel.service

Ab jetzt kann man wunderschön damit arbeiten!

sudo systemctl start vnctunnel

Damit startet man seinen Tunnel.

Perfekt! Mit:

sudo systemctl stop vnctunnel

beendet man ihn wieder, wär hätte das für möglich gehalten!

Mit:

sudo systemctl status vnctunnel

kann man dann auch noch den Status abfragen.

Wunderschön, oder?

Zum guten Schluss dann noch:

sudo systemctl enable vnctunnel

und das Ding startet in Zukunft bei jedem Neustart automatisch mit. So soll es sein!

Warum aber nun VNC?

Das ist ganz einfach. Hat jemand meinen Artikel “Qemu mit VNC” gelesen? Nein, dann solltet ihr das jetzt nachholen, denn darum geht es jetzt.

So. Es ist also möglich, qemu so zu starten, dass hinten ein VNC dabei herausfällt. Na? Hat schon jemand eine Vermutung?

Korrekt. Mit einem solchen Tunnel ist es also auch möglich, von aussen auf eine virtuelle Maschine zuzugreifen! Da sage ich nur, entdecke die Möglichkeiten!

Es gibt da sogar ein Szenario, was ich wohl in naher Zukunft mal ausprobieren werde.

Kennt jemand das Spiel “Birth of the Federation“? Das ist ein Runden basiertes Strategiespiel zum Thema Star Trek aus dem Jahr 1999. Seit 2003, oder 2004 spiele ich es immer wieder mit einem sehr guten Freund von mir. Der Haken an der Sache ist jedoch, er hat einen Mac, oder spielt unter Windows, ich unter Linux. Nächster Haken, dieses Spiel will nicht mal eben über das Internet laufen. Es hat zwar eine Multiplayer-Schnittstelle, aber die funktioniert eigentlich nur im lokalen Netzwerk.

Gut. Nun könnte man einen VPN benutzen. Machen wir auch in der Regel. Bislang lief das unter Hamatchi. Warum? Weil wir es bislang nicht gebacken bekommen haben, ihn in mein VPN einzubinden. Warum? Weil ich so gar keine Ahnung habe, wie man das auf Windows macht. Gut, dass könnte ich mir noch aneignen, da auf meinem Laptop ja auch Windows10 läuft, aber Mac? Davon hab ich ja so gar keine Ahnung. Ich habe auch keinen Zugriff auf seinen Computer und schliesslich, wir wollen spielen und nicht immer nur an irgendetwas herumbasteln.

So. Das Spiel hat jetzt auch Berge von Mods. Zudem kann ich es unter Wine dazu zwingen, in einem Fenster zu laufen. Gut. Bei mir läuft dann also alles, aber wie ist es bei ihm? Dann geht hier was nicht, dann klappt da was nicht und ich hab so gar keine Ahnung, warum das so ist!

Jetzt festhalten! Ich mache das jetzt viel einfacher! VNC gibt es sowohl für Windows, wie auch für Mac. Es zu installieren ist ja auch kein Hexenwerk. Was liegt da also näher, als wenn ich mir einfach eine kleine VM zusammenbastele, dort alles fertig zum laufen bringe und dann starte? Er logt sich über VNC dann in die virtuelle Maschine ein, startet das Spiel mit den Mods, wir gehen über meinen VPN und alle sind glücklich?

Zum Schluss

Wahrscheinlich wird sich jetzt der Eine oder Andere denken, so könnte man doch auch gemütlich einen Webserver vom heimischen Rechner aus ins Netz tunneln. Ja, geht! Aber!

Alles unter Port 1024 erfordert auf dem Server Root-Rechte! Das heisst, ihr müsst euren Tunnel als Root aufbauen. Ich muss hoffentlich niemandem erzählen, dass ihr damit unter Umständen einem Angreifer Tür und Tor öffnet! Von daher bin ich da jetzt auch nicht drauf eingegangen. Wer es ausprobieren will, kann dies auf eigene Gefahr gerne tum. Ich übernehme keine Haftung!

Schreib einen Kommentar

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