Freitag, 11. Mai 2018

SSH Tricks - Remote Port Forwarding, oder: Support-Zugriff auf den PC der Mutter

Mittels SSH gibt es eine einfache Möglichkeit einen Remote-Zugriff auf Systeme hinter Firewalls/ NAT zu ermöglichen: Remote Port Forwarding - eine besonders nützliche Funktion wenn man bei den Eltern IT-Support macht und nicht ständig hinfahren will ;)

Wie in folgendem Bild zu sehen ist, lässt sich mittels Remote Port Forwarding ein beliebiger lokaler Port auf einem System (in der Grafik TARGET) an einen Port auf einem Remote Server weiterreichen. Alle eingehenden Verbindungen auf diesem Port am Remote Server werden dann automatisch durch die bestehende SSH Verbindung zu dem System hinter der Firewall weitergegeben. Somit kann, trotz NAT und Firewall, eine Verbindung per SSH von SUPPORT zu TARGET aufgebaut werden. 

SSH Remote Port Forwarding

SSH Konfiguration

Hinweis: Im Folgenden werden nur die relevanten Einstellungen für unser Port-Forwarding aufgeführt. Da beide SSH-Dienste über das Internet erreichbar sein werden, sollten deren Konfiguration grundsätzlich gehärtet und sicher sein. Eine gute Anleitung dazu gibt es im Gentoo-Wiki.

Mit folgenden Einstellung lässt sich das Port Forwarding auf dem SERVER aktivieren. Da wir die Verbindung dauerhaft aufrecht erhalten wollen und dabei das Risiko für SERVER so klein wie möglich halten wollen, erstellen wir für das Port Forwarding einen eigenen Benutzer namens remoteport auf SERVER und schränken diesen stark ein. Hierzu legen wir den Benutzer mit minimalen Berechtigungen ohne Gruppenzugehörigkeit an:
SERVER # useradd -m remoteport
Zusätzlich sorgen wir per Konfiguration des SSH-Daemon dafür, dass dieser Benutzer nur Remote Port Forwarding nutzen kann:
  • ForceCommand: Damit wird verhindert das der Benutzer eine shell oder scp/sftp benutzen kann. Stattdessen wird immer und ausschließlich der definierte Befehl ausgeführt.
  • X11Forwarding: Deaktivierung von X11-Weiterleitung durch den SSH-Tunnel
  • PermitTunnel: Deaktivierung der VPN-Funktionalität (Weiterleitung von TUN Interfaces)
  • PermitOpen: Limitierung von Local Port Forwarding. Ohne kann SERVER als Proxy benutzt werden.
Mittels der Option GatewayPorts lässt sich konfigurieren, ob die weitergeleiteten Ports auf dem Server extern zugreifbar sind oder nur über localhost/loopback interface.
Je nachdem was in der sshd_config global erlaubt wurde sollte natürlich noch mehr für den Benutzer deaktiviert werden (z.B. AgentForwarding)

Benötigte Einstellungen: /etc/ssh/sshd_config auf SERVER
PermitRootLogin no
PasswordAuthentication no
Match User remoteport
    AllowTCPForwarding yes
    X11Forwarding no
    PermitTunnel no
    PermitOpen localhost:61234
    GatewayPorts yes
    ForceCommand echo 'Support Account - Login forbidden'
Da durch das Remote Port Forwarding der SSH-Dienst auf TARGET über das Internet erreichbar sein wird, sollten zumindest, zum Schutz vor Bruteforce-Angriffen, keine Passwortbasierte Anmeldung zugelassen werden.

Empfohlene Einstellungen: /etc/ssh/sshd_config auf TARGET
PermitRootLogin no
PasswordAuthentication no
Nachdem wir die Konfiguration gemacht haben, müssen wir nur noch je ein SSH-Key-Paar auf TARGET und SUPPORT erzeugen und die public Keys verteilen:
# ssh-keygen -t ed25529
Die Verteilung der Keys sieht dann wie folgt aus:
  1. id_ed25519.pub von TARGET muss in die Datei ~remoteport/.ssh/authorized_keys auf SERVER eingetragen werden
  2. id_ed25519.pub von SUPPORT muss in die Datei ~support/.ssh/authorized_keys auf TARGET eingetragen werden
Danach kann von TARGET aus der Tunnel zu Server mit folgendem Befehl aufgebaut werden:
# ssh -N -R 60022:localhost:22 remoteport@SERVER  

Automatischer Start des SSH-PortForwarding beim Booten

In meinem Beispiel soll über SSH ein Remote Support für meine Mutter ermöglicht werden. Um es möglichst fehlertolerant zu gestalten, muss der Tunnel automatisch beim System-Start aufgebaut werden. Voraussetzung hierzu ist allerdings, dass der verwendete Schlüssel für die Authentisierung ohne Passphrase abgelegt ist. In dem Fall ist es also umso wichtiger, dass der Benutzer remoteport gut abgesichert ist!

Als erstes legen wir uns ein kleines Script unter /usr/local/bin/remote_port.sh an (natürlich muss es noch als ausführbar markiert werden):
#!/bin/sh
ssh -i [PATH-TO-id_ed25519.pub] -N -R 60022:localhost:22 remoteport@SERVER
Als nächstes müssen wir nur noch dafür sorgen, dass das Script beim System-Start ausgeführt wird. Das geht z.B. bei systemd durch das Erzeugen eines Unit-Files unter /etc/systemd/system/remote_ssh.service:
[Unit]
Description=SSH Remote Port Forwarding
ConditionPathExists=|/usr/bin
After=network.target
[Service]
User=localuser
ExecStart=/usr/local/bin/remote_port.sh
RestartSec=60
Restart=always
[Install]
WantedBy=multi-user.target
Natürlich muss der Unit-File noch "enabled" werden damit er auch beim System-Start ausgeführt wird:
# systemctl enable remote_ssh.service
Bei anderen Init-Systemen ist das ähnlich einfach. Ggf. muss man nur die auto-restart-Funktionalität selber bauen. Das geht z.B. in dem man einfach das Script remote_port.sh beim Aufruf forked und dann im Hintergrund innerhalb einer while true-Schleife das SSH-Kommando einfach neu startet sobald es sich beendet hat.  

Keine Kommentare:

Kommentar veröffentlichen