Question En ssh'ing, comment puis-je définir une variable d'environnement sur le serveur qui change d'une session à l'autre?


Quand je ssh sur un serveur, comment puis-je passer une variable d’environnement du client au serveur? Cette variable d'environnement change entre différents appels de ssh donc je ne veux pas écraser $HOME/.ssh2/environment chaque fois que je fais un appel ssh. Comment puis-je faire ceci?


76
2017-07-13 16:59


origine


Votre question doit être un peu plus spécifique. - Ignacio Vazquez-Abrams
La question était assez claire pour moi. Cependant, du ssh man page, je ne vois pas d'autre moyen que de définir la variable manuellement une fois que vous vous êtes connecté au serveur, sauf si vous modifiez ~ / .ssh2 / environment. - garyjohn
Est-ce une variable différente à chaque fois? Ou une valeur différente? - Dennis Williamson
Duplicata possible de Comment passer une variable d'environnement via une commande ssh? - Tonin
Autrement dit, comme cela est déjà plus populaire. Ce n'est pas grave, c'est plus vieux. - kenorb


Réponses:


Bien sûr, vous pouvez définir la variable d'environnement à l'intérieur de la commande, mais vous devrez faire attention à la citation: rappelez-vous que votre shell va analyser votre ligne de commande locale, puis le shell distant va essayer la chaîne reçoit.

Si vous souhaitez qu'une variable obtienne la même valeur sur le serveur qu’elle possède sur le client, essayez le SendEnv option:

ssh -o SendEnv = MYVAR server.example.com mycommand

Cela nécessite le support du serveur, cependant. Avec OpenSSH, le nom de la variable doit être autorisé dans /etc/sshd_config.

Si le serveur n'autorise que certains noms de variables spécifiques, vous pouvez contourner ce problème; par exemple une configuration commune permet LC_* à travers, et vous pouvez faire ce qui suit:

ssh -o SendEnv = LC_MYVAR server.example.com 'MYVAR = $ LC_MYVAR; non défini LC_MYVAR; exporter MYVAR; ma commande

Si même LC_* n'est pas une option, vous pouvez transmettre des informations dans le TERM variable d'environnement, qui est toujours copiée (il peut cependant y avoir une limite de longueur). Vous devrez toujours vous assurer que le shell distant ne restreint pas le TERM variable pour désigner un type terminal connu. Passe le -t option à ssh si vous ne démarrez pas un shell interactif distant.

env TERM = "informations supplémentaires: $ TERM" ssh -t server.example.com 'MYVAR = $ {TERM%: *}; TERM = $ {TERM ## *:}; exporter MYVAR; ma commande

Une autre possibilité est de définir la variable directement dans la commande:

ssh -t server.example.com 'export MYVAR = "informations supplémentaires"; ma commande

Ainsi, en passant une variable locale:

ssh -t server.example.com 'export MYVAR =' "'$ LOCALVAR'" '; ma commande

Cependant, méfiez-vous de citer des problèmes: la valeur de la variable sera interpolée directement dans l'extrait de shell exécuté sur le côté distant. Le dernier exemple ci-dessus suppose que $LOCALVAR ne contient pas de guillemets simples (').


89
2017-07-13 19:25



Merci beaucoup, j'étais furieux que les stupides variables LC_ * soient exportées sur ssh et votre réponse m'a indiqué où regarder. Je dois juste le désactiver dans ~ / .ssh / config - akostadinov
Je suis dans la situation de l'affiche originale, mais la variable que je voulais transmettre est TERM, alors je suis un peu perplexe par votre réponse. Ce transfert automatique de TERM a-t-il été désactivé par les versions récentes d'OpenSSH? - Doub
@Doub La valeur par défaut est de refuser toutes les variables d'environnement du côté du serveur, avec AcceptEnv directives en sshd_config comme souhaité par l'administrateur. Mais TERM est traité spécialement, pour autant que je sache, il n'y a aucun moyen de le filtrer côté serveur (il est défini dans l'environnement du shell, quel que soit le paramètre de configuration). Etes-vous sûr qu'il n'y a pas de script de profil qui le remplace (comme /etc/profile ou ~/.profile ou ~/.bashrc)? - Gilles
@Gilles: Je l'ai testé à nouveau, et à moins que j'ajoute explicitement TERM à ma directive AcceptEnv, le TERM n'est pas transmis. Je n'ouvre pas de shell, mais j'exécute une commande directement, par exemple: "ssh -o SendEnv = TERM shell.example.com env". Cela imprime toute variable d'environnement, et TERM n'apparaît que s'il se trouve dans SendEnv sur le client et AcceptEnv sur le serveur. Si je lance "ssh -o SendEnv = TERM shell.example.com echo \ $ {TERM}" avec AcceptEnv ou SendEnv, il affiche "dumb", ce dont je ne suis pas sûr (env ne fait même pas liste TERM dans ce cas). - Doub
@Doub Oh, je vois. TERM n'est transmis que si le client demande au serveur d'allouer un tty. S'il n'y a pas de terminal du côté distant, il serait inutile de transmettre TERM. Lorsque vous spécifiez une commande, si vous souhaitez avoir un terminal sur le côté distant, vous avez besoin du -t option de ligne de commande (ou RequestTTY dans ~/.ssh/config). - Gilles


Si vous pouvez administrer l'hôte cible, vous pouvez configurer sshd pour permettre le transfert de vos variables d'environnement locales à l'hôte cible.

Depuis la page de manuel de sshd_config:

 PermitUserEnvironment
     Specifies whether ~/.ssh/environment and environment= options in
     ~/.ssh/authorized_keys are processed by sshd.  The default is
     "no".  Enabling environment processing may enable users to bypass
     access restrictions in some configurations using mechanisms such
     as LD_PRELOAD.

la configuration de sshd vit généralement à /etc/ssh/sshd_config


11
2018-02-03 17:09



C'est très utile de savoir que ceci est réglé sur "non" par défaut! - jathanism


Donc, sur votre client, vous avez une variable d’environnement et vous voulez que celle-ci soit disponible pour la commande à distance? Je ne pense pas qu'il soit possible de faire passer magiquement ssh, mais vous pouvez probablement faire quelque chose comme ça. Au lieu d'utiliser, dites:

ssh remote.host my_command

Tu peux le faire:

ssh remote.host env ENV_VAR=$ENV_VAR my_command

6
2017-07-13 17:52



"Probablement"? J'aurais aimé le lire avant d'essayer réellement cette réponse. N'a pas fonctionné pour moi - tishma
Attention aux erreurs reçues, etc.? - pioto
@pioto pourrait citer, par exemple si ENV_VAR contient des espaces - Martin C. Martin
Sur Mac, vous devez avoir l'option -t pour une version interactive, sinon elle semble bloquée. Cela pourrait donc fonctionner: $ ssh -t remote.host env ENV_VAR = $ ENV_VAR my_command - muenalan


La réponse de @ emptyset (qui n'a pas fonctionné pour moi) m'a conduit à cette réponse:

Vous pouvez ajouter cette commande à votre ~/.ssh/authorized_keys fichier:

command="/usr/bin/env VARIABLE=<something> $SHELL" ssh-rsa <key>

export VARIABLE=<something> se retirait immédiatement, et la connexion SSH était fermée (me bloquant hors du serveur), alors que /usr/bin/env ... $SHELLexécutera votre shell par défaut avec un environnement modifié.


2
2018-05-14 14:36



Cela se bloque quand je me connecte pour moi. Lorsque je le retire, SSH revient à la normale et je reçois mon shell de connexion habituel. - Nick Sweeting
@NickSweeting avez-vous essayé de remplacer $SHELL avec une coquille réelle? Vérifiez également que / usr / bin / env existe sur le serveur. Cependant, la solution n’est pas parfaite: j’ai remarqué qu’elle se bloquait lorsque je voulais utiliser scp ou une commande en ligne. - madprog
Oui, c'était la première chose que j'ai essayée. Malheureusement, cela n'a jamais fonctionné, a fini par permettre PermitUserEnvironment yes et en utilisant environment="..." au lieu de command="...". - Nick Sweeting


Vous pouvez essayer d'appeler une commande personnalisée, en supposant que vous ayez une configuration de connexion ssh sans mot de passe. Sur le serveur, modifiez votre entrée ~ / .ssh / authorized_keys correspondant à la clé de votre client:

command="export VARIABLE=<something>" ssh-rsa <key>

Regarder ce lien dans la section Commande forcée pour un peu plus de détails.


1
2017-07-13 17:15



J'ai essayé ceci, mais ça ne marche pas. Il exécute la commande et quitte, donc il n'y a pas de session interactive. Est-ce le comportement normal? Si tel est le cas, cela pourrait être utile si tout ce que vous voulez faire est de permettre à une clé spécifique de déclencher une commande spécifique, mais si vous voulez transmettre des informations qui est utilisé dans une session (comme le dit la question), alors c'est inutile à cette fin. Il n'y a pas de session. - iconoclast


Je faisais une version personnalisée d'OpenSSH pour un périphérique avec un cramfs dans le répertoire home et / etc (Cram FS est en lecture seule) donc ~ / .ssh / environment ne fonctionnerait pas sans reconstruire le FS complet et ceux-ci étaient déployés sur le terrain appareils (systèmes embarqués d’où l’utilisation de CRAMFS). Vous pouvez spécifier dans le fichier sshd_config l'emplacement du fichier authroized_keys, mais pour une raison quelconque, l'environnement = ne fonctionne que pour les variables d'environnement dans les fichiers ~ / .ssh / authroized_keys. L'édition du profil / etc / n'était pas une option et j'ai dû charger ssh dans un répertoire non standard. Dans session.c après le child_set_env (... "MAIL" ...) ajoutez simplement les variables d'environnement dont vous avez besoin (ceci est un hack que je connais ...) mais n'encouragez que quelqu'un qui a besoin de certains envs pour une session si vous êtes compiler à partir de la source, vous pouvez le faire. TGI-FLOSS


1
2017-08-28 16:55