GNU/Linux >> Tutoriels Linux >  >> Linux

Information/assistance requise sur le tunnel SSH inversé (conventions de dénomination, etc.) ?

J'ai plusieurs raspberry pi exécutant Arch Linux (pas d'interface graphique) auxquels j'ai besoin d'accéder. Ces pi sont derrière des pare-feu dans chaque emplacement unique. Actuellement, j'utilise openvpn pour me connecter à ceux-ci, mais les coûts de ce système sont élevés par licence. J'utilise le serveur d'accès d'eux.

En conséquence, j'essaie de concevoir et de configurer un système qui me permet de me connecter à mon serveur VPN (vps) et d'exécuter une commande pour rechercher un nom spécifique (OfficeDevice1991) tel que :customcommandsearch "OfficeDevice1991" puis il renvoie ensuite l'adresse IP de la machine ou quelque chose que je peux utiliser pour SSH avec. Je recherche également la possibilité d'exécuter une commande pour répertorier tous les appareils connectés actifs. Il répertorie l'adresse IP, le nom et peut-être depuis combien de temps il est actif.

Pour cet objectif, j'ai bien sûr besoin de créer quelque chose qui inclut le nom de l'appareil (dans ce cas OfficeDevice1991) et ensuite ce pi pourra se connecter à mon serveur public vps. À partir du serveur public, je peux me connecter et effectuer une recherche sur tous les appareils qui y sont connectés et renvoyer les informations requises pour ssh.

J'ai étudié le SSH inversé et jusqu'à présent, j'ai connecté l'un de mes pi de test et accessible depuis mon vps en utilisant les commandes suivantes :

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

Cela fonctionne très bien, mais en utilisant cette méthode, si je devais l'implémenter, je rencontrerais quelques problèmes :

  1. Je devrais configurer des ports inutilisés uniques
  2. Un moyen de garder ces ports/tunnels ouverts
  3. Je dois trouver un système pour identifier chaque appareil. Je peux connecter chaque port à un nom comme un fichier texte localement ? Il serait avantageux de pouvoir l'inclure dans la configuration ssh de chaque appareil si possible. Je devrais quand même m'assurer que les ports que j'utilise ne sont pas utilisés par d'autres programmes ou par un appareil déjà présent.

Ce que je ne veux pas avoir à faire

  1. Vérifiez quels ports sont libres d'utiliser pour chaque RPI

  2. Doit modifier manuellement .ssh/config pour ajouter un nom pour représenter chaque port attribué à RPI de la partie 1 ci-dessus.

J'écris ceci pour obtenir des informations / de l'aide sur ce qu'il faut faire pour atteindre mon objectif.

Quelqu'un pourrait-il me fournir une solution appropriée ?

Réponse acceptée :

Voici une solution utilisant OpenSSH>=6.7 + socat :

  1. OpenSSH>=6.7 peut utiliser le transfert de socket de domaine Unix

    Cela signifie que le point de terminaison du tunnel inverse sera un socket d'écoute UNIX au lieu d'un socket d'écoute TCP traditionnel. Vous pouvez alors gérer plus facilement la flottille de RPI avec un schéma de nommage simple :le nom du socket sera le nom choisi (et fixe) du RPI, comme OfficeDevice1991 . Il pourrait même s'agir d'une propriété unique du RPI tant qu'il s'agit d'un nom de fichier valide (puisque les noms de socket unix adhèrent aux conventions de nom de fichier). Par exemple son hostname, l'adresse MAC de sa carte ethernet ou wifi…

    SSH peut gérer les sockets Unix pour les tunnels, pas pour se connecter. Il aura besoin de l'aide d'un ProxyCommand pour pouvoir travailler en tant que client unix-socket. socat peut gérer de nombreux types de connexions, y compris les sockets unix.

    MISE À JOUR :
    Il y a aussi un problème spécifique à gérer :le fichier de socket unix n'est pas supprimé lors d'une sortie propre, et il n'aurait pas été supprimé de toute façon, par exemple après un crash. Cela nécessite l'option StreamLocalBindUnlink=yes . Je n'ai pas trouvé initialement que, comme son nom l'indique peut-être, cette option doit être définie sur le nœud créant le socket unix. Donc, à la fin, il est défini sur le client avec un transfert local (-L ) ou bien sur le serveur (dans sshd_config ) avec un renvoi à distance (-R ). OP l'a trouvé là-bas. Cette solution utilise un renvoi à distance.

    Paramétrage sur VPS :

    mkdir /rpi-access
    

    (en tant que root) modifiez le sshd_config fichier (/etc/ssh/sshd_config ). Il nécessite cette option supplémentaire :

    StreamLocalBindUnlink yes
    

    Selon les options par défaut, il peut également nécessiter AllowStreamLocalForwarding yes

    UPDATE2 :
    Également défini dans sshd_config les paramètres ClientAliveInterval et ClientAliveCountMax , permettant ainsi de détecter une déconnexion dans un délai raisonnable, par exemple :

    ClientAliveInterval 300
    ClientAliveCountMax 2
    

    Les connexions ssh obsolètes devraient alors être détectées plus tôt sur le VPS (~10mn avec l'exemple), et le processus sshd correspondant se terminera alors.

    Utilisation sur RPI :

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

    Dans un fichier de configuration, cela ressemblerait à ceci :

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

    En le répétant à nouveau :le StreamLocalBindUnlink yes défini sur sshd côté VPS est importante :la socket qui vient d'être créée n'est pas supprimée, même lors d'une sortie normale. Cette option garantit que la prise est retirée si elle existe avant utilisation, permettant ainsi d'être réutilisée pour d'autres reconnexions. Cela signifie également qu'on ne peut pas considérer la simple présence de la prise comme signifiant que le RPI est connecté (mais voir plus tard).

    Maintenant cela permet de faire sur VPS :

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

    En tant que fichier de configuration, en considérant par exemple que les RPI ont tous un nom commençant par OfficeDevice :

    Host OfficeDevice*
        User rpiuseraccount
        ProxyCommand socat UNIX:/rpi-access/%h -
    
  2. Pour conserver le lien, il suffit d'utiliser une boucle

    Le RPI peut exécuter une boucle reconnectant ssh au VPS chaque fois que les connexions se terminent. Pour cela, il ne doit pas utiliser le mode arrière-plan (pas de -f ). Un mécanisme keepalive devrait également être utilisé. TCPKeepAlive (niveau système) ou ServerAliveInterval (niveau application) sont disponibles. Je pense que TCPKeepAlive n'est utile que sur le serveur (côté recevant la connexion), alors utilisons plutôt ServerAliveInterval.

    Sa valeur (ainsi que ServerAliveCountMax) est probablement à adapter en fonction de différents critères :un firewall abandonnant les connexions inactives après un certain temps, le délai de récupération souhaité, ne générant pas de trafic inutile, … disons 300s ici.

    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
    

    Même si le côté distant n'a pas encore détecté l'échec de connectivité précédent et que l'ancienne connexion ssh est toujours en cours d'exécution, StreamLocalBindUnlink yes rafraîchira de toute façon avec force le socket unix avec la nouvelle connexion.

  3. il est déjà géré par 1.

    Il n'y a pas de customcommandsearch avait besoin. Avec les bons paramètres définis dans 1. en utilisant simplement ssh OfficeDevice1991 se connectera à OfficeDevice1991.

    Si besoin sur le VPS, en tant que root utilisateur uniquement, cette commande :

    fuser /rpi-access/*
    

    peut montrer quels RPI sont actuellement connectés (sauf bien sûr ceux qui ont récemment perdu la connexion avant la détection). Il n'affichera pas les fichiers de socket Unix obsolètes car aucun processus ne leur est lié.

Connexe :Comment passer le contenu d'un fichier en tant que paramètre de ligne de commande ?
Linux
  1. Existe-t-il des conventions de nommage pour les variables dans les scripts shell ?

  2. Ssh - Bureau à distance sur tunnel inverse Ssh pour remplacer Teamviewer ?

  3. Impossible d'exécuter des applications X via SSH sous Linux

  4. SSH avec des clés autorisées à un système Ubuntu avec un répertoire personnel crypté ?

  5. aucune information de version disponible (requise par /usr/bin/ssh)

Tunnellisation et proxy SSH

Ssh – Comment fonctionne le tunneling Ssh inversé ?

ssh accepte toujours l'authentification par mot de passe malgré sa configuration pour l'authentification par clé publique uniquement (ce qui fonctionne !)

SSH lent au démarrage de la session

accès au tunneling ssh uniquement

SSH - Comment inclure la commande -t dans le fichier ~/.ssh/config