Accesso SSH dall'interno e dall'esterno di una LAN usando lo stesso comando terminale


10

Ho un Raspberry Pi (RPi) e sto effettuando connessioni remote con ssh. Sono riuscito a configurare ssh correttamente in modo da poter accedere a RPi sia da una rete locale che da Internet (usando una porta specifica che ho aperto sul mio router).

Supponendo un nome utente johne un RPi chiamato raspi:

Accesso LAN interno

ssh john@192.168.2.7
ssh john@raspi
ssh raspi

Accesso LAN esterno

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

Ma come posso fare semplicemente ssh raspidall'esterno della mia LAN ?. Esiste un modo per configurare raspi in modo che punti a due indirizzi IP, uno in una LAN e uno su Internet?

Quello che voglio sostanzialmente è accedere al mio RPi in un solo modo, non importa se sono a casa o al lavoro.


È possibile eseguire un server DNS sulla propria LAN locale che risponde alla richiesta del nome "raspi" con l'indirizzo IP locale della lan. Ora risolvere lo stesso nome in un diverso indirizzo esterno richiederebbe che quel nome venga popolato (dns dinamico) in modo tale da risolversi. Ma probabilmente avrai bisogno di un nome più lungo di "raspi".
ChuckCottrill,

Consulta le Domande e risposte
slm

Risposte:


7

Osservando più da vicino la tua domanda, sembra che tu stia utilizzando lo stesso computer sia all'interno che all'esterno della LAN. Ho rivisto la mia risposta di conseguenza:

Nel tuo ~/.ssh/config, aggiungi:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Quindi, è possibile ssh raspi-wandall'esterno della LAN o ssh raspi-landall'interno della LAN senza perdere tempo con i server DNS o modificando /etc/hostsper tutti gli utenti, o anche senza dover fare nulla come root. Se vuoi che il nome si raspirisolva in modo diverso a seconda di dove ti trovi, probabilmente richiederà qualche magia di shell scripting per rilevare la tua rete e agire di conseguenza.


1
Grazie DopeGhoti, mi sento molto a mio agio con la tua soluzione per includere a -wane -lanpostfix. Il mio ssh tuttavia non mi è piaciuto il Usernamecampo (opzione di configurazione errata). Funziona bene senza di essa.
Aeronaelius,

2
Mi dispiace, la sintassi corretta è User john, no UserName. Sto correggendo la mia risposta per riflettere questo, e una volta che hai impostato la tua configurazione, puoi omettere il nome utente dalla sshriga di comando.
DopeGhoti,

5

Questo è perfettamente fattibile solo con la configurazione ssh, senza dover usare alias separati per lan e wan o creare alcun port forward aggiuntivo. (Ma naturalmente hai bisogno di un modo per rilevare se sei nella tua lan o no)

In ~/.ssh/config, ti consigliamo di aggiungere qualcosa del genere:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

Al posto di am_i_outside_of_my_lanvorrai inserire un comando che determina se sei all'interno della tua rete domestica o meno, e ritorna con 0 codice di uscita se sei al di fuori di esso, e qualcos'altro.

La hostcondizione è probabilmente autoesplicativa, ma la execcondizione merita una spiegazione: corrisponde solo quando il comando dato ritorna con il codice di uscita 0, cioè. nessun errore.

Quindi, in altre parole, ciò che fa è che la host raspiparte limita questa regola quando si tenta di connettersi all'host raspi, e exec "am_i_outside_my_lan"ulteriormente la limita in modo che si applichi solo quando ci si connette dall'esterno della rete domestica. Quindi all'interno della tua rete domestica ssh user@raspifa esattamente quello che farebbe normalmente, ma al di fuori di essa la regola corrisponde e invece fa l'equivalente di ssh -p 1234 user@12.345.67.89.

Per quanto riguarda cosa usare al posto di am_i_outside_of_my_lan, ciò dipende interamente dalla tua configurazione. Suggerisco di posizionare i comandi in uno script separato invece di provare a scriverlo in linea, perché la citazione sembra essere un po 'difficile da ottenere.

Personalmente, ho usato il seguente script Python per rilevare se sono all'interno della mia rete: (Poiché il mio nome di dominio si risolve in un IP locale all'interno della mia rete)

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

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

Se non hai una configurazione simile, potresti dover fare qualcos'altro. (Ad esempio, potresti guardare il nome della rete wireless a cui sei connesso o persino interrogare un servizio what-is-my-ip per ottenere l'ip esterno della rete a cui sei connesso)


Questa è la risposta corretta; è molto triste che altri abbiano più voti.
Jonathan Tomer

@JonathanTomer: Beh, per essere onesti, ho risposto a questo 3 anni dopo che è stato chiesto, mentre le risposte con punteggio più alto sono state pubblicate in poche ore, quindi è solo un caso di "l'uccello in anticipo prende il verme": P (ho anche dire che mi piace abbastanza la variante specifica di Ellis Hoag di questa soluzione generale - usare arp è abbastanza intelligente e rende la soluzione più generica, poiché nel comando di rilevamento della rete non deve essere regolato per ogni configurazione di rete)
Aleksi Torhamo

3

Sul computer (il Connect- ing uno), è possibile impostare un nome host per 12.345.67.89. Apri il tuo /etc/hostsfile e imposta una voce DNS:

12.345.67.89    raspi

La macchina trasformerà quindi "raspi" in "12.345.67.89" come parte di un processo di risoluzione DNS locale. Se si utilizzano più macchine, è necessario apportare la modifica a ciascuna di esse. Il problema è: richiede l'accesso come root per la modifica /etc/hostse potresti non averlo ovunque.

Se vuoi che "raspi" venga riconosciuto automaticamente da qualsiasi luogo, allora scusa: impossibile. Ciò richiederebbe la registrazione di "raspi" come nome di dominio, il che non può accadere poiché "raspi" non ha TLD e non dipende da alcun server radice DNS. Tuttavia, puoi registrare un nome di dominio (diciamo cfbaptista.me, e puntarlo al tuo indirizzo IP WAN. Con un po 'di port forwarding, sarai in grado di accedere al tuo Raspberry Pi con:

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

(ancora, questo è spendere soldi per quasi nulla ...)

Per quanto riguarda la user@parte, dipende dal nome di accesso sulle diverse macchine. Se hai lo stesso nome sulla macchina di connessione e su quella remota , non è necessario specificare. In caso contrario, è necessario specificare chi si trova sul computer remoto .


nota: come menzionato nell'altra risposta, è possibile creare alias host nella propria configurazione SSH, che ovviamente non richiede root.
strugee,


0

Obiettivo: ssh raspi dovrebbe funzionare all'interno della LAN e su Internet pubblico.

Per fare ciò è necessario assicurarsi che il nome si risolva nell'IP interno sulla LAN e nell'IP pubblico dall'esterno.

Innanzitutto, dovresti ottenere un nome di dominio come raspi.yourdomain.com. Dai un'occhiata a http://freedns.afraid.org/ per domini gratuiti per hobby. Punta il dominio sul tuo IP pubblico

Per la LAN, consiglio di eseguire DNSMasq. Il firmware DD-WRT aperto si integra perfettamente con DNSMasq, utilizzandolo per DHCP e DNS. Devi solo dirgli il tuo dominio di ricerca ("tuodominio.com") e assegnerà automaticamente i nomi DNS in base al nome richiesto di ogni cliente. Per farlo funzionare, dovrebbe essere letto / etc / hostname di raspi raspi.

Una volta impostato, raspi.yourdomain.com dovrebbe risolvere l'IP locale sulla tua LAN (assicurati di utilizzare il DNS locale su tutti i tuoi computer).

Ora, probabilmente non vorrai esporre la porta 22 a Internet pubblico, perché otterrai un sacco di traffico sniffer. Quindi potresti avere il tuo router che espone raspi: 22 come un'altra porta, ad esempio 1234. Per usare la stessa porta su entrambe le reti pubbliche e interne, puoi aggiungere una regola di reindirizzamento delle porte a raspi. Su 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'

(cambia eth0 nel nome dell'interfaccia di rete come mostrato da ip linko ifconfige 1234 nella tua porta pubblica)

Ora puoi ssh -p 1234 raspi.yourdomain.comsia dal pubblico che dalla LAN.

Puoi aggiungere una voce a ~ / .ssh / config sul tuo computer client per accorciarla a just ssh raspi, come menzionato da @DopeGhoti.

Se vuoi esporre le porte SSH delle macchine aggiuntive sullo stesso IP pubblico, ripeti il ​​processo con un altro nome DNS e porta pubblica. Saluti!


0

Ecco una versione sintetica e funzionante della risposta di Aleksi Torhamo che usa curl per afferrare il tuo IP pubblico corrente e quindi verificare se corrisponde all'ip pubblico del tuo server (cioè, sei sulla stessa rete locale).

Nel tuo ~/.ssh/configaggiungi

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

Io credo che ssh elaborerà tutte le direttive corrispondenti, in ordine, quindi in teoria si dovrebbe essere in grado di fare qualcosa di simile Match host raspi / User john / HostName 192.168.2.7seguita da Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234e ottenere lo stesso effetto con una sola curlinvocazione, lasciando che il == '12.345.67.89'caso essere assunta dal fallimento del secondo Matchgoverno di exec.
FeRD

(Dovresti assicurarti che ogni argomento specificato nel primo Matchsia lo stesso o anche specificato nel secondo - se hai specificato un non standard Port xxxxnel primo Matche volevi usare la porta standard nel secondo Match, dovresti sovrascriverlo esplicitamente con un in Port 22modo che non continui a usare la porta xxxx.)
FeRD

0

Supponendo che la macchina disponga di IP 192.168.1. * Quando è collegata alla LAN, è possibile ottenere ciò con la seguente configurazione in ~/.ssh/configmodo da poter sempre utilizzare lo stesso comando (solo ssh raspi) per connettersi:

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

Questa soluzione presuppone che la tua rete domestica abbia un singolo router che credo sia il caso comune.

Aggiungi al tuo ~/.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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.