ssh-agent не добавляет ключ при графическом запуске

ssh-agent не добавляет ключ при графическом запуске

Недавно я добавил следующий скрипт в автозапуск (в KDE):

eval `ssh-agent`
ssh-add

Скрипт должен запускаться при входе в систему, запрашивать мою парольную фразу и загружать мой секретный ключ. Он работает почти нормально. Скрипты выполняются правильно, агент запускается, переменные среды устанавливаются, и меня просят ввести мою парольную фразу. Единственная проблема в том, что после этого ключ не загружается. Но если я затем ввожу ssh-add в терминал, меня просят ввести мою парольную фразу, и ключ сохраняется для оставшейся части моего X-сеанса.

Что я делаю не так? Почему ключ не загружается, хотя меня просят ввести пароль?

PS: Я работаю на Debian jessie.

решение1

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

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

  1. Ваш менеджер рабочего стола запускает собственный SSH-агент после того, как вы запустите свой, и в итоге он его заменяет.

    Я не уверен, в какой момент или как вы запускаете свой агент SSH, но если менеджер рабочего стола запустит его после вашего, его экспортированные переменные переопределят те, которые вы создали.

  2. Ваш менеджер рабочего стола запускает свой собственный агент SSH раньше вашего, и ваш агент не сохраняется.

    Если вы просто запускаете окно терминала и делаете eval $(ssh-agent); ssh-add, то экспортированные им переменные ssh-agentне сохранятся после закрытия окна терминала. После запуска нового окна терминала вы получите переменные, установленные агентом ssh, запущенным менеджером рабочего стола.


Суть ssh-agentработы заключается в том, что в фоновом режиме запускается демон, а затем выводится несколько переменных, которые необходимо настроить.

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-JLbBwVBP4754/agent.4754; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4755; export SSH_AGENT_PID;
echo Agent pid 4755;

Поэтому, когда вы eval $(ssh-agent), вы просто устанавливаете все эти переменные.

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

решение2

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

  1. менеджер сеансов делает это внутренне (в зависимости от какой-то установленной вами опции). Это включает в себя агента, порождаемого модулем PAM (вызываемым из менеджера входа/сеансов).

  2. через пользовательский скрипт, такой как ваш. Однако это не так просто, как может показаться. Когда менеджер сеансов запускает ваш скрипт, он создает новый процесс — интерпретатор скриптов. В его среде переменные устанавливаются, но их нельзя легко экспортировать обратно в менеджер сеансов — его родительский процесс. Это эквивалентно выполнению того же самого в вашей оболочке — запуск скрипта никак не повлияет на среду текущей оболочки. Вам придется sourceэто сделать — тогда команды будут выполнены текущей оболочкой, что даст вам доступ к обновленным/созданным переменным. Это было бы довольно сложно сделать в менеджере сеансов (так как он не является интерпретатором оболочки). Таким образом, ваш ssh-agentна самом деле не конкурирует. Он просто сидит там с идентификаторами, загруженными ssh-addиз вашего скрипта, и никто на самом деле не знает об этом.

Чтобы получить некоторое представление о том, что происходит, проверьте вывод 1

ps fax | grep -E "(ssh|gpg)-[a]gent"

и измените свой сценарий на

echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > ~/ssh-agent.stdout
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> ~/ssh-agent.stdout
eval `ssh-agent | tee -a ~/ssh-agent.stdout`

Это выведет содержимое переменных в файл ~/ssh-agent.stdout, а затем добавит вывод из ssh-agentв то самое место перед его обработкой (и, таким образом, экспортом переменных). Сравните содержимое файла с переменными среды SSH_AUTH_SOCKи, SSH_AGENT_PIDнапример, в свежесозданном терминале оболочки. В большинстве случаев вы сможете сказать, какой из них был запущен первым, поскольку PID (циклически) монотонно растут. Эта часть там, потому что некоторые DE также gpg-agentиспользуют возможность предоставлять услуги SSH-агента.gpg-agent

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


1 скобки - этоловкий трюкчтобы удалить grepсебя из списка процессов.

Связанный контент