GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Erforderliche Informationen/Unterstützung für Reverse-SSH-Tunneling (Namenskonventionen usw.)?

Ich habe mehrere Himbeer-Pis, auf denen Arch Linux (keine GUI) ausgeführt wird, auf die ich zugreifen muss. Diese Pis befinden sich hinter Firewalls an jedem einzelnen Standort. Derzeit verwende ich openvpn, um eine Verbindung zu diesen herzustellen, aber die Kosten für dieses System sind pro Lizenz hoch. Ich benutze den Zugangsserver von ihnen.

Infolgedessen versuche ich, ein System zu entwerfen und einzurichten, das es mir ermöglicht, mich bei meinem VPN-Server (vps) anzumelden und einen Befehl auszuführen, um nach einem bestimmten Namen (OfficeDevice1991) zu suchen, z. B.:customcommandsearch "OfficeDevice1991" und dann gibt es die IP-Adresse der Maschine oder etwas zurück, mit dem ich SSH verbinden kann. Ich suche auch nach der Möglichkeit, einen Befehl auszuführen, um jedes aktive verbundene Gerät aufzulisten. Es listet die IP, den Namen und vielleicht wie lange es aktiv ist.

Für dieses Ziel muss ich natürlich etwas erstellen, das den Namen des Geräts enthält (in diesem Fall OfficeDevice1991), und dann kann sich dieses Pi in meinen öffentlichen vps-Server einklinken. Vom öffentlichen Server aus kann ich mich anmelden und jedes damit verbundene Gerät durchsuchen und Informationen zurückgeben, die für die SSH-Verbindung erforderlich sind.

Ich habe mich mit Reverse-SSH beschäftigt und bisher habe ich mit den folgenden Befehlen einen meiner Test-Pis verbunden und von meinem vps aus darauf zugegriffen:

PI:

ssh -fN -R 12345:localhost:22 -i /publickeyfile [email protected] //Pi's command to connect to vpn

VPS:

ssh -p 12345 [email protected] //command for vpn to connect to pi

Das funktioniert großartig, aber wenn ich diese Methode verwenden würde, würde ich auf ein paar Probleme stoßen:

  1. Ich müsste eindeutige unbenutzte Ports einrichten
  2. Eine Möglichkeit, diese Ports/Tunnel offen zu halten
  3. Ich muss mir ein System einfallen lassen, um jedes Gerät zu identifizieren. Ich kann jeden Port mit einem Namen wie eine Textdatei lokal einloggen? Es wäre von Vorteil, dies nach Möglichkeit in das SSH-Setup für jedes Gerät aufnehmen zu können. Ich müsste trotzdem sicherstellen, dass die von mir verwendeten Ports nicht von anderen Programmen oder Geräten verwendet werden, die bereits vorhanden sind.

Was ich nicht tun möchte

  1. Überprüfen Sie, welche Ports für jedes RPI kostenlos verwendet werden können

  2. Muss .ssh/config manuell bearbeiten um einen Namen hinzuzufügen, der jeden Port repräsentiert, der dem RPI aus Teil 1 oben zugewiesen wurde.

Ich schreibe dies zur Information/Unterstützung, was ich für mein Ziel tun kann.

Kann mir jemand eine passende Lösung anbieten?

Akzeptierte Antwort:

Hier ist eine Lösung mit OpenSSH>=6.7 + socat:

  1. OpenSSH>=6.7 kann die Unix-Domain-Socket-Weiterleitung verwenden

    Das bedeutet, dass der Reverse-Tunnel-Endpunkt ein UNIX-Listening-Socket anstelle eines herkömmlichen TCP-Listening-Sockets ist. Sie können dann die Flottille von RPIs mit einem einfachen Benennungsschema einfacher verwalten:Der Name des Sockets ist der gewählte (und feste) Name des RPI, wie OfficeDevice1991 . Es könnte sogar eine eindeutige Eigenschaft des RPI sein, solange es sich um einen gültigen Dateinamen handelt (da Unix-Socket-Namen Dateinamenkonventionen einhalten). Zum Beispiel seinen Hostnamen, die MAC-Adresse seiner Ethernet- oder WLAN-Karte …

    SSH kann Unix-Sockets für Tunnel handhaben, nicht um sich selbst zu verbinden. Es benötigt die Hilfe eines ProxyCommand um als Unix-Socket-Client arbeiten zu können. socat kann mit vielen Arten von Verbindungen umgehen, einschließlich Unix-Sockets.

    UPDATE:
    Es gibt auch ein spezielles Problem zu behandeln:Die Unix-Socket-Datei wird beim sauberen Beenden nicht gelöscht und wäre zum Beispiel nach einem Absturz sowieso nicht gelöscht worden. Dazu ist die Option StreamLocalBindUnlink=yes erforderlich . Ich fand anfangs nicht, dass diese Option, wie der Name vielleicht andeutet, auf dem Knoten gesetzt werden muss, der den Unix-Socket erstellt. Am Ende wird es also auf dem Client mit einer lokalen Weiterleitung (-L ) sonst auf dem Server (in sshd_config ) mit einer Remote-Weiterleitung (-R ). OP hat es dort gefunden. Diese Lösung verwendet eine Remote-Weiterleitung.

    Konfiguration auf VPS:

    mkdir /rpi-access
    

    (als root) bearbeiten Sie die sshd_config Datei (/etc/ssh/sshd_config ). Es erfordert diese zusätzliche Option:

    StreamLocalBindUnlink yes
    

    Abhängig von den Standardoptionen ist möglicherweise auch AllowStreamLocalForwarding yes erforderlich

    UPDATE2:
    Wird auch in sshd_config gesetzt die Parameter ClientAliveInterval und ClientAliveCountMax , wodurch ein Verbindungsabbruch in angemessener Zeit erkannt werden kann, z. B.:

    ClientAliveInterval 300
    ClientAliveCountMax 2
    

    Veraltete ssh-Verbindungen sollten dann auf dem VPS früher erkannt werden (~10 Minuten im Beispiel) und der entsprechende sshd-Prozess wird dann beendet.

    Nutzung auf RPI:

    ssh -fN -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile [email protected]
    

    In einer Konfigurationsdatei wäre dies etwa so:

    Host ip
    User useraccount
    RemoteForward /rpi-access/OfficeDevice1991:localhost:22
    IdentityFile /privatekeyfile
    

    Um es noch einmal zu wiederholen:StreamLocalBindUnlink yes eingestellt auf sshd auf VPS-Seite Option ist wichtig:Der gerade erstellte Socket wird nicht entfernt, auch nicht beim normalen Beenden. Diese Option stellt sicher, dass der Sockel entfernt wird, falls er vor der Verwendung vorhanden ist, und somit für weitere Neuverbindungen wiederverwendet werden kann. Das bedeutet auch, dass man das bloße Vorhandensein des Sockets nicht als Zeichen dafür ansehen kann, dass das RPI verbunden ist (aber siehe später).

    Jetzt erlaubt dies auf VPS:

    ssh -o 'ProxyCommand=socat UNIX:/rpi-access/%h -' [email protected]
    

    Als Konfigurationsdatei, wenn man bedenkt, dass RPIs beispielsweise alle einen Namen haben, der mit OfficeDevice beginnt :

    Host OfficeDevice*
        User rpiuseraccount
        ProxyCommand socat UNIX:/rpi-access/%h -
    
  2. Um den Link beizubehalten, verwenden Sie einfach eine Schleife

    Das RPI kann eine Schleife ausführen, die ssh immer dann wieder mit dem VPS verbindet, wenn die Verbindungen beendet werden. Dazu darf es nicht den Hintergrundmodus verwenden (kein -f ). Es sollte auch ein Keepalive-Mechanismus verwendet werden. TCPKeepAlive (Systemebene) oder ServerAliveInterval (Anwendungsebene) sind verfügbar. Ich denke, TCPKeepAlive ist nur auf dem Server (der Seite, die die Verbindung empfängt) nützlich, also verwenden wir lieber ServerAliveInterval.

    Sein Wert (wie auch ServerAliveCountMax) sollte wahrscheinlich in Abhängigkeit von verschiedenen Kriterien angepasst werden:eine Firewall, die inaktive Verbindungen nach einer bestimmten Zeit verwirft, die gewünschte Wiederherstellungsverzögerung, keinen nutzlosen Verkehr erzeugen, … sagen wir hier 300s.

    OfficeDevice1991 RPI:

    #!/bin/sh
    while : ; do
        ssh  -N -o ConnectTimeout=30 -o ServerAliveInterval=300 -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile [email protected]
        sleep 5 # avoid flood/DDoS in case of really unexpected issues
    done
    

    Auch wenn die Remote-Seite den vorherigen Verbindungsfehler noch nicht erkannt hat und die alte ssh-Verbindung noch einige Zeit läuft, StreamLocalBindUnlink yes wird den Unix-Socket sowieso zwangsweise auf die neue Verbindung aktualisieren.

  3. es wird bereits von 1 behandelt.

    Es gibt keine customcommandsearch erforderlich. Mit den richtigen Einstellungen in 1. einfach mit ssh OfficeDevice1991 verbindet sich mit OfficeDevice1991.

    Bei Bedarf auf dem VPS als root Nur Benutzer, dieser Befehl:

    fuser /rpi-access/*
    

    kann anzeigen, welche RPIs derzeit verbunden sind (natürlich mit Ausnahme derjenigen, die kürzlich die Verbindung vor der Erkennung verloren haben). Die veralteten Unix-Socket-Dateien werden nicht angezeigt, da kein Prozess an sie gebunden ist.

Verwandte:Wie übergebe ich den Inhalt einer Datei als Befehlszeilenparameter?
Linux
  1. So verwenden Sie SSH-Tunneling für den Zugriff auf eingeschränkte Server

  2. So richten Sie SSH-Tunneling ein

  3. Gibt es Namenskonventionen für Variablen in Shell-Skripten?

  4. Ssh – Remote Desktop über Ssh Reverse Tunnel als Ersatz für Teamviewer?

  5. Wie finde ich die erforderlichen Informationen beim Menschen?

SSH-Tunneling und Proxying

Ssh – Wie funktioniert Reverse-SSH-Tunneling?

keine Versionsinformationen verfügbar (wird von /usr/bin/ssh benötigt)

Zugriff nur über SSH-Tunneling

SSH - So fügen Sie den Befehl -t in die Datei ~/.ssh/config ein

SSH-Verbindung über einen Reverse (Remote) SSH-Tunnel