2 votes

Changer l'adresse IP ssh en fonction du réseau actuel

J'ai ces deux entrées dans mon fichier de configuration ssh sur mon ordinateur portable :

Hôte server1_int
  Nom d'hôte 192.168.1.92
  Fichier d'identité ~/.ssh/id_rsa
  Utilisateur moi
  Port 1234

Hôte server1_ext
  Nom d'hôte 134.x.y.z
  Fichier d'identité ~/.ssh/id_rsa
  Utilisateur moi
  Port 4321

Ce serveur est derrière un NAT. Quand je suis également derrière le NAT, j'ai besoin de me connecter en ssh sur "server1_int". Si je suis ailleurs sur Internet, j'ai besoin de me connecter en ssh sur "server1_ext" pour atteindre mon serveur. Existe-t-il un moyen de configurer ssh pour qu'il choisisse la bonne entrée en fonction du sous-réseau dans lequel se trouve actuellement mon ordinateur portable ?

3voto

A.B Points 7722

Vous pouvez utiliser dans ~/.ssh/config (ou une configuration client globale) le mot-clé Match avec le critère exec pour exécuter un script renvoyant un verdict (vrai ou faux) :

Match

Restreint les déclarations suivantes (jusqu'au prochain mot-clé Host ou Match) à être utilisées uniquement lorsque les conditions suivant le mot-clé Match sont satisfaites. Les conditions Match sont spécifiées en utilisant un ou plusieurs critères ou le jeton unique all qui correspond toujours. Les mots-clés de critères disponibles sont : canonical, exec, host, originalhost, user et localuser. Le critère all doit apparaître seul ou immédiatement après canonical.

[...]

Le mot-clé exec exécute la commande spécifiée sous le shell de l'utilisateur. Si la commande renvoie un code de sortie zéro alors la condition est considérée comme vraie. Les commandes contenant des caractères d'espacement doivent être citées. Les arguments à exec acceptent les jetons décrits dans la section JETONS.

Utilisons comme verdict "Essayer cette adresse IP nécessitera-t-il ce routeur ? (y compris la vérification de l'absence de routeur)" dans le script ~/bin/hasthisgateway.sh (Cet exemple de script, destiné à Linux, peut probablement être amélioré. N'oubliez pas de lui appliquer la commande chmod u+rx) :

#!/bin/sh
routeur=$(/sbin/ip -o route get "$1" |grep -E -o ' via ([0-9]+.){3}[0-9]+'|sed 's/^ via //')
[ "$routeur" = "$2" ] # test final et code de retour

Pour le premier cas, en supposant que nous sommes dans le même LAN, nous ne voulons pas de routeur, pour le deuxième cas, eh bien c'est le cas par défaut restant, nous n'avons pas besoin du critère exec. Bien qu'il corresponde partout, il ne remplacera pas les valeurs précédentes, comme indiqué dans le manuel :

Pour chaque paramètre, la première valeur obtenue sera utilisée.
[...]
Étant donné que la première valeur obtenue pour chaque paramètre est utilisée, les déclarations spécifiques à l'hôte devraient être données près du début du fichier et les valeurs par défaut générales à la fin.

Mais ce n'est pas suffisant : ailleurs, les entrées Host indiquent également qu'elles s'appliquent uniquement jusqu'au prochain Host ou bien Match. Ainsi, en réalité, ces entrées Match sont utilisées quoi qu'il arrive en tant que valeur par défaut (elles devraient être indentées au même niveau que l'entrée Host) et nous ne pouvons pas utiliser simplement un Match all pour le deuxième cas sinon cela définirait le nom d'hôte pour tout autre réglage, y compris d'autres paramètres Host. Pour éviter cela, ajoutez un critère originalhost :

Le mot-clé originalhost correspond à l'hôte tel qu'il a été spécifié en ligne de commande.

Il est possible d'ajouter d'autres cas avant le cas par défaut (un autre LAN interne ? il y a probablement un routeur spécifique alors, ou choisissez un script de critères plus adapté).

~/.ssh/config :

Host server1
  #parties communes
  IdentityFile ~/.ssh/id_rsa 
  User me
  #interne
Match originalhost server1 exec "~/bin/hasthisgateway.sh 192.168.1.92 ''"
  Hostname 192.168.1.92
  Port 1234
  #externe
Match originalhost server1
  Hostname 134.x.y.z
  Port 4321

Maintenant, dans les deux cas, vous pouvez utiliser la même commande ssh server1 qui se comportera différemment. Cela affectera aussi scp, sftp, lftp ... Il aurait probablement été possible d'utiliser uniquement des entrées Match et aucune entrée Host pour ce cas.

0voto

altin Points 689

Étant donné que les configurations SSH ne peuvent pas être scriptées, le moyen le plus simple de procéder serait de configurer un transfert de port et de toujours se connecter à une adresse IP publique, ou de créer un script de connexion à votre serveur.

Pseudocode pour le script bash

if (ip.startsWith("192.168.1.")) {
   ssh me@192.168.1.92 -p 1234
}
else {
   ssh me@134.x.y.z -p 4321
}

Gardez à l'esprit que si vous êtes connecté à un autre réseau commençant par "192.168.1", le script supposera que le serveur SSH est accessible par une adresse IP locale, ce qui ne sera pas le cas. La seule façon d'éviter cela est de faire vérifier par le script s'il est réellement à cette adresse IP en exécutant une commande netcat ou quelque chose du genre.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X