Почему я должен переустанавливать env vars в tmux при повторном присоединении?

37

В основном я работаю над подключением mac и ssh / tmux к машине Linux, чтобы выполнять свою работу. У меня есть ssh-agent, работающий на машине с Linux. я имею

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

по моему .tmux.conf. Тем не менее, всякий раз, когда я снова присоединяюсь к этой сессии, я должен

tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

для того, чтобы новые окна tmux были $SSH_AUTH_SOCKустановлены правильно. Я бы предпочел не делать этого. Любые идеи?

Обновить

Я думаю, что я не объясняю это хорошо. Вот моя функция оболочки для открытия оболочки на удаленной машине:

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

Когда tmux запускает эту команду SSH, $SSH_AUTH_SOCKэто не установлен, даже если он будет установлен в моей локальной среде. Если я поместил это в окружение tmux с помощью setenvкоманды выше, все работает нормально. У меня вопрос, почему я вообще должен запускать команду setenv?

Обновление 2

Больше информации:

Когда я присоединяюсь к существующему сеансу, $SSH_AUTH_SOCKне устанавливается в среде tmux (или глобальной среде).

% tmux showenv | grep -i auth_sock
-SSH_AUTH_SOCK

Если я установлю это вручную, все будет работать:

% tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

Если я отсоединяюсь и снова присоединяюсь, $SSH_AUTH_SOCKпроисходит возврат к неустановленному.

Крис У.
источник
Это вообще не про SSH, не так ли? Какие переменные окружения у вас есть в новой оболочке, из чего получается env?
Хауке Лагинг
Какую оболочку вы используете на Mac? Bash?
SLM
@HaukeLaging Это действительно о tmux.
Крис У.
@slm Я использую Zsh.
Крис У.
Как насчет существующих окон? Они все еще работают?
Хауке Лагинг

Ответы:

35

С тех пор, как я получил Баунти, я перепишу свой ключевой комментарий для полноты картины - и чтобы не ставить посетителей с той же проблемой на неправильном пути:

Tmux удалит переменные окружения

Страница руководства Tmux утверждает, что update-environment удалит переменные, «которые не существуют в исходной среде [...], как если бы -r был задан команде set-environment».

Видимо это то, что вызвало проблему. Смотрите ответ Криса ниже . Тем не менее, я до сих пор не представляю, как переменная может отсутствовать в «исходной среде» и быть действительной во вновь созданном окне tmux ...


Предыдущий ответ:

Как работает SSH forwarding

На удаленной машине посмотрите на среду вашей оболочки после установки 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

Важным здесь является SSH_AUTH_SOCK, который в настоящее время настроен на какой-то файл в / tmp. Если вы изучите этот файл, то увидите, что это сокет домена Unix - и он связан с конкретным экземпляром ssh, к которому вы подключились. Важно отметить, что это меняется каждый раз, когда вы подключаетесь.

Как только вы выйдете, этот конкретный файл сокета исчезнет. Теперь, если вы пойдете и снова подключите сеанс tmux, вы увидите проблему. В нем есть среда, с которой первоначально был запущен tmux, что могло быть несколько недель назад. Эта конкретная розетка давно умерла.

Решение

Поскольку мы знаем, что проблема заключается в том, чтобы знать, где сейчас находится действующий сокет аутентификации SSH, давайте просто поместим его в предсказуемое место!

В файле .bashrc или .zshrc на удаленном компьютере добавьте следующее:

# 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

Я не думаю, что вам даже нужно поместить команду update-environment в ваш tmux.conf. Согласно справочной странице , SSH_AUTH_SOCK уже включен по умолчанию.

кредит

Мой ответ - отрывок из этого поста Марка Смита, который объясняет ту же проблему для экрана .

DJF
источник
Спасибо за ваш вдумчивый ответ. Мой вопрос не о настройке my $SSH_AUTH_SOCKв новых оболочках, а о настройке $SSH_AUTH_SOCKв новых окнах tmux до получения .bashrc / .zshrc.
Крис У.
@ChrisW. Я предполагал, что скрипт должен быть помещен в rc-файл вашей оболочки входа в систему на удаленной машине. Если вы войдете в систему, появится новая оболочка, SSH_AUTH_SOCK будет изменен и экспортирован . Когда вы затем запустите tmux, он унаследует SSH_AUTH_SOCK из родительской среды. Поскольку значение SSH_AUTH_SOCK теперь исправлено, tmux должен продолжать работать при последующих входах в систему ... Возможно, я неправильно понял проблему
djf
Я предполагаю, что моя путаница связана со средой, в которой ssh ​​запускается tmux в контексте нового окна (например tmux neww ssh somehost).
Крис У.
Одной из проблем этого подхода является то, что 2-е соединение SSH с машиной перезапишет значение SSH_AUTH_SOCK. Этот подход работает только тогда, когда сеанс tmux открыт через самое последнее соединение SSH.
Фила
12

Я понял это. Короткий ответ, мне нужно удалить SSH_AUTH_SOCKиз update-environment. Так как это было в этом списке, ценность сдувалась каждый раз, когда я снова прикреплялся. Спасибо @djf за подсказку. Существенный бит со страницы руководства tmux (1) в update-environmentразделе:

Любые переменные, которые не существуют в исходной среде, должны быть удалены из среды сеанса (как если бы команда-окружения была задана -r).

Крис У.
источник
1
@ChrisW. не могли бы вы быть немного более понятным? Я думаю, что у меня та же проблема: иногда агент перестает работать, когда я заново подключаю сеансы tmux. Это имеет некоторый смысл, так как соединение SSH является новым, и когда я ssh, он запустит новый агент. Что я должен изменить, чтобы это работало? Я надеюсь, что это то, что я могу запустить, потому что я не хочу перенастраивать каждую машину, в которую я работаю. - Теперь у меня есть оболочка ssh, которая запускает tmux удаленно или восстанавливает существующие соединения, возможно, я могла бы что-то сделать до восстановления tmux.
сорин
@ChrisW. короткие ответы иногда хороши, но не могли бы вы дать длинный ответ? Я изо всех сил пытаюсь заставить это работать, и ничто в этом посте не работает для меня.
Redbmk
@sorin @redbmk К сожалению об этом. Это единственная строка, которую мне пришлось изменить в своей работе, .tmux.confчтобы заставить это работать: set -g update-environment "SSH_ASKPASS WINDOWID SSH_CONNECTION XAUTHORITY" вы видите проблемы sshили переменные среды в целом?
Крис В.
2

Вместо того, чтобы использовать tmux для управления моим ssh-агентом, я использую bash:

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

У меня есть это в моем ~ / bashrc , и это прекрасно работает.

скромный
источник
$SSH_AUTH_SOCKнастроен правильно в моих оболочках, но когда я сделаю что-то подобное tmux neww ssh somehost, мне будет предложено, чтобы моя фраза-пароль разблокировала мой закрытый ключ, если я не запустился tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK.
Крис В.
1

Я ответил на аналогичный вопрос на StackOverflow https://stackoverflow.com/a/49395839/241025 . Так как эта страница появилась первой в моих поисках в Google, я хотел опубликовать ее краткую версию здесь.

Чтобы каждый сеанс tmux имел набор пользовательских переменных среды, вы должны добавить значения в переменные среды tmux для каждого сеанса. Вот пример того, как это сделать.

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

Последний шаг явного экспорта FOO необходим для того, чтобы текущая панель выбрала переменную среды. Любые последующие панели или окна, которые вы создаете для этого сеанса tmux, будут наследовать FOO, но не будут отображаться в других сеансах.

RobotNerd
источник
0

Объяснение DJF приносит другое возможное решение в моем уме:

До tmux/ screenработает:

  1. Авторизоваться.
  2. Начать экземпляр ssh-agent.
  3. Начните tmux/ screenс переменной (ов) среды для этого ssh-agent.

Это не могло использовать пересылку SSH клиенту, но это не было запрошено.

Хауке Лагинг
источник
1
ssh-agentне привязывается к TTY, почему он должен быть убит при выходе из системы (?) - зачем использовать nohup?
Пой
@poige Правильно.
Хауке Лагинг