ProxyCommand conditionnel dans ~ / .ssh / config?


14

J'ai mon ~/.ssh/configconfiguré avec différents hôtes qui sont accessibles soit sur notre VPN d'entreprise, soit via un serveur proxy SSH.

En ce moment j'ai juste

Host internal-server
    ProxyCommand ssh -W internal.ip:22 external-server

Cependant, si je suis dans le réseau interne, je peux accéder directement à l'IP interne, donc le proxy via le serveur externe ajoute juste un retard à la connexion.

Existe-t-il un moyen de proxy provisoire si l'IP interne n'est pas accessible et de me connecter directement autrement?

Réponses:


8

J'ai l'habitude de configurer quelque chose comme ça. Il suppose que l'hôte intermédiaire sera en mesure de résoudre le nom.

Host *%homeproxy
    ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22

Donc je me connecte pour aimer ssh blah%homeproxy.


Mon google-fu me fait défaut. Pouvez-vous expliquer cela davantage? Je n'ai jamais vu cette syntaxe *% auparavant.
fukawi2

3
Le personnage n'a rien de spécial %. Vous pourriez vraiment utiliser n'importe quoi. Le pourcentage est utilisé car il n'est pas valide dans un nom d'hôte ou un nom d'utilisateur. La cutcommande associée à la ProxyCommand utilise le %comme délimiteur pour extraire le nom d'hôte.
Zoredache

1
C'est bien, mais cela signifie que je dois épeler le nom d'hôte complet plutôt que l'alias ssh.
alt

@mobiusnz Cela signifie simplement que vous avez besoin d'un nom différent pour chaque moyen de connexion différent. Dans mon cas, par exemple, si je suis à la maison, j'utilise ssh targetH, c'est-à-dire cible depuis chez moi . Si dans un réseau local à cibler, tout simplement ssh target. Cela aurait été bien que cela soit dit plus simplement dans la réponse.
Rubens

4

J'utilise une méthode différente en utilisant Match. Dans mon cas, je veux utiliser un proxy local s'il fonctionne, ou non, s'il ne l'est pas. La directive suivante accomplit bien cela:

Match Exec "nc -z 127.0.0.1 1086"
    ProxyCommand nc -X 5 -x 127.0.0.1:1086 %h %p

Il correspond à chaque tentative ssh et exécute une vérification rapide à l'aide de ncpour voir si mon proxy est opérationnel sur 1086 (dans ce cas, se nctermine sans erreur). Si cela se produit, il définit la ProxyCommand.


2

Il y a dix ans, j'ai écrit une commande proxy pour ce type de scénario. Dans votre cas d'utilisation, ma commande proxy pourrait être utilisée comme ceci:

Host internal-server
    ProxyCommand ssh-multipath-proxy %h:%p -- ssh -W %h:%p external-server

Quelques mises en garde: je suis un peu gêné d'admettre qu'il ne gère pas IPv6 et qu'il n'essaiera qu'une seule adresse IP par nom d'hôte. En outre, il ne transférera pas la bannière du client vers le serveur avant l'envoi de la bannière du serveur. Mais il est peu probable que cela cause des problèmes.


2

Merci pour la réponse de @ till , cela m'a beaucoup inspiré.

J'ai trouvé que vous pouvez forcer la redirection de votre connexion avec ProxyCommand nc dst dst-port.

Par exemple, vous vous connecterez en fait B.comsi vous utilisez

ssh A.com -o ProxyCommand="nc B.com 22"

Mais UserKnownHostsFileenregistrera toujoursA.com

Vous pouvez donc ajouter un domaine "auto" à votre ssh_config

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(timeout 0.1 nc -z %h %p) && nc %h %p || ssh -W %h:%p external-server'

Je l'ai remplacé nc -w 1 %h %ppar (timeout 0.1 nc -z %h %p) && nc %h %p, ce sera plus rapide si vous pouviez atteindre le serveur interne en moins de 100 ms.

Ou vous pouvez le remplacer par ping, mais cela peut indiquer de mauvaises informations si vous utilisez un proxy basé sur TCP comme proxychains, ou si le serveur n'autorise pas l'écho ICMP.

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(ping %h &>/dev/null) && nc %h %p || ssh -W %h:%p external-server'

Vous pouvez remplacer (timeout 0.1 nc -z %h %p)par tout ce qui détecte si vous êtes sur un serveur interne.

Si vous avez plusieurs adresses IP candidates, même vous pouvez utiliser ceci:

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c 'f(){(timeout 0.1 ping -c 1 $1 &>/dev/null) && nc $1 %p;}; f 1.1.1.1 || f 2.2.2.2 || f 3.3.3.3'

Il essaiera de se connecter 1.1.1.1, en cas d'échec, essayez de vous connecter 2.2.2.2, puis 3.3.3.3.


0

Cela fonctionne un peu plus automatiquement avec un minuscule délai supplémentaire de 1 seconde si vous n'êtes pas derrière le pare-feu et que le pare-feu ne rejette pas:

Host proxyhost.example.com
ProxyCommand none

Host *.example.com
ProxyCommand sh -c "nc -w 1 %h %p || ssh -W  %h:%p proxyhost.example.com"

0

Je créerais généralement une autre entrée quelque chose comme ça -

Host myVM
    ProxyCommand ssh -W internal.ip:22 external-server
    User ubuntu

Host myVM-np
    User ubuntu

Il vous suffit ensuite d'appeler celui que vous souhaitez, en fonction de votre environnement proxy actuel.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.