GNU/Linux >> Tutoriales Linux >  >> Linux

¿Se requiere información/asistencia sobre túneles Ssh inversos (convenciones de nomenclatura, etc.)?

Tengo varios raspberry pi que ejecutan Arch Linux (sin GUI) a los que necesito acceder. Estos pi están detrás de los cortafuegos en cada ubicación única. Actualmente uso openvpn para conectarme a estos pero los costos de ese sistema son caros por licencia. Yo uso el servidor de acceso de ellos.

Como resultado, estoy tratando de diseñar y configurar un sistema que me permita iniciar sesión en mi servidor VPN (vps) y ejecutar un comando para buscar un nombre específico (OfficeDevice1991) como:customcommandsearch "OfficeDevice1991" y luego devuelve la dirección IP de la máquina o algo que pueda usar para SSH. También estoy buscando la capacidad de ejecutar un comando para enumerar todos los dispositivos conectados activos. Muestra la IP, el nombre y quizás cuánto tiempo ha estado activo.

Para este objetivo, por supuesto, necesito crear algo que incluya el nombre del dispositivo (en este caso, OfficeDevice1991) y luego ese pi podrá conectarse a mi servidor público vps. Desde el servidor público, puedo iniciar sesión y hacer una búsqueda de todos los dispositivos conectados a él y devolver la información necesaria para acceder a ssh.

He estado investigando SSH inverso y hasta ahora tengo uno de mis pi de prueba conectado y accesible desde mi vps usando los siguientes comandos:

IP:

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

Esto funciona muy bien, pero al usar este método, si tuviera que implementarlo, me encontraría con algunos problemas:

  1. Tendría que configurar puertos únicos no utilizados
  2. Alguna forma de mantener abiertos estos puertos/túneles
  3. Necesito idear un sistema para identificar cada dispositivo. ¿Puedo registrar cada puerto con un nombre como un archivo de texto localmente? Sería beneficioso poder incluir eso en la configuración de ssh para cada dispositivo si es posible. Todavía tendría que asegurarme de que los puertos que uso no estén siendo utilizados por ningún otro programa o dispositivo que ya esté allí.

Lo que no quiero tener que hacer

  1. Compruebe qué puertos son de uso gratuito para cada RPI

  2. Tiene que editar manualmente .ssh/config para agregar un nombre para representar cada puerto asignado a RPI de la parte 1 anterior.

Escribo esto para obtener información/asistencia sobre qué hacer para lograr mi objetivo.

¿Alguien podría proporcionarme una solución adecuada?

Respuesta aceptada:

Aquí hay una solución usando OpenSSH>=6.7 + socat:

  1. OpenSSH>=6.7 puede usar el reenvío de sockets de dominio Unix

    Eso significa que el punto final del túnel inverso será un socket de escucha UNIX en lugar de un socket de escucha TCP tradicional. Luego puede administrar más fácilmente la flotilla de RPI con un sencillo esquema de nombres:el nombre del socket será el nombre elegido (y fijo) del RPI, como OfficeDevice1991 . Incluso podría ser una propiedad única del RPI siempre que sea un nombre de archivo válido (ya que los nombres de socket de Unix se adhieren a las convenciones de nombres de archivo). Por ejemplo su nombre de host, la dirección MAC de su tarjeta ethernet o wifi…

    SSH puede manejar sockets Unix para túneles, no para conectarse. Necesitará la ayuda de un ProxyCommand para poder trabajar como cliente de unix-socket. socat puede manejar muchos tipos de conexiones, incluidos los sockets de Unix.

    ACTUALIZACIÓN:
    También hay un problema específico que manejar:el archivo de socket de Unix no se elimina al salir limpio, ni se habría eliminado de todos modos, por ejemplo, después de un bloqueo. Esto requiere la opción StreamLocalBindUnlink=yes . Inicialmente no encontré que, como su nombre lo indica, esta opción debe establecerse en el nodo que crea el socket de Unix. Entonces, al final, se configura en el cliente con un reenvío local (-L ) o bien en el servidor (en sshd_config ) con un reenvío remoto (-R ). OP lo encontró allí. Esta solución utiliza un reenvío remoto.

    Configuración en VPS:

    mkdir /rpi-access
    

    (como root) edite el sshd_config archivo (/etc/ssh/sshd_config ). Requiere esta opción adicional:

    StreamLocalBindUnlink yes
    

    Dependiendo de las opciones predeterminadas, también podría requerir AllowStreamLocalForwarding yes

    ACTUALIZACIÓN 2:
    También configurado en sshd_config los parámetros ClientAliveInterval y ClientAliveCountMax , permitiendo así detectar una desconexión en un tiempo razonable, por ejemplo:

    ClientAliveInterval 300
    ClientAliveCountMax 2
    

    Las conexiones ssh obsoletas deberían detectarse antes en el VPS (~10 minutos con el ejemplo), y el proceso sshd correspondiente se cerrará.

    Uso en RPI:

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

    En un archivo de configuración, esto sería similar a esto:

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

    Repitiéndolo de nuevo:el StreamLocalBindUnlink yes establecido en sshd en el lado VPS La opción es importante:el socket recién creado no se elimina, incluso al salir normalmente. Esta opción garantiza que el enchufe se elimine si existe antes de su uso, lo que permite su reutilización para futuras reconexiones. Esto también significa que uno no puede considerar que la mera presencia del zócalo significa que el RPI está conectado (pero vea más adelante).

    Ahora esto permite hacer en VPS:

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

    Como archivo de configuración, teniendo en cuenta, por ejemplo, que los RPI tienen un nombre que comienza con OfficeDevice :

    Host OfficeDevice*
        User rpiuseraccount
        ProxyCommand socat UNIX:/rpi-access/%h -
    
  2. Para mantener el enlace, solo use un bucle

    El RPI puede ejecutar un bucle que vuelve a conectar ssh al VPS cada vez que finaliza la conexión. Para esto no debe usar el modo de fondo (sin -f ). También se debe utilizar un mecanismo de mantenimiento. Están disponibles TCPKeepAlive (nivel de sistema) o ServerAliveInterval (nivel de aplicación). Creo que TCPKeepAlive es útil solo en el servidor (el lado que recibe la conexión), así que mejor usemos ServerAliveInterval.

    Su valor (así como ServerAliveCountMax) probablemente debería adaptarse según varios criterios:un cortafuegos que elimina las conexiones inactivas después de cierto tiempo, el retraso de recuperación deseado, no genera tráfico inútil,... digamos 300 aquí.

    Dispositivo de oficina1991 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
    

    Incluso si el lado remoto aún no detectó la falla de conectividad anterior, y durante un tiempo más la antigua conexión ssh aún se está ejecutando, StreamLocalBindUnlink yes de todos modos actualizará forzosamente el socket de Unix a la nueva conexión.

  3. ya está manejado por 1.

    No hay customcommandsearch necesario. Con la configuración correcta establecida en 1. simplemente usando ssh OfficeDevice1991 se conectará a OfficeDevice1991.

    Si es necesario en el VPS, como root solo usuario, este comando:

    fuser /rpi-access/*
    

    puede mostrar qué RPI están conectados actualmente (por supuesto, excepto aquellos que perdieron la conexión recientemente antes de la detección). No mostrará los archivos de socket de Unix obsoletos porque no hay ningún proceso vinculado a ellos.

Relacionado:¿Cómo pasar el contenido de un archivo como un parámetro de línea de comando?
Linux
  1. ¿Existen convenciones de nomenclatura para las variables en los scripts de Shell?

  2. Ssh:¿Escritorio remoto a través del túnel inverso Ssh para reemplazar a Teamviewer?

  3. Cómo configurar el túnel SSH inverso en Linux

  4. No se pueden ejecutar aplicaciones X a través de SSH en Linux

  5. ¿SSH con Authorized_keys a un sistema Ubuntu con homedir encriptado?

Cómo usar túneles SSH para acceder a servidores restringidos

Cómo configurar túneles SSH

Tunelización y proxy SSH

Ssh:¿cómo funciona el túnel Ssh inverso?

ssh todavía acepta la autenticación de contraseña a pesar de estar configurado para autenticación de clave pública únicamente (¡lo cual funciona!)

Conexión SSH a través de un túnel SSH inverso (remoto)