Dlaczego muszę ponownie ustawiać zmienne env w tmux po ponownym dołączeniu?

37

Pracuję głównie na komputerze Mac i ssh / tmux podłączonym do komputera z systemem Linux, aby wykonać swoją pracę. Mam ssh-agent działający na komputerze z systemem Linux. mam

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

w moim .tmux.conf. Jednak za każdym razem, gdy ponownie dołączam do tej sesji, muszę biegać

tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

aby nowe okna tmux $SSH_AUTH_SOCKustawiły się poprawnie. Wolałbym tego nie robić. Jakieś pomysły?

Aktualizacja

Myślę, że nie wyjaśniam tego dobrze. Oto moja funkcja powłoki, aby otworzyć powłokę na zdalnym komputerze:

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

Kiedy tmux uruchamia to polecenie ssh, nie$SSH_AUTH_SOCK jest ustawione, mimo że jest ustawione w moim lokalnym środowisku. Jeśli umieszczę to w środowisku tmux za pomocą powyższego polecenia, wszystko działa dobrze. Moje pytanie brzmi: dlaczego w ogóle muszę uruchamiać komendę setenv?setenv

Aktualizacja 2

Więcej informacji:

Gdy dołączam się do istniejącej sesji, $SSH_AUTH_SOCKnie jest ustawiony w środowisku tmux (lub środowisku globalnym).

% tmux showenv | grep -i auth_sock
-SSH_AUTH_SOCK

Jeśli ustawię to ręcznie, wszystko działa:

% tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

Jeśli odłączę się i ponownie dołączę, $SSH_AUTH_SOCKwróci do nie ustawiania.

Chris W.
źródło
W ogóle nie chodzi o SSH, prawda? Jakie zmienne środowiskowe masz w nowej powłoce, jakie są dane wyjściowe env?
Hauke ​​Laging
Jakiej powłoki używasz na komputerze Mac? Grzmotnąć?
slm
@HaukeLaging Tak naprawdę chodzi o tmux.
Chris W.
@slm Używam zsh.
Chris W.
Co z istniejącymi oknami? Czy oni nadal działają?
Hauke ​​Laging

Odpowiedzi:

35

Ponieważ otrzymałem nagrodę, ponownie opublikuję mój kluczowy komentarz w celu zapewnienia kompletności - aby uniknąć umieszczania gości z tym samym problemem na niewłaściwym torze:

Tmux usunie zmienne środowiskowe

Strona man Tmuxa stwierdza, że ​​update-environment usunie zmienne „nieistniejące w środowisku źródłowym [...] tak, jakby -r podano komendzie set-environment”.

Najwyraźniej to spowodowało problem. Zobacz odpowiedź Chrisa poniżej . Jednak nadal nie wyobrażam sobie, jak zmienna może być nieobecna w „środowisku źródłowym”, a jednocześnie być poprawna w nowo utworzonym oknie tmux ...


Poprzednia odpowiedź:

Jak działa przekazywanie SSH

Na zdalnym komputerze spójrz na środowisko swojej powłoki po ustanowieniu połączenia 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

Ważnym tutaj jest SSH_AUTH_SOCK, który jest obecnie ustawiony na jakiś plik w / tmp. Jeśli przyjrzysz się temu plikowi, zobaczysz, że jest to gniazdo domeny uniksowej - i jest on podłączony do konkretnego wystąpienia ssh, w którym się połączyłeś. Co ważne, zmienia się to przy każdym połączeniu.

Po wylogowaniu ten konkretny plik gniazda zniknie. Teraz, jeśli pójdziesz i ponownie przełączysz sesję tmux, zobaczysz problem. Ma środowisko od momentu uruchomienia tmux - co mogło być tygodnie temu. To szczególne gniazdo już dawno nie żyje.

Rozwiązanie

Ponieważ wiemy, że problem ma związek ze świadomością, gdzie aktualnie znajduje się gniazdo uwierzytelniania SSH, po prostu umieśćmy je w przewidywalnym miejscu!

W pliku .bashrc lub .zshrc na zdalnym komputerze dodaj następujące elementy:

# 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

Nie sądzę, że musisz nawet umieścić polecenie aktualizacji środowiska w tmux.conf. Według strony man , SSH_AUTH_SOCK jest już objęta domyślnie.

Kredyt

Moja odpowiedź jest fragmentem tego postu na blogu autorstwa Marka „xb95” Smitha, który wyjaśnia ten sam problem dotyczący ekranu .

djf
źródło
Dziękuję za miłą odpowiedź. Moje pytanie nie dotyczy ustawiania mojego $SSH_AUTH_SOCKw nowych powłokach, chodzi o ustawianie $SSH_AUTH_SOCKw nowych oknach Tmux przed .bashrc / .zshrc.
Chris W.
@ChrisW. Założyłem, że skrypt powinien zostać umieszczony w pliku rc powłoki logowania na zdalnym komputerze. Jeśli się zalogujesz, pojawi się nowa powłoka, SSH_AUTH_SOCK zostanie zmieniony i wyeksportowany . Kiedy uruchomisz tmux, odziedziczy SSH_AUTH_SOCK ze środowiska nadrzędnego. Ponieważ wartość SSH_AUTH_SOCK jest teraz ustalona, ​​tmux powinien kontynuować pracę przy kolejnych logowaniach ... Może źle zrozumiałem problem
djf
Myślę, że moje zamieszanie dotyczy środowiska, w którym ssh jest uruchamiany przez tmux w kontekście nowego okna (np tmux neww ssh somehost.).
Chris W.,
Jednym z problemów z tym podejściem jest to, że drugie połączenie SSH z maszyną zastąpi wartość parametru SSH_AUTH_SOCK. To podejście działa tylko wtedy, gdy sesja tmux jest otwarta przez najnowsze połączenie SSH.
phylae,
12

Zrozumiałem to. Krótka odpowiedź, musiałem usunąć SSH_AUTH_SOCKz update-environment. Ponieważ znajdowała się na tej liście, wartość była zdejmowana za każdym razem, gdy ponownie podłączałem się. Dzięki @djf za wskazówkę. Istotny bit ze strony podręcznika man tmux (1) w update-environmentsekcji:

Wszelkie zmienne, które nie istnieją w środowisku źródłowym, są ustawione do usunięcia ze środowiska sesji (tak jakby -r podano komendzie set-environment).

Chris W.
źródło
1
@ChrisW. czy mógłbyś być trochę bardziej jasny? Myślę, że mam ten sam problem: czasami agent przestaje działać, kiedy ponownie przyłączam sesje Tmux. Ma to pewien sens, ponieważ połączenie SSH jest nowe i kiedy ssh uruchomi nowego agenta. Co muszę zmienić, aby działało? Mam nadzieję, że mogę coś uruchomić, ponieważ nie chcę ponownie konfigurować każdej maszyny, na której przesyłam. - Teraz mam opakowanie ssh, które uruchamia tmux zdalnie lub przywraca istniejące połączenia, prawdopodobnie mógłbym coś zrobić przed przywróceniem tmux.
sorin
@ChrisW. krótkie odpowiedzi są czasem miłe, ale czy mógłbyś podać długą odpowiedź? Mam problem z uruchomieniem tego i nic w tym poście nie działa dla mnie.
redbmk
@sorin @redbmk Przepraszamy za to. To jedyny wiersz, który musiałem zmienić, .tmux.confaby to zadziałało: set -g update-environment "SSH_ASKPASS WINDOWID SSH_CONNECTION XAUTHORITY" czy widzisz problemy ze sshzmiennymi środowiskowymi?
Chris W.
2

Zamiast używać tmux do obsługi mojego agenta ssh, mam bash obsługiwać go za pomocą:

### 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 ### }}}

Mam to w moim ~ / bashrc i działa świetnie.

poważny
źródło
$SSH_AUTH_SOCKjest poprawnie ustawiony w moich powłokach, ale kiedy zrobię coś takiego tmux neww ssh somehost, zostanie wyświetlony monit o moje hasło do odblokowania mojego klucza prywatnego, chyba że uruchomię tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK.
Chris W.
1

Odpowiedziałem na podobne pytanie na StackOverflow https://stackoverflow.com/a/49395839/241025 . Ponieważ ta strona pojawiła się jako pierwsza w moich wyszukiwaniach w Google, chciałem opublikować tutaj jej skróconą wersję.

Aby każda sesja tmux miała zestaw niestandardowych zmiennych środowiskowych, musisz dodać wartości do zmiennych środowiskowych na sesję tmux. Oto przykład, jak to zrobić.

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

Konieczny jest ostatni krok jawnego eksportu FOO, aby bieżący panel mógł pobrać zmienną środowiskową. Wszelkie kolejne panele lub okna tworzone dla tej sesji tmux odziedziczą FOO, ale nie pojawią się w innych sesjach.

RobotNerd
źródło
0

Wyjaśnienie djf przywołuje mi inne możliwe rozwiązanie:

Przed tmux/ screenjest uruchomiony:

  1. Zaloguj Się.
  2. Uruchom instancję ssh-agent.
  3. Rozpocznij tmux/ screenze zmiennymi środowiskowymi dla tego ssh-agent.

Nie można użyć przekazywania SSH do klienta, ale nie został o to poproszony.

Hauke ​​Laging
źródło
1
ssh-agentnie wiąże się z TTY, dlaczego należy go zabić przy wylogowaniu (?) - po co używać nohup?
poige
@poige Prawidłowe.
Hauke ​​Laging