Как получить пароль для ключевой фразы SSH один раз и только при необходимости?

15

(Я прочитал многие вопросы на этом сайте, которые выглядят взаимосвязанными, и я считаю, что это действительно новый вопрос.)

У меня много ключей на многих серверах, и все они защищены парольными фразами.

Мне нравится вводить парольные фразы примерно так же, как я люблю вводить пароли - это реальное снижение производительности.

  • Команды ssh-agent + ssh-add могут быть использованы в оболочке входа в систему, что означает, что вам нужно вводить вашу фразу-пароль только один раз при входе в систему

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

У меня проблема в том, что оба эти решения, как правило, инициируются при входе в оболочку (например .zshrc), полагаются на то, что я ввожу свою фразу-пароль при входе в систему, даже если она мне не понадобится разблокирована. (Я не доволен, что связка ключей поддерживает агента живым бесконечно долго.)

То, что я хотел бы, чтобы мне предлагали пароль (для агента) только при необходимости .

Таким образом, я могу войти на сервер A, сделать что-то, затем ssh на сервер B и в этот момент попросить пароль. Сделайте что-нибудь на сервере B, выйдите из системы. Вернитесь к A, сделайте еще кое-что, снова отправьте ssh в B и не нуждайтесь в моей парольной фразе (она удерживается агентом).

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

artfulrobot
источник
Почему бы просто не генерировать ssh-ключи без паролей? Если вы все равно собираетесь пройти через все эти неприятности?
devnull
1
Если кто-то взломает и у него есть ключи без пароля (или активный агент ssh), они также могут иметь доступ ко многим другим серверам. Кроме того, ключи без пароля могут быть украдены и использованы в другом месте.
artfulrobot
Насколько я знаю, нет способа делать то, что вы хотите, не жертвуя каким-то уровнем безопасности, а это звучит так, будто вы этого не хотите. Томас Найман дал исчерпывающий ответ, который открывает множество возможностей, если вы еще не читали его: unix.stackexchange.com/a/90869/82289 . Я справляюсь с этим в своей компании, используя промежуточный сервер, который управляет сессиями ssh с Tmux.
devnull
@DevNull кажется странным, что вы можете сделать это с рабочего стола, но не с терминалом, нет? Конечно, просто нужно, чтобы агент перешел на tty, если ключи не были добавлены? Это должно быть способ, которым работают gui?
artfulrobot
Вы можете посмотреть мой ответ здесь: unix.stackexchange.com/a/184160/89706 (ссылка на вопрос: unix.stackexchange.com/questions/90853/… )
Джонни Вонг

Ответы:

16

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

Вместо этого добавьте

AddKeysToAgent yes

в ваш .ssh / config

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

Тоби
источник
Я хотел бы, чтобы люди комментировали, когда голосовали против. Если это не правильно, это важно, мы знаем, почему это не правильно. Спасибо за публикацию, я не успел попробовать ваше предложение сам.
artfulrobot
Мне тоже интересно, может из-за моих кросс-постов?
Тоби
Это работает для меня. Однако это очень недавнее дополнение к openssh (7.2). В случае, если это кому-нибудь поможет, openssh 7.3 доступен в Debian Sid.
artfulrobot
@artfulrobot: Странно, так как у меня такое же поведение (auto-ssh-add при первом вызове ssh) работало годами, пока оно наконец не прекратилось некоторое время назад. В поисках причины я нашел AddKeysToAgent и предположил, что причиной его остановки было то, что я случайно очистил мой .ssh / config и AddKeysToAgent вместе с ним. Теперь мне интересно, почему он работал задолго до выхода OpenSSH 7.2? Я не воображаю это :-)
Тоби
@ Тоби, это именно то, что мне нужно. К сожалению, ssh-agent не запускается автоматически в kubuntu, поэтому мне нужно решить следующую проблему.
Огадай,
7

У Zsh есть preexecловушка, которая выполняет функцию перед выполнением команды, введенной в командной строке. Вот хук, который ищет sshв вашей командной строке и, если найден, проверяет существование агента ssh. Если это не найдено, он запускает связку ключей.

Таким образом, цепочка для ключей запускается только перед командами ssh, и только тогда, когда это необходимо.

Поместите это в свой ~/.zshrc:

function check_ssh {
  [[ $3 =~ '\bssh\b' ]] || return
  [[ -n "$SSH_AGENT_PID" && -e "/proc/$SSH_AGENT_PID" ]] \
    && ssh-add -l >/dev/null && return
  eval `keychain --eval id_dsa --timeout 60`
}    
autoload -U add-zsh-hook
add-zsh-hook preexec check_ssh

Здесь происходит всякий раз, когда команда набирается, check_sshвызывается до ее выполнения.

Первая строка функции проверяет расширенную команду на sshиспользование регулярного выражения Zsh. sshдолжны иметь границы слов по \bобе стороны. Если это не найдено, функция возвращается.

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

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

Он по- прежнему оставляет проблему о встроенной SSH вещи, как gitили rsyncили , scpкак это не будет вызывать функцию (вы можете добавить их в регулярное выражение).

artfulrobot
источник
Даже без zshэтого можно создать короткий сценарий с тем же эффектом и поместить его PATHперед фактическим sshклиентом. Может даже работать с rsyncet al, если они читают, PATHа не работают /usr/bin/sshнапрямую.
ilkkachu
2

Для zsh я написал набор утилит и оболочек для более или менее того, что вы хотите: https://www.vinc17.net/unix/index.en.html#zsh-ssh-utils

На самом деле это делает еще больше, потому что ssh-agentон будет использоваться всеми сеансами входа в систему (рабочий стол или через SSH, и GNU Screen также поддерживается, если вы запускаете с него оболочки входа, например, с shell -zshпомощью~/.screenrc файла), и он выйдет только после последняя сессия заканчивается

Примечание. Я использую только одну фразу-пароль для всех своих ключей. Я не уверен в поведении для разных парольных фраз; там могут потребоваться некоторые изменения.

vinc17
источник
Вау, это довольно много кода. Хорошая работа и спасибо, что поделились. Я думаю, что мне нужно что-то более простое - SSH для меня довольно важный инструмент.
artfulrobot