Acesso SSH de dentro e de fora de uma LAN usando o mesmo comando do terminal


10

Eu tenho um Raspberry Pi (RPi) e estou fazendo conexões remotas usando o ssh. Consegui configurar o ssh corretamente para poder acessar o RPi a partir de uma rede local e da Internet (usando uma porta específica que abri no meu roteador).

Supondo um nome de usuário johne um RPi chamado raspi:

Acesso à LAN interna

ssh john@192.168.2.7
ssh john@raspi
ssh raspi

Acesso à LAN externa

ssh -p 1234 john@12.345.67.89
ssh -p 1234 12.345.67.89

Mas como posso simplesmente fazer ssh raspifora da minha LAN? Existe uma maneira de configurar o raspi para apontar para dois endereços IP, um em uma LAN e outro na Internet?

O que eu basicamente quero é acessar meu RPi de uma única maneira, independentemente de eu estar em casa ou no trabalho.


Você pode executar um servidor DNS na sua LAN local que responda à solicitação do nome "raspi" com o endereço IP da LAN local. Agora, resolver esse mesmo nome para um endereço externo diferente exigiria que o nome fosse preenchido (dns dinâmico) de forma que ele também fosse resolvido. Mas você provavelmente precisará de um nome mais longo que "raspi".
ChuckCottrill

Veja estas perguntas e respostas: unix.stackexchange.com/questions/61655/…
slm

Respostas:


7

Olhando mais de perto a sua pergunta, parece que você está usando o mesmo computador dentro e fora da LAN. Revisei minha resposta de acordo:

No seu ~/.ssh/config, adicione:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Em seguida, você pode ssh raspi-wansair de fora da LAN ou ssh raspi-lande dentro da LAN sem mexer nos servidores DNS ou editar /etc/hostspara todos os usuários, ou mesmo precisar fazer algo como root. Se você deseja que o nome raspiseja resolvido de maneira diferente, dependendo de onde você estiver, isso provavelmente exigirá alguma mágica de script de shell para detectar sua rede e agir de acordo.


1
Obrigado DopeGhoti, estou muito confortável com sua solução para incluir um -wane um -lanpostfix. No entanto, meu ssh não gostou do Usernamecampo (opção de configuração incorreta). Está funcionando bem sem ele.
Aeronaelius

2
Sinto muito, a sintaxe correta é User john, não UserName. Estou corrigindo minha resposta para refletir isso e, depois de definir sua configuração, você pode omitir o nome de usuário na sshlinha de comando.
DopeGhoti

5

Isso é perfeitamente possível com apenas a configuração ssh, sem a necessidade de usar aliases separados para lan e wan ou criar qualquer porta extra para a frente. (Naturalmente, você precisa de alguma maneira de detectar se está dentro da sua LAN ou não)

Em ~/.ssh/config, você deseja adicionar algo como isto:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

No lugar de am_i_outside_of_my_lanvocê deseja colocar um comando que determine se você está dentro da sua rede doméstica ou não e retorna com o código de saída 0 se você estiver fora dela, e algo mais.

A hostcondição é provavelmente auto-explicativa, mas a execcondição merece alguma explicação: Combina apenas quando o comando fornecido retorna com o código de saída 0, ou seja. sem erro.

Portanto, em outras palavras, o que isso faz é a host raspiparte que restringe essa regra quando você tenta se conectar ao raspi do host e a exec "am_i_outside_my_lan"restringe ainda mais, de forma que ela só se aplica quando você está se conectando de fora da sua rede doméstica. Portanto, dentro da sua rede doméstica ssh user@raspifaz exatamente o que normalmente faria, mas fora dela a regra corresponde e, em vez disso, o equivalente a ssh -p 1234 user@12.345.67.89.

Quanto ao que usar no lugar am_i_outside_of_my_lan, isso depende inteiramente da sua configuração. Eu sugiro colocar os comandos em um script separado, em vez de tentar escrevê-lo em linha, porque a citação parece um pouco difícil de acertar.

Pessoalmente, usei o seguinte script Python para detectar se estou dentro da minha própria rede: (Como meu nome de domínio é resolvido para um IP local dentro da minha própria rede)

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

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

Se você não tiver uma configuração semelhante, talvez precise fazer outra coisa. (Por exemplo, você pode procurar o nome da rede sem fio à qual está conectado ou até consultar algum serviço what-is-my-ip para obter o ip externo da rede à qual está conectado)


Essa é a resposta correta; é muito triste que outros tenham mais votos.
Jonathan Tomer

@ JonathanTomer: Bem, para ser justo, eu respondi isso três anos depois que foi perguntado, enquanto as respostas com maior pontuação foram publicadas em poucas horas, então é apenas um caso de "o madrugador pega o verme": P (eu também tenho dizer que eu gosto bastante da variante específica dessa solução geral de Ellis Hoag - usar arp é bastante inteligente e torna a solução mais genérica, pois no comando de detecção de rede não é necessário ajustar todas as configurações de rede)
Aleksi Torhamo

3

No seu computador (a conectar- ing um), você pode definir um nome de host para 12.345.67.89. Abra seu /etc/hostsarquivo e defina uma entrada DNS:

12.345.67.89    raspi

Sua máquina transformará "raspi" em "12.345.67.89" como parte de um processo de resolução de DNS local. Se você usar várias máquinas, a alteração deverá ser feita em cada uma delas. O problema é: ele requer acesso root para editar /etc/hosts, e talvez você não o tenha em todos os lugares.

Se você deseja que "raspi" seja reconhecido automaticamente de qualquer lugar, lamento: não é possível. Isso exigiria o registro de "raspi" como um nome de domínio, o que não pode acontecer porque "raspi" não possui TLD e não dependeria de nenhum servidor raiz DNS. No entanto, você pode registrar um nome de domínio (digamos cfbaptista.me, e apontar para o seu endereço IP da WAN. Com algum encaminhamento de porta, você poderá acessar o seu Raspberry Pi com:

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

(ainda assim, está gastando dinheiro por quase nada ...)

Em relação à user@peça, isso depende do seu nome de login nas diferentes máquinas. Se você tiver o mesmo nome na máquina de conexão e na remota , não será necessário especificar. Caso contrário, você precisa especificar quem você é na máquina remota .


nota: como mencionado na outra resposta, você pode criar aliases de host na sua configuração SSH, o que obviamente não requer raiz.
strugee


0

Objetivo: ssh raspi trabalhar dentro da LAN e na Internet pública.

Para fazer isso, você precisa garantir que o nome seja resolvido para o IP interno na LAN e o IP público de fora.

Primeiro, você deve obter um nome de domínio como raspi.yourdomain.com. Confira http://freedns.afraid.org/ para domínios gratuitos para uso em hobby. Aponte o domínio para seu IP público

Para a LAN, recomendo executar o DNSMasq. O firmware DD-WRT aberto integra-se firmemente ao DNSMasq, usando-o para DHCP e DNS. Você apenas precisa informar seu domínio de pesquisa ("seudominio.com") e ele atribuirá automaticamente nomes DNS com base no nome solicitado de cada cliente. Para fazer isso funcionar, o / etc / hostname do raspi deve ser lido raspi.

Depois que isso for configurado, raspi.seudominio.com deve resolver o IP local na sua LAN (apenas verifique se você está usando o DNS local em todas as suas máquinas).

Agora, você provavelmente não deseja expor a porta 22 à Internet pública, porque obterá uma tonelada de tráfego sniffer. Portanto, seu roteador pode expor raspi: 22 como outra porta, por exemplo, 1234. Para usar a mesma porta em redes públicas e internas, você pode adicionar uma regra de redirecionamento de porta ao raspi. No 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'

(altere eth0 para o nome da sua interface de rede, como mostrado por ip linkor ifconfig, e 1234 para sua porta pública)

Agora você pode ssh -p 1234 raspi.yourdomain.comdo público e da LAN.

Você pode adicionar uma entrada em ~ / .ssh / config em sua máquina cliente para encurtar isso para apenas ssh raspi, como mencionado por @DopeGhoti.

Se você deseja expor portas SSH de máquinas adicionais no mesmo IP público, basta repetir o processo com outro nome DNS e porta pública. Felicidades!


0

Aqui está uma versão sucinta e funcional da resposta de Aleksi Torhamo usando curl para obter seu IP público atual e, em seguida, verificando se ele corresponde ao IP público do servidor (ou seja, você está na mesma rede local).

No seu ~/.ssh/configadd

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

Eu acredito que ssh irá processar todas as directivas correspondentes, em ordem, portanto, em teoria você deve ser capaz de fazer algo parecido Match host raspi / User john / HostName 192.168.2.7seguido por Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234e obter o mesmo efeito com apenas uma curlinvocação, deixando o == '12.345.67.89'caso ser assumida pelo fracasso da segunda Matchregra de exec.
FeRD 3/0318

(Você apenas precisa garantir que todos os argumentos especificados no primeiro Matchsejam iguais ou também especificados no segundo - se você especificou um não padrão Port xxxxno primeiro Matche desejou usar a porta padrão no segundo Match, você teria que substituí-lo explicitamente para trás com um Port 22modo que não continuar a porta de uso xxxx).
Ferd

0

Supondo que sua máquina tenha IP 192.168.1. * Quando conectado à sua LAN, você pode fazer isso com a seguinte configuração, ~/.ssh/configpara poder sempre usar o mesmo comando (apenas ssh raspi) para conectar:

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

0

Esta solução pressupõe que sua rede doméstica tenha um único roteador, que eu acredito ser o caso comum.

Adicione ao seu ~/.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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.