Debian.pro/

Про Debian


SSH-Agent Forwarding и screen

Статью мне прислал selivan. Как обычно, прилагаю её без каких-либо изменений.

В предыдущих статьях SSH ключи и Гуляем с сервера на сервер с одним ssh-ключом. SSH-agent forwarding inkvizitor68sl рассказал, как использовать ssh-ключи для удобной и безопасной прозрачной авторизации на разных серверах. К сожалению, если на одном из серверов используется screen — после обрыва сессии и повторного подключения Forwarding работать перестаёт. Но с помощью лома и какой-то там матери это проблема легко решаема :)

Когда ssh-слиент с включенным ForwardAgent подсоединяется к серверу, он создаёт сокет, сокет, через который можно получить этот самый ключ, и указывающую на него переменную $SSH_AUTH_SOCK, которую наследует запущенный в рамках сессии шелл. Кроме неё, создаются ешё несколько переменных: $SSH_CLIENT, $SSH_CONNECTION, $SSH_TTY, в которых хранится информация о текущем ssh-подключении.

Когда мы запускаем screen и присоединяемся к уже запущенной сессии — запущенные в рамках его сессии шеллы сохранят старые значения этих переменных(сокет при каждом подключении, разумеется, создаётся новый) — и Forwarding в них не заработает. Нам нужно где-то сохранять состояние этих переменных при подключении и при необходимости их перечитывать. Сделаем так:

.bashrc:


parent="$(ps -o comm --no-headers $PPID)"

case $parent in
sshd)
keep_vars="SSH_CLIENT SSH_TTY SSH_AUTH_SOCK SSH_CONNECTION DISPLAY XAUTHORITY"
touch $HOME/.ssh/keep_vars
chmod 600 $HOME/.ssh/keep_vars
for i in $keep_vars; do
(eval echo export $i=\\\'\$$i\\\')
done > $HOME/.ssh/keep_vars
;;
screen)
source $HOME/.ssh/keep_vars
;;
esac

# This command must be run from shell within detached and re-attached screen session
# to interact with ssh-agent properly
alias fixssh="source $HOME/.ssh/keep_vars"

alias ssh='source $HOME/.ssh/keep_vars; ssh'
alias scp='source $HOME/.ssh/keep_vars; scp'

Если шелл запущен из ssh-сессии, он сохранит значение переменных в файл ~/.ssh/keep_vars. Если шелл запущен из screen, он их перечитает при запуске. Если шелл уже висел в screen — переменные будут перечитаны при первом запуске ssh или scp. Для принудительного перечитывания переменных есть комманда fixssh.

15.12.2011 byinkvizitor68sl|Заметки
Метки: , ,

Комментарии (15):

  1. Ярослав :

    Скажи норм книгу по shell — программированию, bash, кроме Дейвида Тэйнсли

  2. C admin.com начните (там есть глава про скрипты на баше). А потом ставьте себе реальные задачки и решайте их при помощи гугла.

  3. selivan :

    Shell хорош для небольших скриптов, потому что позволяет быстро и удобно связать несколько консольных программ. Для более сложных задач есть python/ruby/perl

  4. Та лаааадно. На баше можно всё написать. Вопрос только в скорости работы этого «всего».

  5. Aectann :

    Ну и Advanced Bash Scripting Guide.

  6. Aectann :

    Это к первому комментарию ответ, если что.

  7. selivan :

    Можно-то можно, люди вон на sed’e тетрисы пишут. Но всё-таки выбор подходящего инструмента уменьшает сложность решения задачи.

  8. toywar :

    Ну тут уже что кому по душе. Я, например, люблю на bash’е делать. Хотя уверен, что с python’ом это делается еще проще и быстрее.

  9. Написал кучу ненужностей. Решается всё банальным экспортом нового ssh_auth_sock
    export SSH_AUTH_SOCK=$(find /tmp -name «agent*[0-9]» 2>/dev/null)

  10. selivan :

    insider: а если в системе залогинено несколько пользователей? А если только один, но запущено несколько сеансов? Тогда несколько файлов agent* даже по владельцу не отличишь

  11. selvian: У меня приведенный в статье совет не сработал, сработало изменение всего лишь одной переменной SSH_AUTH_SOCK, на что я и указал в своем комментарии. Я не утверждаю, что мое решение претендует на звание лучшего, просто оно короче и эффективней в моем случае.
    В:Если в системе залогинено несколько пользователей?
    О:Если у тебя не рутовые привилилегии, то ты не сможешь просмотреть содержимое их папки ssh в tmp и find выдаст ошибку, которая уйдет в /dev/null.

    В: Если запущено несколько сеансов?
    О: По-моему, глупо заходить на один сервер несколько раз, тем более, если ты уже умеешь пользоваться screen.

  12. selivan :

    Итого: если привелегии рутовые, я подхвачу чужой ssh-agent. Если не рутовые — может не сработать.
    Кстати, а это отличная мысль — если я дал кому-то доступ на сервер по ключу, и он использует ssh-agent(или putty-agent), не получится ли у меня утащить его другие ключи из агента? Наверное, нет, но попробовать интересно

    Несколько сеансов может быть запущено, например, потому что не я один отвечаю за сопровождение этого сервера.

  13. selvian: Если не рутовые, то сработает. Проверь.
    Я даже нашел чей-то скриптик, делающий нечто подобное моим изысканиям.
    https://github.com/remibergsma/screen-ssh-agent-updater

    По поводу утащить ключи, думаю, что получится только авторизоваться, воспользовавшись чужим ключом, но сам ключ, не удастся посмотреть.

  14. selivan :

    insider: это https://github.com/remibergsma/screen-ssh-agent-updater сработает, он там ещё и ID пользователя проверяет. Да, вобщем проще. Зато мой вариант не ломается и при логине нескольких человек под одним пользователей, у каждого остаётся личный ssh-agent :)

    А вообще, надо на tmux переползать, он веселее развивается(screen не обновлялся с 2006) и у него из коробки есть вот такое:

    set -g update-environment «DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY»

Написать комментарий