Accès SSH depuis l'intérieur et l'extérieur d'un LAN en utilisant la même commande de terminal

10

J'ai un Raspberry Pi (RPi) et je lui connecte à distance en utilisant ssh. J'ai réussi à configurer correctement ssh de manière à pouvoir accéder au RPi à la fois depuis un réseau local et depuis Internet (en utilisant un port spécifique que j'ai ouvert sur mon routeur).

En supposant un nom d'utilisateur johnet un RPi nommé raspi:

Accès LAN intérieur

ssh [email protected]
ssh john@raspi
ssh raspi

Accès LAN extérieur

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

Mais comment faire simplement ssh raspidepuis l'extérieur de mon réseau local?. Existe-t-il un moyen de configurer raspi pour pointer vers deux adresses IP, une dans un LAN et une sur Internet?

Ce que je veux essentiellement, c'est accéder à mon RPi d'une manière unique, que je sois à la maison ou au travail.

Aeronaelius
la source
Vous pouvez exécuter un serveur DNS sur votre réseau local qui répond à la demande du nom "raspi" avec l'adresse IP du réseau local. Désormais, la résolution de ce même nom à une adresse extérieure différente nécessiterait que ce nom soit rempli (DNS dynamique) de manière à ce qu'il soit également résolu. Mais vous aurez probablement besoin d'un nom plus long que "raspi".
ChuckCottrill

Réponses:

7

En regardant de plus près votre question, il semble que vous utilisez le même ordinateur à la fois à l'intérieur et à l'extérieur du LAN. J'ai révisé ma réponse en conséquence:

Dans votre ~/.ssh/config, ajoutez:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Ensuite, vous pouvez ssh raspi-wandepuis l'extérieur du LAN, ou ssh raspi-landepuis l'intérieur du LAN sans toucher aux serveurs DNS ou modifier /etc/hostspour tous les utilisateurs, ou même avoir besoin de faire quoi que ce soit en tant que root. Si vous voulez que le nom raspise résolve différemment selon l'endroit où vous vous trouvez, cela nécessitera probablement un peu de magie de script shell pour détecter votre réseau et agir en conséquence.

DopeGhoti
la source
1
Merci DopeGhoti, je suis très à l'aise avec votre solution pour inclure a -wanet -lanpostfix. Mon ssh n'a cependant pas aimé le Usernamechamp (option de configuration incorrecte). Il fonctionne très bien sans cela.
Aeronaelius
2
Je suis désolé, la syntaxe correcte ne l'est User johnpas UserName. Je corrige ma réponse pour refléter cela, et une fois que vous avez ainsi défini votre configuration, vous pouvez omettre le nom d'utilisateur de la sshligne de commande.
DopeGhoti
5

Ceci est parfaitement réalisable avec juste la configuration ssh, sans avoir à utiliser des alias séparés pour le lan et le wan ou créer des ports supplémentaires vers l'avant. (Mais vous avez naturellement besoin d'un moyen pour détecter si vous êtes dans votre réseau local ou non)

Dans ~/.ssh/config, vous voudrez ajouter quelque chose comme ceci:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

Au lieu de, am_i_outside_of_my_lanvous voudrez placer une commande qui détermine si vous êtes à l'intérieur de votre réseau domestique ou non, et retourne avec 0 code de sortie si vous êtes en dehors, et autre chose sinon.

La hostcondition est probablement explicite, mais la execcondition mérite une explication: elle ne correspond que lorsque la commande donnée revient avec le code de sortie 0, c'est-à-dire. pas d'erreur.

En d'autres termes, ce que cela fait, c'est que la host raspipartie restreint cette règle lorsque vous essayez de vous connecter à l'hôte raspi, et la exec "am_i_outside_my_lan"limite davantage pour qu'elle ne s'applique que lorsque vous vous connectez à l'extérieur de votre réseau domestique. Donc, à l'intérieur de votre réseau domestique, il ssh user@raspifait exactement ce qu'il ferait normalement, mais en dehors de celui-ci, la règle correspond et il fait à la place l'équivalent de ssh -p 1234 [email protected].

Quant à quoi utiliser à la place am_i_outside_of_my_lan, cela dépend entièrement de votre configuration. Je suggère de placer les commandes dans un script séparé au lieu d'essayer de l'écrire en ligne, car la citation semble être un peu difficile à bien faire.

Personnellement, j'ai utilisé le script Python suivant pour détecter si je suis à l'intérieur de mon propre réseau: (puisque mon nom de domaine se résout en une adresse IP locale à l'intérieur de mon propre réseau)

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

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

Si vous n'avez pas une configuration similaire, vous devrez peut-être faire autre chose. (Par exemple, vous pouvez regarder le nom du réseau sans fil auquel vous êtes connecté, ou même interroger un service what-is-my-ip pour obtenir l'ip externe du réseau auquel vous êtes connecté)

Aleksi Torhamo
la source
Ceci est la bonne réponse; c'est très triste que d'autres aient plus de votes.
Jonathan Tomer
@JonathanTomer: Eh bien, pour être honnête, j'ai répondu à cela 3 ans après qu'il ait été demandé, alors que les réponses les mieux notées ont été publiées en quelques heures, donc c'est juste un cas de "le lève-tôt obtient le ver": P (j'ai aussi pour dire que j'aime bien la variante spécifique d'Ellis Hoag de cette solution générale - utiliser arp est assez intelligent et rend la solution plus générique, comme dans la commande de détection de réseau n'a pas besoin d'être réglée pour chaque configuration de réseau)
Aleksi Torhamo
3

Sur votre ordinateur (le Connect- ing un), vous pouvez définir un nom d' hôte 12.345.67.89. Ouvrez votre /etc/hostsfichier et définissez une entrée DNS:

12.345.67.89    raspi

Votre machine transformera ensuite "raspi" en "12.345.67.89" dans le cadre d'un processus de résolution DNS local. Si vous utilisez plusieurs machines, le changement doit être effectué sur chacune d'elles. Le problème est: il nécessite un accès root pour modifier /etc/hosts, et vous pourriez ne pas l'avoir partout.

Si vous voulez que "raspi" soit reconnu automatiquement de n'importe où, alors désolé: pas possible. Cela nécessiterait l'enregistrement de "raspi" comme nom de domaine, ce qui ne peut pas se produire car "raspi" n'a pas de TLD, et ne dépendrait d'aucun serveur racine DNS. Cependant, vous pouvez enregistrer un nom de domaine (disons cfbaptista.me, et le pointer vers votre adresse IP WAN. Avec une redirection de port, vous pourrez accéder à votre Raspberry Pi avec:

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

(encore, c'est dépenser de l'argent pour presque rien ...)

Concernant la user@pièce, cela dépend de votre identifiant sur les différentes machines. Si vous avez le même nom sur la machine connectée et sur la machine distante , alors pas besoin de le préciser. Sinon, vous devez spécifier qui vous êtes sur la machine distante .

John WH Smith
la source
remarque: comme mentionné dans l'autre réponse, vous pouvez créer des alias d'hôte dans votre configuration SSH, qui bien sûr ne nécessite pas de root.
Strugee
En effet ! Voici un petit lien: collectiveidea.com/blog/archives/2011/02/04/how-to-ssh-aliases
John WH Smith
0

Objectif: ssh raspi fonctionner à l'intérieur du LAN et sur Internet public.

Pour ce faire, vous devez vous assurer que le nom résout l'IP interne sur le LAN et l'IP publique de l'extérieur.

Tout d'abord, vous devez obtenir un nom de domaine tel que raspi.yourdomain.com. Consultez http://freedns.afraid.org/ pour les domaines gratuits à utiliser pour les loisirs. Pointez le domaine vers votre IP publique

Pour le LAN, je recommande d'exécuter DNSMasq. Le micrologiciel ouvert DD-WRT s'intègre étroitement à DNSMasq, l'utilisant pour DHCP et DNS. Il vous suffit de lui indiquer votre domaine de recherche ("votredomaine.com") et il attribuera automatiquement les noms DNS en fonction du nom demandé par chaque client. Pour que cela fonctionne, le fichier / etc / hostname de raspi doit lire raspi.

Une fois que cela est configuré, raspi.votredomaine.com devrait se résoudre en IP locale sur votre LAN (assurez-vous simplement que vous utilisez le DNS local sur toutes vos machines).

Maintenant, vous ne voulez probablement pas exposer le port 22 à l'Internet public, car vous obtiendrez une tonne de trafic de renifleur. Ainsi, votre routeur peut exposer raspi: 22 comme un autre port, par exemple 1234. Pour utiliser le même port sur les réseaux publics et internes, vous pouvez ajouter une règle de redirection de port à raspi. Sous 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'

(remplacez eth0 par le nom de votre interface réseau comme indiqué par ip linkou ifconfig, et 1234 par votre port public)

Maintenant, vous pouvez ssh -p 1234 raspi.yourdomain.comà la fois du public et du LAN.

Vous pouvez ajouter une entrée à ~ / .ssh / config sur votre machine cliente pour la raccourcir ssh raspi, comme mentionné par @DopeGhoti.

Si vous souhaitez exposer les ports SSH de machines supplémentaires sur la même IP publique, répétez simplement le processus avec un autre nom DNS et un autre port public. À votre santé!

Eric Drechsel
la source
0

Voici une version succincte et fonctionnelle de la réponse d'Aleksi Torhamo utilisant curl pour récupérer votre adresse IP publique actuelle, puis en vérifiant si elle correspond à l'adresse IP publique de votre serveur (c'est-à-dire que vous êtes sur le même réseau local).

Dans votre ~/.ssh/configannonce

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
la source
Je pense ssh que toutes les directives correspondantes seront traitées dans l'ordre, donc en théorie, vous devriez pouvoir faire quelque chose comme Match host raspi / User john / HostName 192.168.2.7suivi Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234et obtenir le même effet avec une seule curlinvocation, laissant l' == '12.345.67.89'hypothèse être prise en compte par l'échec de la deuxième Matchrègle exec.
FeRD
(Vous devez vous assurer que chaque argument spécifié dans le premier Matchest le même ou également spécifié dans le second - si vous avez spécifié un non standard Port xxxxdans le premier Matchet que vous vouliez utiliser le port standard dans le second Match, vous devez le remplacer explicitement par un Port 22afin qu'il ne continue pas à utiliser le port xxxx.)
FeRD
0

En supposant que votre machine possède IP 192.168.1. * Lorsqu'elle est connectée à votre réseau local, vous pouvez y parvenir avec la configuration suivante ~/.ssh/configafin que vous puissiez toujours utiliser la même commande (juste ssh raspi) pour vous connecter:

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
la source
0

Cette solution suppose que votre réseau domestique possède un seul routeur, ce qui, je crois, est le cas le plus courant.

Ajoutez à votre ~/.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
la source