Wozu VPN wenn es SSH gibt?

Nehmen wir mal an ihr wollt in ein bestimmtes Netzwerk zu welchem ihr Zugangsdaten habt für einen SSH-Server.
Dann ist quasi alles möglich, und noch viel mehr. Zunächst einmal benötigen wir auf einem Unix-Rechner folgende Datei ~/.ssh/config
mit folgendem Inhalt:
Host remote.server
HostName ssh.domain.com
User user
Port 222
Host client-pc
HostName 192.168.1.xxx
User user
DynamicForward 1080
LocalForward 1631 127.0.0.1:631
ServerAliveInterval 60
ServerAliveCountMax 3
ProxyCommand ssh -q -W %h:%p user@ssh.domain.com -p 222
ProxyCommand proxytunnel -p 192.168.1.1:8080 -r %h:%p -u proxyuser -s proxypass
Sieht erstmal sehr kryptisch aus, im folgenden Text wird aber noch auf jeden dieser Punkte eingegangen, dies ist quasi die eierlegende Wollmilchsau und jeder kann hier Dinge evtl. weglassen.
1. SSH-Jump-Host
Zunächst einmal wird in dieser ssh-config davon ausgegangen, dass ein ssh jump notwendig ist, der erste Host ist unser Zugangspunkt eines über das Web offenen ssh Zugriffspunkt, der zweite Host ist quasi ein weiterer dahinter liegender Client. Wer also keinen ssh jump benötigt, der lässt den ersten Absatz mit dem ersten Host einfach weg.
2. Zusatzprogramme
Als erstes müssten folgende Tools installiert werden:
sudo apt install proxychains-ng proxytunnel openssh-server
sudo dnf install proxychains-ng proxytunnel openssh-server
3. Passwortfrei dank ssh-Zertifikaten
Damit der Zugang Passwortfrei mit ssh-zertifikaten funktioniert führen wir folgende Befehle aus, zunächst generieren wir einen ssh-key, falls noch nicht geschehen:
ssh-keygen
und als nächstes übertragen wir die Keys auf den Remote-Server und falls nötig auch als erstes auf den Jump-Host:
ssh-copy-id -p 222 user@ssh.domain.com
und danach auf den eigentlichen Remote-Host, nicht wundern hier wird bereits der Name des SSH-Zugangs aus der config verwendet anstelle einer IP o.Ä.
ssh-copy-id client-pc
4. Erstellen eines Start- und eines Stopscripts
wir legen ein Script an: nano ~/start_ssh.sh
und folgendem Inhalt:
#!/bin/bash
#sleep 15 #unkommentieren falls das Script als Cronjob bei jedem Reboot laufen soll
ssh -fN client-pc
Wie im Script bereits erwähnt wird ist es ratsam einen sleep-timer von 15 Sekunden einzubauen für all jene die dieses Script automatisch als Cronjob bei jedem Reboot verwenden wollen. Ansonsten würde das Script zu früh im Bootprozess scheitern. Der Vorteil als Cronjob ist, dass die Verbindung quasi immer nach dem Start ausgeführt wird.
Ein Script zum Beenden der SSH-Verbindung sieht folgendendermaßen aus und kann z.B. unter: nano ~/stop_ssh.sh
angelegt werden.
#!/bin/bash
# Find the PID of the SSH process running for 'another-pc'
pid=$(ps aux | grep 'ssh -fN client-pc' | grep -v grep | awk '{print $2}')
# Kill the process if the PID is found
if [ -n "$pid" ]; then
kill $pid
echo "SSH connection to client-pc has been terminated."
else
echo "No active SSH connection to client-pc found."
fi
Das Beenden der SSH Verbindung kann sinnvoll sein, besonders wenn man andere Verbindungsarten einsetzen möchte und damit nicht in Konflikt geraten will.
Nicht vergessen, dass die Scripte noch als Ausführbar markiert werden sollten.
chmod +x ~./start_ssh.sh
chmod +x ~./stop_ssh.sh
5. Socks Proxy für Firefox (optional)
Die Zeilen unserer ssh-config enthalten ganz unten folgende Zeilen, welche lediglich benötigt werden, wenn es beim Zielrechner einen Proxyzugang gibt.
ProxyCommand ssh -q -W %h:%p user@ssh.domain.com -p 222
ProxyCommand proxytunnel -p 192.168.1.1:8080 -r %h:%p -u proxyuser -s proxypass
Diejenigen die am Remote-PC einen Proxy verwenden müssen können dies über folgende Einstellungen erreichen:
Firefox benötigt jetzt noch die richtigen Netzwerkeinstellungen, wir wählen aus:
Manuelle Proxyeinstellungen -> alles leer lassen außer bei Socks-Proxy tragen wir ein: localhost mit dem Port 1080 und SocksV5 auswählen. Ebenfalls ganz unten ein Häkchen setzen bei: Bei Verwendung von SOCKS v5 den Proxy für DNS-Anfragen verwenden.
Alternativ bietet es sich auch an das Add-on FoxyProxy zu verwenden, dies dient einer besseren Kontrolle und Umschaltfunktion zwischen den verschiedenen Proxyeinstellungen.
6. Lokale Programme befähigen den Socks-Proxy zu verwenden (optional)
Am Beispiel Remmina erklärt:
Für Remmina benötigen wir das proxychains-ng tool. Hierfür erstellen wir einen Starter der Remmina mit diesem Zusatz öffnet: "proxychains remmina"
Zusätzlich erstellen/ergänzen wir die proxychains config am Ende unter /etc/proxychains.conf
mit folgendem Text:
socks5 127.0.0.1 1080
7. Remote Verzeichnisse einbinden
Um Dateiverwaltungsprogramme wie Nautilus, Nemo, Dolphin etc. zu befähigen auf die entfernten Ordner zuzugreifen reicht es i.d.R. aus in der Eingabezeile des Dateimanagers folgendes einzutragen:
sftp://client-pc
8. Remote-Drucken
Hierbei geht es um diese wichtige Zeile:
LocalForward 1631 127.0.0.1:631
Dies ermöglicht es uns auf den Cups-Server des Clients zuzugreifen (vorausgesetzt dieser Client hat einen Cups-Server und die darin bereits eingerichteten Drucker). Wir benötigen hierfür aber noch einige Zusatzprogramme, in diesem Beispiel mit dnf installiert:
sudo apt install cups cups-browsed colord
sudo dnf install cups cups-browsed colord
Danach ergänzen wir in der Cups-config noch den Hinweis, dass wir einen anderen Port als den normalen verwenden, dass liegt schlicht daran, dass Ports unter 1000 bestimmten Restriktionen unterliegen, welche wir der Einfachheit halber umgehen wollen.
echo "ServerName localhost:1631" | sudo tee -a /etc/cups/client.conf
sudo systemctl restart cups
Als nächstes überprüfen wir, ob denn wirklich bereits alle Drucker auf der Gegenseite auch bei uns gelistet werden:
lpstat -h localhost:1631 -e
Diese Eingabe müsste uns die Drucker des ssh-remote-clients ausgeben und dem Remote-Drucken sollte nun nichts mehr im Wege stehen, jedes Programm mit einer Printfunktion müsste nun unsere Drucker des Remote-Clients ausweisen.
9. Fazit
Es ist also jederzeit Möglich in einem remote Netzwerk zu Arbeiten und dort lokale Adressen in Firefox zu öffnen, die Dateistruktur zu verwenden oder sogar Dokumente auszudrucken. Alles ganz ohne VPN.
10. Bonus: Wake-on-Lan
Kleiner Gedanke zum Schluss, was wäre wenn man den externen Client nur dann einschaltet, wenn er auch benötigt wird? Also Das Start- und Stopscript um die Möglichkeit ergänzen den Client erst dann Ein- bzw. Auszuschalten. Hierzu gibt es einige Vorbereitungen:
Bios-Einstellungen
Wake-on-Lan sollte im Bios aktiviert werden, entweder wirklich als Begriff "Wake-on-Lan" zu finden oder es verbirgt sich hinter PXE-Einstellungen.
Shutdown ohne sudo
Damit wir im Stopscript den Client nach Verwendung auch wieder herunterfahren können ist es notwendig systemctl poweroff
ohne sudo auszuführen. Dazu folgende Datei mit dem folgenden Inhalt ergänzen:
sudo nano /etc/polkit-1/rules.d/49-shutdown.rules
polkit.addRule(function(action, subject) {
if (action.id.indexOf("org.freedesktop.login1.") === 0 && subject.isInGroup("users")) {
return polkit.Result.YES;
}
});
Evtl. muss "users" mit "wheel" ersetzt werden, das hängt davon ab ob der User des Clients in der Wheel oder in der User-Gruppe verortet ist.
Wake-on-lan einrichten
Auf dem Ziel-Client nutzen wir nun das Tool ethtool
um zunächst unsere permanente MAC-Adresse zu identifizieren.
ethtool -p eth0 #replace eth0 with your Name for the ethernet adapter
Diese notieren wir dann im fertigen Script.
Wichtig wäre auch zu wissen ob das System Wake-on-lan unterstützt, dieser Befehl überprüft ob Wake-on-Lan verfügbar ist. Sollte hier im Ergebniss "d" anstelle von "g" stehen bedeutet dies wir müssen zunächst "wol" aktivieren.
ethtool enp2s0 | grep "Wake-on"
Dies ermöglichen wir über einen Systemd-Eintrag mit folgender Datei und folgendem Inhalt:
sudo nano /etc/systemd/system/wol.service
[Unit]
Description=Enable Wake-on-LAN
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool -s enp2s0 wol g
[Install]
WantedBy=default.target
Der neue Systemd-Eintrag muss nun noch aktiviert und gestartet werden:
sudo systemctl enable wol.service
sudo systemctl start wol.service
Unser Jumphost (sofern wakeonlan auch als Paket installiert ist) sollte nun in der Lage sein den Client mit folgendem Befehl zu starten:
wakeonlan <MAC-ADDRESS>
Start- und Stoppscripte anpassen
Nun gilt es die beiden Scripte auf die neue Situation anzupassen (Achtung: hier ist beim Startscript eine Pausephase von 60 Sek. hinterlegt um dem Client die nötige Zeit zum Booten zu geben:
Startscript:
#!/bin/bash
ssh -p 222 user@ssh.domain.com "wakeonlan 12:34:56:78:9A:BC"
sleep 60 #Pause für den Systemstart evtl anpassen.
ssh -fN client-pc
Stopscript:
#!/bin/bash
ssh client-pc "systemctl poweroff"
sleep 10
# Find the PID of the SSH process running for 'another-pc'
pid=$(ps aux | grep 'ssh -fN client-pc' | grep -v grep | awk '{print $2}')
# Kill the process if the PID is found
if [ -n "$pid" ]; then
kill $pid
echo "SSH connection to client-pc has been terminated."
else
echo "No active SSH connection to client-pc found."
fi
Nun startet und fährt unser Client-PC bei jedem Einsatz rauf und runter. Das ist sicherlich auch als Energieeffizient zu bezeichnen.