13 votes

Comment exécuter un tunnel en arrière-plan dans le cadre d'un script shell

Je lance ces deux commandes tout le temps pour me connecter à mon instance rds sur aws qui est protégée derrière un pare-feu (donc je passe par l'instance ec2) de la manière suivante :

commande 1 : ouvrir le tunnel (en arrière-plan)

ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub &

commande 2 : se connecter à la base de données via le port du tunnel :

PGPASSWORD=password psql dbname -U user -h ip_address -p port;

ce qui est génial, mais j'aimerais mettre ces deux commandes dans une seule fonction. Mais rien n'a fonctionné avec moi :

essai 1 : exécution sans l'arrière-plan :

function db()
{
    ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub &
    PGPASSWORD=password psql dbname -U user -h ip_address -p port;
}

simplement me dit cela :

$proddb
[1] 62924
psql: could not connect to server: Connection refused
    Is the server running on host "127.0.0.1" and accepting
    TCP/IP connections on port 6666?

bien que la commande initiale soit en cours d'exécution en arrière-plan :

ps aux | grep host
(standard input):435:abdullah         62924   0.0  0.0  4315660   5828 s006  S     3:06PM   0:00.03 ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub

et si je lance immédiatement la commande suivante après ça.. je me connecte à la base de données sans problème !

PGPASSWORD=password psql dbname -U user -h ip_address -p port;
user=>

Comment puis-je faire en sorte que cela fonctionne ?

18voto

A.B Points 3913

La première commande n'a pas eu le temps d'établir un tunnel lorsque la deuxième commande a été exécutée, donnant ainsi un "Connexion refusée".

Il suffit de ne pas utiliser & mais d'utiliser plutôt l'option -f:

-f
Demande à ssh de passer en arrière-plan juste avant l'exécution de la commande. C'est utile si ssh doit demander des mots de passe ou des phrases de passe, mais que l'utilisateur le veut en arrière-plan. Cela implique -n. La manière recommandée de démarrer des programmes X11 sur un site distant est quelque chose comme ssh -f host xterm.
Si l'option de configuration ExitOnForwardFailure est définie sur "yes", alors un client lancé avec -f attendra que toutes les redirections de ports distants soient établies avec succès avant de se placer en arrière-plan.

En mettant tout cela ensemble, remplacez la ligne ssh dans la fonction par :

ssh -o ExitOnForwardFailure=yes -f -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub

de cette façon, en exécutant la fonction plusieurs fois, aucun ssh inutile (multiple-1) ne restera en cours.

Il est aussi possible de remplacer -N par une simple commande sleep distante. Ainsi, il n'y aura pas de commande ssh en attente pendant longtemps qui devra être recherchée pour être arrêtée. Ssh attendra toujours la fin de l'utilisation du tunnel avant de se terminer, donc le court délai n'est pas un problème :

ssh -o ExitOnForwardFailure=yes -f -L port:host:5432 user@$ip -i ~/.ssh/key.pub sleep 15

0voto

desi Points 1

Cette solution par @A.B peut également être utilisée pour créer un "jump server" entre la dmz (internet ou les points de terminaison edge) et la mz (backend) avec un tunnel de redirection de port ssh vers les hôtes backend, par exemple :

(tous les ports respectifs doivent être ouverts en utilisant firewall-cmd)

desthost_ip est l'ip cible pour le service en cours d'accès, il doit avoir un processus répondant lié à lui, c'est-à-dire, tomcat, webapp, etc.

Sur le bord de la dmz :

ssh -o ExitOnForwardFailure=yes -f -L localhost_ip:port:desthost_ip:port user@dest_ip -i xyz.key sleep 15

Donc, si localhost a également une ip publique; en supposant que desthost a un service basé sur https en cours d'exécution, alors quelque chose comme ceci peut fonctionner :

https://public_ip_of_localhost:port

Cela devrait faire apparaître la page de service desthost_ip:port.

ssh -o ExitOnForwardFailure=yes -f -L 192.168.1.199:8001:192.168.2.10:8081 user@192.168.2.10 -i xyz.key sleep 15

Et

https://192.168.1.199:8001 

ou

https://public_ip_for_192.168.1.199:8001

fera apparaître la page de service sur 192.168.2.10:8081.

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