Pourquoi dois-je redéfinir env vars dans tmux lorsque je le rattache?

37

Je travaille principalement sur un mac et ssh / tmux attachés à une machine Linux pour faire mon travail. J'ai ssh-agent en cours d'exécution sur la machine Linux. j'ai

set -g update-environment "SSH_AUTH_SOCK SSH_ASKPASS WINDOWID SSH_CONNECTION XAUTHORITY"

dans mon .tmux.conf. Pourtant, chaque fois que je me rattache à cette session, je dois courir

tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

afin que les nouvelles fenêtres tmux soient $SSH_AUTH_SOCKcorrectement configurées. Je préférerais ne pas avoir à faire cela. Des idées?

Mise à jour

Je pense que je ne l'explique pas bien. Voici ma fonction shell pour ouvrir un shell sur une machine distante:

sshh () {
    tmux -u neww -n ${host} "ssh -Xt ${host} $*"
}

Lorsque tmux exécute cette commande ssh, $SSH_AUTH_SOCKn’est pas défini, même s’il est défini dans mon environnement local. Si je mets cela dans l'environnement tmux avec la setenvcommande ci-dessus, tout fonctionne correctement . Ma question est la suivante: pourquoi dois-je exécuter la commande setenv?

Mise à jour 2

Plus d'information:

Lorsque j'attache à une session existante, $SSH_AUTH_SOCKn'est pas défini dans l'environnement tmux (ou l'environnement global).

% tmux showenv | grep -i auth_sock
-SSH_AUTH_SOCK

Si je le configure manuellement, les choses fonctionnent:

% tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

Si je me détache et que je réattache, cela $SSH_AUTH_SOCKrevient à ne pas être défini.

Chris W.
la source
Ce n'est pas du tout sur SSH, n'est-ce pas? Quelles variables d'environnement avez-vous dans un nouveau shell, quelle est la sortie env?
Hauke ​​Laging
Quel shell utilisez-vous sur le Mac? Frapper?
slm
@HaukeLaging C'est vraiment à propos de tmux.
Chris W.
@slm j'utilise zsh.
Chris W.
Qu'en est-il des fenêtres existantes? Travaillent-ils encore?
Hauke ​​Laging

Réponses:

35

Depuis que j'ai reçu le Bounty, je vais republier mon commentaire-clé par souci d'exhaustivité - et pour éviter de mettre les visiteurs avec le même problème sur la mauvaise voie:

Tmux va supprimer les variables d'environnement

La page de manuel de Tmux indique que update-environment supprimera les variables "qui n'existent pas dans l'environnement source [...] comme si -r avait été attribué à la commande set-environment".

Apparemment, c'est ce qui a causé le problème. Voir la réponse de Chris ci-dessous . Cependant, je ne peux toujours pas imaginer comment la variable pourrait être absente dans "l'environnement source" tout en restant valide dans la nouvelle fenêtre tmux ...


Réponse précédente:

Comment fonctionne le transfert SSH

Sur la machine distante, examinez l'environnement de votre shell après avoir établi la connexion SSH:

user@remote:~$ env | grep SSH
SSH_CLIENT=68.38.123.35 45926 22
SSH_TTY=/dev/pts/0
SSH_CONNECTION=68.38.123.35 48926 10.1.35.23 22
SSH_AUTH_SOCK=/tmp/ssh-hRNwjA1342/agent.1342

Le plus important ici est SSH_AUTH_SOCK, qui est actuellement défini sur un fichier dans / tmp. Si vous examinez ce fichier, vous constaterez qu'il s'agit d'un socket de domaine Unix et qu'il est connecté à l'instance particulière de ssh à laquelle vous vous êtes connecté. Fait important, cela change chaque fois que vous vous connectez.

Dès que vous vous déconnectez, ce fichier de socket particulier est parti. Maintenant, si vous attachez de nouveau votre session tmux, vous verrez le problème. Il a l'environnement depuis le lancement initial de tmux - ce qui aurait pu être le cas il y a des semaines. Cette prise particulière est morte depuis longtemps.

Solution

Puisque nous savons que le problème consiste à savoir où se trouve le socket d'authentification SSH actuellement actif, plaçons-le simplement dans un endroit prévisible!

Dans votre fichier .bashrc ou .zshrc sur la machine distante, ajoutez les éléments suivants:

# Predictable SSH authentication socket location.
SOCK="/tmp/ssh-agent-$USER-screen"
if test $SSH_AUTH_SOCK && [ $SSH_AUTH_SOCK != $SOCK ]
then
    rm -f /tmp/ssh-agent-$USER-screen
    ln -sf $SSH_AUTH_SOCK $SOCK
    export SSH_AUTH_SOCK=$SOCK
fi

Je ne pense pas que vous deviez même mettre une "commande update-environment" dans votre tmux.conf. Selon la page de manuel, SSH_AUTH_SOCK est déjà couvert par défaut.

Crédit

Ma réponse est un extrait de ce blog de Mark 'xb95' Smith qui explique le même problème pour screen .

djf
la source
Merci pour votre réponse réfléchie. Ma question ne concerne pas la définition de mon $SSH_AUTH_SOCKnouveau shell, mais bien celle de la $SSH_AUTH_SOCKnouvelle fenêtre de tmux avant que .bashrc / .zshrc ne soit obtenu.
Chris W.
@ChrisW. J'ai supposé que le script devrait être placé dans le fichier rc de votre shell de connexion sur la machine distante. Si vous vous connectez, un nouveau shell est créé, SSH_AUTH_SOCK est modifié et exporté . Lorsque vous démarrez ensuite tmux, il héritera de SSH_AUTH_SOCK de l’environnement parent. Puisque la valeur de SSH_AUTH_SOCK est maintenant fixée, tmux devrait continuer à travailler sur les connexions suivantes ... Peut-être ai-je mal compris le problème
djf
J'imagine que ma confusion concerne l'environnement dans lequel ssh est exécuté par tmux dans le contexte d'une nouvelle fenêtre (par exemple tmux neww ssh somehost).
Chris W.
Un problème avec cette approche est qu’une 2ème connexion SSH à la machine écrasera la valeur de SSH_AUTH_SOCK. Cette approche ne fonctionne que lorsque la session tmux est ouverte via la connexion SSH la plus récente.
phylae
12

Je l'ai compris. Réponse courte, je devais enlever SSH_AUTH_SOCKde update-environment. Comme il figurait dans cette liste, la valeur volait à chaque fois que je me rattachais. Merci à @djf pour l'indice. La partie saillante de la page de manuel tmux (1) de la update-environmentsection:

Toutes les variables qui n'existent pas dans l'environnement source sont définies pour être supprimées de l'environnement de session (comme si -r avait été attribué à la commande set-environment).

Chris W.
la source
1
@ChrisW. Pourriez-vous s'il vous plaît être un peu plus clair? Je pense avoir le même problème: parfois, l'agent cesse de fonctionner lorsque je rattache des sessions tmux. Cela a du sens car la connexion SSH est nouvelle et quand je ssh elle démarrera un nouvel agent. Que dois-je changer pour que cela fonctionne? J'espère que c'est quelque chose que je peux exécuter car je ne veux pas avoir à reconfigurer chaque machine dans laquelle je suis ssh-ing. - Maintenant, j'ai un wrapper ssh qui démarre tmux à distance ou restaure les connexions existantes. Je pourrais probablement faire quelque chose avant de restaurer tmux.
sorin
@ChrisW. Les réponses courtes sont bien parfois, mais pourriez-vous donner une réponse longue? J'ai du mal à faire en sorte que cela fonctionne et rien dans ce poste ne fonctionne pour moi.
Redbmk
@sorin @redbmk Désolé pour ça. C’est la seule ligne que j’ai du changer .tmux.confpour que cela fonctionne: set -g update-environment "SSH_ASKPASS WINDOWID SSH_CONNECTION XAUTHORITY" Voyez-vous des problèmes avec sshles variables d’environnement ou en général?
Chris W.
2

Au lieu d’utiliser tmux pour gérer mon agent ssh, je l’ai fait avec:

### SSH Agent ### {{{
SSH_ENV="$HOME/.ssh/environment"

function start_agent {
    echo "Initialising new SSH agent..."
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
    echo succeeded
    chmod 600 "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add;
}

## Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
  else
    start_agent;
fi
### End SSH Agent ### }}}

J'ai ceci dans mon ~ / bashrc , et cela fonctionne très bien.

sage
la source
$SSH_AUTH_SOCKest correctement défini dans mes coques, mais lorsque je fais quelque chose du genre tmux neww ssh somehost, on me demandera de saisir ma phrase secrète pour déverrouiller ma clé privée, sauf si je me lance tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK.
Chris W.
1

J'ai répondu à une question similaire sur StackOverflow https://stackoverflow.com/a/49395839/241025 . Cette page étant apparue en premier dans mes recherches sur Google, je souhaitais en publier une version récapitulative ici.

Pour que chaque session tmux dispose d'un ensemble de variables d'environnement personnalisées, vous devez ajouter les valeurs aux variables d'environnement par session de tmux. Voici un exemple de la façon de le faire.

tmux new-session -s one
tmux setenv FOO foo-one
export FOO='foo-one'

La dernière étape d’exportation explicite de FOO est nécessaire pour que le volet actuel sélectionne la variable d’environnement. Tous les volets ou fenêtres que vous créez pour cette session tmux hériteront de FOO, mais ils ne s'afficheront pas dans les autres sessions.

RobotNerd
la source
0

L'explication de DJF apporte une autre solution possible dans mon esprit:

Avant tmux/ screenest en cours d'exécution:

  1. S'identifier.
  2. Démarrer une instance de ssh-agent.
  3. Démarrer tmux/ screenavec la ou les variables d’environnement pour cela ssh-agent.

Cela ne peut pas utiliser le transfert SSH vers le client, mais cela n’a pas été demandé.

Hauke ​​Laging
la source
1
ssh-agentne se lie pas à ATS, pourquoi devrait-il être tué à la déconnexion (?) - pourquoi utiliser nohup?
poige
@poige Correct.
Hauke ​​Laging,