ssh-agent и screen


8

Некоторое время назад на StackOverflow я задал этот вопрос о ssh-agent и crontab . У меня сейчас похожий вопрос о ssh-agent и screen в системах linux.

Итак, на моем Mac ssh-agent запускается при запуске системы, поэтому он всегда доступен для меня. Я думаю, что это было бы верно под моим Linux (Redhat El5 / Fedora), если бы я использовал X-Windows. Тем не менее, это удаленный сервер, и я всегда захожу через ssh.

Я хотел бы, чтобы ssh-ключи были настроены правильно, чтобы мне не приходилось вводить свой пароль несколько раз во время svn-обновления или фиксации. Я счастлив вводить парольную фразу один раз за сеанс, и я не рекомендую нашей команде использовать ssh-ключи без пароля.

В какой-то короткий момент мне показалось, что в моем .bash_profile было выполнено «eval` ssh-agent -s` », в сочетании с командой убить ssh-agent, когда я вышел из системы. Тем не менее, мы интенсивно используем экран для управления длительными интерактивными программами и средами разработки. Если вы запускаете и останавливаете ssh-agent, как я только что описал, то он убивается, когда вы выходите из терминала, а подсессии экрана, которые раньше ссылались на этот экземпляр ssh-agent, прекращаются.

Итак ... как я могу быть пользователем консоли, который использует экран, который использует пароль со своими ssh-ключами, которому не нужно постоянно вводить фразу-пароль?

Ответы:


4

При следующей настройке вам не понадобится никакой оболочки для вызова screen. Более того, он избегает использования /tmp(с вытекающими отсюда рисками безопасности).

  1. Убедитесь, что у вас есть каталог ~ / tmp:

    mkdir ~/tmp
    
  2. Добавьте к .screenrcследующей строке:

    setenv SSH_AUTH_SOCK "$HOME/tmp/ssh-agent-screen"
    
    • Это гарантирует , что внутри screen, sshвыглядит для сокета всегда в том же месте, а не меняющийся пути.
    • Вы должны использовать setenvлюбую оболочку, которую используете, поскольку это экран, а не команда оболочки.
  3. Добавьте к .bash_profileследующей строке:

    [ -n "$SSH_AUTH_SOCK" ] && [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ] && ln -sf "$SSH_AUTH_SOCK" "$HOME/tmp/ssh-agent-screen"
    
    • Это будет связывать фиксированное местоположение (где sshвыглядит) с реальным, и должно появиться после запуска ssh-agent.
    • Использование [ -n "$SSH_AUTH_SOCK" ]правильно предотвратит ошибки, когда SSH_AUTH_SOCKне установлено.
    • [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ]предотвратит сеансы экрана, связывающие $ HOME / tmp / ssh-agent-screen с самим собой, если источники экрана .bash_profile.
  4. Вместо того чтобы начать ssh-agentв .bash_profile, вы можете рассмотреть возможность соединения с ssh -A(с использованием форвардингом агента и сделать использование удаленной машины вашего агента).

После этой настройки вы можете просто использовать стандартную экранную команду. Вам нужно будет только воссоздать существующие сеансы или вручную установить SSH_AUTH_SOCK внутри них в фиксированное положение шага 2.

Кредиты на этот сайт для идеи; Я избегал использования /tmp. Этот ответ похож, но использует дополнительные псевдонимы.


2

Можете ли вы запустить ssh-agent из initscript вместо .bash_profile? Например, я мог бы поставить

su -c 'ssh-agent -s > ~/.ssh_agent_env' myusername

в соответствующей части /etc/conf.d/local, хотя RHEL / Fedora, вероятно, использует другую систему. Как вы указали в своем комментарии, терминальные сеансы должны будут иметь возможность подключаться к агенту, поэтому эта команда создает файл .ssh_agent_envв домашнем каталоге пользователя. Тогда вы можете добавить

[ -f ~/.ssh_agent_env ] && source ~/.ssh_agent_env >/dev/null

в .bash_profile.

Еще одна вещь, которую вы могли бы сделать, это поместить следующее в .bash_profile

ps -U myusername | grep -q ssh-agent || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

который начнется ssh-agentтолько если он еще не запущен. Тогда вам не нужно убивать это.

В качестве немного другой альтернативы второму предложению, вместо проверки существования ssh-agentпроцесса, вы можете проверить наличие файла ~/.ssh_agent_env,

[ -f ~/.ssh_agent_env ] || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

Если все работает правильно, между этими двумя способами не должно быть существенной разницы.


Идея initscript интересна - в основном, просто запустите ее при запуске системы для всех пользователей, которые этого хотят? Это может сработать. У нас не так много пользователей, которым было бы все равно. Является ли это значительно лучше, чем отсутствие парольной фразы, - интересный вопрос, поскольку я подозреваю, что это означает, что вам нужно будет вводить его только один раз при перезагрузке компьютера. Хм. И то, и другое предложение основаны на возможности подключения новых терминальных сеансов к ssh-агенту, если он уже запущен. Я не совсем уверен, что это так просто, но я еще не пробовал. Спасибо за идеи!
Майкл Х.

@khedron: Да, но вам нужно было бы вставить одну строку /etc/conf.d/local(или ваш эквивалент) для каждого пользователя, который использует агент, чтобы запустить отдельный ssh-agentпроцесс для каждого пользователя. Если, как вы говорите, у вас нет огромного количества пользователей, это не так уж плохо. Вы подняли хороший вопрос (который я забыл рассмотреть) о терминальных сеансах, подключаемых к агенту; см. мое изменение к ответу.
Дэвид Z


2

Лучше всего использовать пересылку по ssh-агенту ( -Aопция). Это позволяет человеку, использующему ssh, использовать ключи от ssh-agent, работающего на машине, с которой они приходят, предположительно на рабочей станции, на которой они фактически сидят.


Это также позволяет злоумышленнику, который скомпрометирует вашу учетную запись, скомпрометировать учетные записи на других компьютерах, к которым этот агент может получить доступ. Поэтому я стараюсь свести к минимуму переадресацию агента ssh.
Пол Прайс

2

чтобы продолжить переадресацию агента ssh, вы обнаружите, что по умолчанию перенаправленные учетные данные ssh не будут доступны вашему экранному сеансу после выхода, повторного входа и повторного подключения к сеансу.

Однако вы можете обойти это, установив на экран переменную среды SSH_AUTH_SOCK, которая будет известна, и обновив это известное местоположение до текущего сокета аутентификации.

Я использую эту функцию оболочки для повторного входа в экран и исправления ssh auth sock:

function sr () { 
    if [ ${+STY} = 1 ] ;then 
            echo already in screen\!
    else
            if [ "${SSH_AUTH_SOCK}x" != "x" ]; then
                    if [ ! -d /tmp/screenssh ]; then
                            mkdir /tmp/screenssh 
                    fi
                    rm -f /tmp/screenssh/socket
                    ln -s $SSH_AUTH_SOCK /tmp/screenssh/socket
                    echo $REMIP > /tmp/screenssh/remip
            fi                
            screen -DR
    fi
}

и у меня есть это в моем .screenrc:

setenv SSH_AUTH_SOCK /tmp/screenssh/socket

Надеюсь это поможет.


Использование / tmp означает, что кто-либо еще на машине может уничтожить любой из ваших файлов, если он знает их путь.
Blaisorblade

1

Если я вас правильно понял, вам просто нужен сеанс экрана, который вы иногда отсоединяете и снова подключаете, но больше никогда не хотите вводить пароли для ssh-agent (пароль вашего личного ключа).

Я думаю, что самый простой способ - запустить экран, чем запустить ssh-agent с помощью вспомогательной оболочки, а затем остаться в этой вспомогательной оболочке. Т.е.

screen
ssh-agent bash
ssh-add   # enter your password once

# some commands, some logins and logouts to remote servers via ssh public key

# <ctrl>+<a>, <ctrl>+<d> to detach screen
# you can now logout from this computer
# login again

# reattach to your screen
screen -r
# ssh-agent is still running

Это по сути то, что я делаю. Я использую экран, чтобы пометить одну из «вкладок» внутри как обладающую полномочиями ssh-agent, и использую ее для работы svn и т. Д. Есть дополнительная складка, когда я заставляю ssh-agent повторно авторизоваться через несколько часов, но да, это в основном то, где я нахожусь.
Майкл Х.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.