Acceso SSH desde dentro y fuera de una LAN utilizando el mismo comando de terminal

10

Tengo una Raspberry Pi (RPi) y estoy haciendo conexiones remotas con ssh. Me las arreglé para configurar ssh correctamente de modo que pueda acceder al RPi tanto desde una red de área local como desde Internet (usando un puerto específico que abrí en mi enrutador).

Asumiendo un nombre de usuario johny un RPi llamado raspi:

Acceso LAN interno

ssh [email protected]
ssh john@raspi
ssh raspi

Acceso LAN externo

ssh -p 1234 [email protected]
ssh -p 1234 12.345.67.89

Pero, ¿cómo puedo simplemente hacerlo ssh raspidesde fuera de mi LAN? ¿Hay alguna forma de configurar raspi para que apunte a dos direcciones IP, una en una LAN y otra en Internet?

Lo que básicamente quiero es acceder a mi RPi de una sola manera, sin importar si estoy en casa o en el trabajo.

Aeronaelius
fuente
Puede ejecutar un servidor DNS en su LAN local que responda a la solicitud del nombre "raspi" con la dirección IP de LAN local. Ahora, resolver ese mismo nombre en una dirección externa diferente requeriría que ese nombre se complete (dns dinámico) de tal manera que también se resuelva. Pero probablemente necesitará un nombre más largo que "raspi".
ChuckCottrill
Vea estas preguntas y respuestas: unix.stackexchange.com/questions/61655/…
slm

Respuestas:

7

Mirando más de cerca su pregunta, parece que está usando la misma computadora tanto dentro como fuera de la LAN. He revisado mi respuesta en consecuencia:

En su ~/.ssh/config, agregue:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Luego, puede hacerlo ssh raspi-wandesde fuera de la LAN, o ssh raspi-landesde el interior de la LAN sin preocuparse por los servidores DNS o editar /etc/hostspara todos los usuarios, o incluso sin tener que hacer nada como root. Si desea que el nombre se raspiresuelva de manera diferente dependiendo de dónde se encuentre, eso probablemente requerirá algo de magia de scripting de shell para detectar su red y actuar en consecuencia.

DopeGhoti
fuente
1
Gracias DopeGhoti, estoy muy cómodo con su solución para incluir un -wany -lanpostfix. Sin embargo, a mi ssh no le gustó el Usernamecampo (opción de configuración incorrecta). Está funcionando bien sin él.
Aeronaelius
2
Lo siento, la sintaxis correcta es User john, no UserName. Estoy corrigiendo mi respuesta para reflejar esto, y una vez que haya configurado su configuración, puede omitir el nombre de usuario desde la sshlínea de comandos.
DopeGhoti
5

Esto es perfectamente factible solo con la configuración ssh, sin tener que usar alias separados para lan y wan o crear ningún puerto adicional hacia adelante. (Pero, naturalmente, necesita alguna forma de detectar si está dentro de su lan o no)

En ~/.ssh/config, querrás agregar algo como esto:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

En lugar de am_i_outside_of_my_lan, querrá colocar un comando que determine si está dentro de su red doméstica o no, y regresa con un código de salida 0 si está fuera de ella, y algo más.

La hostcondición probablemente se explica por sí misma, pero execmerece una explicación: coincide solo cuando el comando dado regresa con el código de salida 0, es decir. No hay error.

En otras palabras, lo que hace es que la host raspiparte restringe esta regla a cuando intentas conectarte al host raspi, y la exec "am_i_outside_my_lan"restringe aún más para que solo se aplique cuando te estás conectando desde fuera de tu red doméstica. Entonces, dentro de su red doméstica ssh user@raspihace exactamente lo que normalmente haría, pero fuera de ella, la regla coincide y en su lugar hace el equivalente de ssh -p 1234 [email protected].

En cuanto a qué usar en lugar de am_i_outside_of_my_lan, eso depende completamente de su configuración. Sugiero colocar los comandos en un script separado en lugar de intentar escribirlo en línea, porque las citas parecen ser un poco difíciles de entender.

Personalmente, utilicé el siguiente script de Python para detectar si estoy dentro de mi propia red: (Dado que mi nombre de dominio se resuelve en una IP local dentro de mi propia red)

#! /usr/bin/env python
import socket, sys

sys.exit(socket.gethostbyname('mydomain.com').startswith('192.168.1.'))

Si no tiene una configuración similar, es posible que tenga que hacer otra cosa. (Por ejemplo, puede mirar el nombre de la red inalámbrica a la que está conectado, o incluso consultar algún servicio what-is-my-ip para obtener la ip externa de la red a la que está conectado)

Aleksi Torhamo
fuente
Esta es la respuesta correcta; Es muy triste que otros tengan más votos.
Jonathan Tomer
@JonathanTomer: Bueno, para ser justos, respondí esto 3 años después de que se le preguntó, mientras que las respuestas de mayor puntuación se publicaron en cuestión de horas, por lo que es solo un caso de "el pájaro madrugador consigue el gusano": P (también tengo para decir que me gusta bastante la variante específica de Ellis Hoag de esta solución general: usar arp es bastante inteligente y hace que la solución sea más genérica, ya que en el comando de detección de red no tiene que ajustarse para cada configuración de red)
Aleksi Torhamo
3

En el ordenador (el Connect- ing uno), se puede establecer un nombre de host para 12.345.67.89. Abra su /etc/hostsarchivo y configure una entrada DNS:

12.345.67.89    raspi

Luego, su máquina transformará "raspi" en "12.345.67.89" como parte de un proceso de resolución de DNS local. Si utiliza varias máquinas, el cambio debe realizarse en todas y cada una de ellas. El problema es que requiere acceso root para editar /etc/hosts, y es posible que no lo tenga en todas partes.

Si desea que "raspi" sea reconocido automáticamente desde cualquier lugar, entonces lo siento: no es posible. Esto requeriría el registro de "raspi" como nombre de dominio, lo que no puede suceder ya que "raspi" no tiene TLD y no dependería de ningún servidor raíz DNS. Sin embargo, puede registrar un nombre de dominio (digamos cfbaptista.me, y señalarlo a su dirección IP de WAN. Con algún reenvío de puertos, podrá acceder a su Raspberry Pi con:

ssh (you@)(raspi.)cfbaptista.me

(Aún así, eso es gastar dinero por casi nada ...)

En cuanto a la user@parte, depende de su nombre de inicio de sesión en las diferentes máquinas. Si tiene el mismo nombre en la máquina de conexión y en la remota , no es necesario especificarlo. De lo contrario, debe especificar quién es usted en la máquina remota .

John WH Smith
fuente
nota: como se menciona en la otra respuesta, puede crear alias de host en su configuración SSH, que por supuesto no requiere root.
strugee
En efecto ! Aquí hay un pequeño enlace: collectiveidea.com/blog/archives/2011/02/04/how-to-ssh-aliases
John WH Smith
0

Objetivo: ssh raspi debe funcionar dentro de la LAN y en la Internet pública.

Para hacer esto, debe asegurarse de que el nombre se resuelva en la IP interna de la LAN y en la IP pública desde el exterior.

Primero, debe obtener un nombre de dominio como raspi.yourdomain.com. Visite http://freedns.afraid.org/ para obtener dominios gratuitos para uso hobby. Apunte el dominio a su IP pública

Para la LAN, recomiendo ejecutar DNSMasq. El firmware abierto DD-WRT se integra estrechamente con DNSMasq, utilizándolo para DHCP y DNS. Solo tiene que indicarle su dominio de búsqueda ("yourdomain.com") y asignará automáticamente nombres DNS en función del nombre solicitado de cada cliente. Para que esto funcione, debe leer raspi's / etc / hostname raspi.

Una vez que esto esté configurado, raspi.yourdomain.com debería resolver la IP local en su LAN (solo asegúrese de estar usando el DNS local en todas sus máquinas).

Ahora, probablemente no desee exponer el puerto 22 a Internet público, ya que obtendrá un montón de tráfico sniffer. Por lo tanto, puede hacer que su enrutador exponga raspi: 22 como algún otro puerto, digamos 1234. Para usar el mismo puerto en redes públicas e internas, puede agregar una regla de redireccionamiento de puerto a raspi. En Linux:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1234 -j REDIRECT --to-port 22
sudo sh -c 'iptables-save > /etc/iptables/iptables.rules'

(cambie eth0 al nombre de su interfaz de red como se muestra con ip linko ifconfig, y 1234 a su puerto público)

Ahora puedes hacerlo ssh -p 1234 raspi.yourdomain.comdesde público y LAN.

Puede agregar una entrada a ~ / .ssh / config en su máquina cliente para acortar esto a solo ssh raspi, como lo menciona @DopeGhoti.

Si desea exponer puertos SSH de máquinas adicionales en la misma IP pública, simplemente repita el proceso con otro nombre DNS y puerto público. ¡Salud!

Eric Drechsel
fuente
0

Aquí hay una versión sucinta y funcional de la respuesta de Aleksi Torhamo usando curl para tomar su IP pública actual y luego verificar si coincide con la IP pública de su servidor (es decir, está en la misma red local).

En su ~/.ssh/configcomplemento

Match host raspi exec "[[ $(curl -s ipinfo.io/ip) == '12.345.67.89' ]]"
  User john
  HostName 192.168.2.7

Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]"
  User john
  HostName 12.345.67.89
  Port 1234
Alec Jacobson
fuente
Yo creo que ssh va a procesar todas las directivas que coinciden, en orden, así que en teoría debería ser capaz de hacer algo así Match host raspi / User john / HostName 192.168.2.7seguido de Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234y conseguir el mismo efecto con una sola curlinvocación, dejando que el == '12.345.67.89'caso sea asumido por el fracaso de la segunda Matchregla de exec.
FeRD
(Debería asegurarse de que todos los argumentos especificados en el primero Matchsean iguales o también especificados en el segundo, si especificó un no estándar Port xxxxen el primero Matchy desea utilizar el puerto estándar en el segundo Match, tendrías que anularlo explícitamente con un Port 22para que no continúe usando el puerto xxxx.)
FeRD
0

Suponiendo que su máquina tiene IP 192.168.1. * Cuando está conectada a su LAN, puede lograr esto con la siguiente configuración ~/.ssh/configpara que siempre pueda usar el mismo comando (solo ssh raspi) para conectarse:

Match Originalhost raspi Exec "ifconfig | grep 192\.168\.1\."
    HostName 192.168.1.2
    User john
    Port 22

Host raspi
    HostName 12.34.56.78
    User john
    Port 1234
Cvuorinen
fuente
0

Esta solución supone que su red doméstica tiene un solo enrutador, lo cual creo que es el caso común.

Añadir a tu ~/.ssh/config

Match host raspi exec "test $(arp 192.168.1.1 | awk '{print $4}') = ROUTER_MAC_ADDRESS"
        Hostname 192.168.2.7
        User john

Host raspi
        Hostname 12.345.67.89
        Port 1234
        User john
Ellis Hoag
fuente