Вопрос или проблема
Я хочу наладить связь между несколькими компьютерами в своей сети (статический Ethernet) через SSH. Для этого мне нужно запускать ssh-add
каждый раз, когда я вхожу в определённую машину.
Что я могу сделать, чтобы это было настроено один раз и чтобы он не спрашивал у меня пароль каждый раз при входе или перезагрузке машины?
Я знаю, что есть способ добавить несколько строк в файл bash_profile
, но мне всё равно приходится вводить пароль каждый раз, когда я перезагружаю/вхожу на определённую машину.
if [ -z "$SSH_AUTH_SOCK" ] ; then
eval `ssh-agent -s`
ssh-add
fi
Это典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典典ش典典訊선典후윈典典典典典典典典典典典…
премьерика выбор배찌 디코 주제주제
비국적 장일리능
기업 각국의 무능력/무능력, 탈영 자체 전시 의미에는 고객의 요구 를 다루기 위해 관리 및 장착합니다.
비국적 장일리능
비국적 장일리능 예사, 예사, 예사, 지정된 경우와 저가 etc. 후 구매를 자유롭게 다 됩니다.
비국적 장일리능 용》
비국적 장일리능 용》
비국적 장일리능 관리 및 장착 대 금리무 능기 환률상환금 (기재되면) 금리 즉시 실 발생하면 예사하신 후가 포함 에 대한 제안이 들어오셨습니다.
Теперь пароль нужно вводить каждый раз, когда ключ используется для аутентификации. Хотя это лучший вариант с точки зрения безопасности, он обеспечивает худшую удобство использования. Это также может привести к выбору слабого пароля, чтобы уменьшить бремя его повторного ввода.
ssh-ключ с паролем, с ssh-agent
Добавление следующего в ~/.bash_profile
автоматически запустит ssh-agent
и загрузит ssh-ключи при входе:
if [ -z "$SSH_AUTH_SOCK" ] ; then
eval `ssh-agent -s`
ssh-add
fi
Теперь пароль должен быть введен при каждом входе. Хотя это немного лучше с точки зрения удобства, это имеет недостаток в том, что ssh-agent
запрашивает пароль, независимо от того, будет ли ключ использоваться в сессии входа. Каждое новое вход выполнение также создает новый экземпляр ssh-agent
, который остается запущенным с добавленными ключами в памяти даже после выхода, если он не будет явно закрыт.
Чтобы закрыть ssh_agent
при выходе, добавьте следующее в ~/.bash_logout
if [ -n "$SSH_AUTH_SOCK" ] ; then
eval `/usr/bin/ssh-agent -k`
fi
или следующее в ~/.bash_profile
trap 'test -n "$SSH_AUTH_SOCK" && eval `/usr/bin/ssh-agent -k`' 0
Создание нескольких экземпляров ssh-agent
может быть предотвращено созданием постоянного коммуникационного сокета к агенту в фиксированном месте в файловой системе, например, в ответе Колина Андерсона. Это улучшение по сравнению с созданием нескольких экземпляров агентов. Однако, если его явно не закрыть, расшифрованный ключ всё равно остается в памяти после выхода.
На настольных компьютерах ssh-агенты, включенные в среду рабочего стола, такие как SSH-агент Gnome Keyring, могут быть лучшим вариантом, так как обычно они могут быть настроены на запрос пароля в первый раз, когда ssh-ключ используется в течение сессии входа, и хранят расшифрованный закрытый ключ в памяти до конца сессии.
ssh-ключ с паролем, с ssh-ident
ssh-ident
— это утилита, которая может управлять ssh-agent
от вашего имени и загружать идентичности по мере необходимости. Она добавляет ключи только тогда, когда они нужны, независимо от того, сколько терминалов, SSH или сеансов входа требует доступа к ssh-agent
. Она также может добавлять и использовать другой агент и другой набор ключей в зависимости от хоста, к которому вы подключены, или директории, из которой вызывается ssh
. Это позволяет изолировать ключи при использовании пересылки агентов с разными хостами. Это также позволяет использовать несколько учетных записей на таких сайтах, как GitHub.
Чтобы включить ssh-ident
, установите его и добавьте следующий алиас в ~/.bash_profile
:
alias ssh="/path/to/ssh-ident"
ssh-ключ с паролем, с keychain
keychain
— это небольшая утилита, которая управляет ssh-agent
от вашего имени и позволяет ssh-agent
оставаться запущенным после завершения сессии входа. При последующих входах keychain
подключится к существующему экземпляру ssh-agent
. На практике это означает, что пароль должен быть введен только при первом входе после перезагрузки. При последующих входах используется незашифрованный ключ из существующего экземпляра ssh-agent
. Это также может быть полезно для разрешения аутентификации RSA/DSA без пароля в заданиях cron
без ssh-ключей без пароля.
Чтобы включить keychain
, установите его и добавьте что-то вроде следующего в ~/.bash_profile
:
eval `keychain --agents ssh --eval id_rsa`
С точки зрения безопасности ssh-ident
и keychain
хуже экземпляров ssh-agent
, ограниченных сроком службы определенной сессии, но они обеспечивают высокий уровень удобства. Чтобы улучшить безопасность keychain
, некоторые люди добавляют опцию --clear
к вызову keychain
в ~/.bash_profile
. При этом пароли должны быть повторно введены при входе, как указано выше, но задания cron
всё равно будут иметь доступ к незашифрованным ключам после выхода пользователя. keychain
страница вики содержит дополнительную информацию и примеры.
ssh-ключ без пароля
С точки зрения безопасности это худший вариант, поскольку закрытый ключ полностью не защищен в случае его раскрытия. Однако это единственный способ гарантировать, что пароль не придется повторно вводить после перезагрузки.
ssh-ключ с паролем, с ssh-agent
, передача пароля в ssh-add
из скрипта
Хотя может показаться простым передать пароль в ssh-add
из скрипта, например echo "passphrase\n" | ssh-add
, это не так просто, как кажется, так как ssh-add
не читает пароль из stdin
, а открывает /dev/tty
напрямую для чтения.
Это можно обойти с помощью expect
, инструмента для автоматизации интерактивных приложений. Ниже приведен пример скрипта, который добавляет ssh-ключ с паролем, хранящимся в скрипте:
#!/usr/bin/expect -f
spawn ssh-add /home/user/.ssh/id_rsa
expect "Введите пароль для /home/user/.ssh/id_rsa:"
send "пароль\n";
expect "Идентичность добавлена: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)"
interact
Обратите внимание, что пароль хранится в открытом виде в скрипте, поэтому с точки зрения безопасности это едва лучше, чем наличие ssh-ключа без пароля. Если этот подход будет использоваться, важно убедиться, что скрипт expect
, содержащий пароль, имеет надлежащие разрешения, чтобы быть читаемым, изменяемым и выполняемым только владельцем ключа.
Добавьте это в ваш ~/.bashrc
, затем выйдите и войдите снова, чтобы изменения вступили в силу.
if [ ! -S ~/.ssh/ssh_auth_sock ]; then
eval `ssh-agent`
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
ssh-add -l > /dev/null || ssh-add
Это должно запрашивать пароль только в первый раз, когда вы входите после каждой перезагрузки. Он будет продолжать использовать один и тот же ssh-agent
, пока он работает.
Хотя это не совсем связано с вопросом OP, но может быть полезно для других: с версии 7.2.0 ssh
есть опция, которая позволяет добавлять ключ в ssh-agent
при первой аутентификации; опция называется AddKeysToAgent
и может быть установлена на yes
, no
, ask
или confirm
, системно или в вашем личном файле .ssh/config
.
ssh-agent
кеширует различные разблокированные ssh-ключи, так что у вас могут быть ssh-ключи, защищенные паролями, но без необходимости вводить их каждый раз.
Для кеширования разблокированных ключей ему явно нужно разблокировать эти ключи. Для разблокировки ключей, которые заблокированы паролем, ему явно нужно знать эти пароли.
Любой метод, который не требует авторизации от человека (например, "ввод пароля"), не только сделает вашу систему небезопасной; он также сделает бессмысленным всю цель ssh-agent.
Сказав все это, вы можете просто использовать ssh-ключи, которые не защищены паролем (нажмите Enter, когда вас попросят ввести пароль при генерации ключа).
Поскольку пароля нет, ssh-agent
не нужно запрашивать у вас его, чтобы (не) закешировать его.
Вот обходной вариант для автоматизации вашего пароля SSH.
-
Создайте однострочный скрипт, который выводит ваш пароль на стандартный вывод, например:
echo 'echo MY_SSH_PASSWORD' > ~/.print_ssh_password && chmod 700 ~/.print_ssh_password
Важно: Убедитесь, что вы скопировали пробел перед чтобы предотвратить сохранение вашего пароля в истории.
И используйте один из следующих методов.
-
используя подход с стандартным вводом:
cat ~/.ssh/id_rsa | SSH_ASKPASS=~/.print_ssh_password ssh-add -
-
или с использованием именованного канала:
-
Создайте именованный канал (вы также можете попробовать подстановку процессов):
mkfifo --mode 0600 ~/.ssh_fifo
-
Запустите
ssh-add
, указав программу, используемую для аутентификации:cat ~/.ssh/id_rsa >~/.ssh_fifo | SSH_ASKPASS=~/.print_ssh_password ssh-add ~/.ssh_fifo
Смотрите:
man ssh-add
, чтобы узнать больше оSSH_ASKPASS
. -
Я не рекомендую вам использовать ssh-add (который требует открытия ssh-agent) при входе. Это связано с тем, что вы не можете контролировать, когда заканчивается секция ssh-agent, и это может создать угрозу безопасности, когда вы не нуждаетесь в файлах ключей в одной из секций входа.
Вместо этого я рекомендую написать скрипт, который открывает подпроцесс ssh-agent, все файлы ключей автоматически добавляются, и он вызывается, когда необходимо использовать ssh. Если вы можете это сделать, продолжайте читать.
У вас будет два выбора:
-
Удалить все пароли для ваших ключей, что ослабляет безопасность, если ваши файлы ключей будут украдены. (поэтому не рекомендуется)
-
Использовать один и тот же пароль для ваших ключей. Тогда, когда вы
ssh-add keyfile1 keyfile2 ...
, вам нужно будет ввести пароль только один раз за сеанс.
В обоих случаях вы можете написать такой скрипт с именем "ssh_keys_section.sh":
#!/bin/bash
# Этот скрипт запускает ssh-agent в подпроцессе и автоматически добавляет все файлы ключей сразу.
# Этот агент завершится, когда вы наберете `exit`, чтобы закрыть подпроцесс.
exec ssh-agent bash -c "ssh-add /path/to/keyfile1 /path/to/keyfile2 ...; exec bash"
Замечания:
- Команда для изменения или удаления пароля:
ssh-keygen -p -f keyfile
- Внутри подпроцесса вы также можете открыть больше терминалов, которые будут разделять одни и те же разблокированные ключи, используя, возможно, команду вроде
/path/to/yourterminal &
(в зависимости от ОС)
Если вы используете seahorse в качестве менеджера паролей
... Что вы, вероятно, и делаете ;D
Еще одно решение, которое достигает цели, которую вы ищете, — просто добавить ssh-ключи в seahorse для автоматической разблокировки при входе. Основное преимущество этого состоит в том, что вам никогда не придется вводить пароль для ключей после входа через gdm или через любой другой способ, даже если ключи имеют пароль. Это предполагает наличие как закрытого, так и открытого ключа. Они также ДОЛЖНЫ следовать соглашению об именовании для seahorse. По умолчанию используется допустимое (id_rsa для закрытого ключа и id_rsa.pub для открытого ключа... В общем, всё, что называется privatekeyname и privatekeyname.pub)
Чтобы добавить ssh-ключ в seahorse для автоматической разблокировки при входе;
(на fedora25, я не уверен, где находится путь на других дистрибутивах, но это, вероятно, очень похоже)
/lib64/seahorse/seahorse-ssh-askpass /path/to/keys/here
Для меня это было
/lib64/seahorse/seahorse-ssh-askpass ~/.ssh/id_rsa
(seahorse автоматически предположит, что открытый ключ был id_rsa.pub в моем случае)
После выполнения команды seahorse появится небольшое поле gtk для ввода пароля закрытого ключа. Или просто оставьте его пустым, если вы сгенерировали ключ без пароля.
Seahorse не выдаст сообщение, если все прошло нормально. Вам нужно будет попытаться подключиться к целевой машине с помощью ssh. Тогда seahorse предложит вам разблокировать ключ с помощью пароля графически (ЭТО СЛУЧИТСЯ ТОЛЬКО ОДИН РАЗ), и это должно выглядеть немного по-другому на этот раз ;P (это также часть, когда seahorse, как я полагаю, выполняет некоторую магию seahorse для ssh-add), и предложит ВАРИАНТ разблокировать ключ при входе, вам нужно отметить эту опцию, чтобы достичь вашей цели.
Только потому, что я не читал все ответы, я бы рекомендовал отменить все, что вам сказали сделать с ssh-add до того, как попытаетесь ответить на этот вопрос. В противном случае это может привести к чему-то плохому с вашими ключами, не знаю.
Я использовал скрипт, упомянутый steampowered, я сделал ниже указанный, потому что он не оставляет файлы валяться.
Работает только в оболочке zsh
.
#!/usr/bin/env zsh
AGENT_BIN=`which ssh-agent`
AGENT_ADD_BIN=`which ssh-add`
AGENT_PID=`ps -fe | grep ${AGENT_BIN} | awk -vuser=$USER -vcmd="$AGENT_BIN" '$1==user && $8==cmd{print $2;exit;}'`
if [ -z "$AGENT_BIN" ]; then
echo "ssh agent не найден!";
return
fi
if [ "" -eq "$AGENT_PID" ]; then
if read -sq "YN?Вы хотите разблокировать ваши ssh-ключи?"; then
echo ""
output=`$AGENT_BIN | sed 's/echo/#echo/g'`
eval $output
$AGENT_ADD_BIN
fi
else
for f in "/proc/"*
do
cmdline=`cat "$f/cmdline"`
if [ "${AGENT_BIN}" -ef "${cmdline}" ]; then
export SSH_AUTH_SOCK=`cat $f/net/unix | grep --binary-file=text -oP '((/[^/]*?)+/ssh-[^/]+/agent\.\d+$)'`
export SSH_AGENT_PID=${f##*/}
break;
fi
done
fi
SSH_ENV="$HOME/.ssh/environment"
function start_agent {
echo "Инициализация нового агента SSH..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo успешно
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add;
}
# Обработка настроек SSH, если применимо
if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
# ps ${SSH_AGENT_PID} не работает под cygwin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
Благодарность здесь: https://www.cygwin.com/ml/cygwin/2001-06/msg00537.html
Это решение также поддерживается здесь: http://mah.everybody.org/docs/ssh
if [ ! -S ${HOME}/.ssh/ssh_auth_sock ]; then
eval $(ssh-agent)
ln -sf "${SSH_AUTH_SOCK}" ${HOME}/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=${HOME}/.ssh/ssh_auth_sock
ssh_keys=$(find -E ~/.ssh -type f -regex '.*(rsa$|pem)')
ssh_agent_keys=$(ssh-add -l | awk '{key=NF-1; print $key}')
for k in "${ssh_keys}"; do
for l in "${ssh_agent_keys}"; do
if [[ ! "${k}" = "${l}" ]]; then
ssh-add "${k}" > /dev/null 2>&1
fi
done
done
Решение для единого входа для SSH может привести меня к pam_ssh
.
Согласно этой статье, концепция заключается в следующем:
Если вы работаете с несколькими машинами на основе *nix через ssh, вы, вероятно, устали постоянно вводить свой пароль каждый раз, когда хотите получить доступ к другой машине. Существует безопасный способ дать вам доступ ко всем машинам, к которым у вас есть доступ через ssh, без необходимости вводить другой пароль (кроме того, который вы изначально ввели).
Это на самом деле довольно просто сделать, вы в основном просто создаете пару открытый/закрытый ключ для аутентификации на других машинах, а затем вы используете PAM для запуска агента, чтобы загрузить ваши ключи после входа, обеспечивая решение единого входа для доступа ко всем вашим удалённым машинам. Этот гид приведет вас через этот процесс.
Я не проверял, будет ли это действительно работать.
Вдохновленный ответом Колина Андерсона, я написал альтернативный скрипт (который нужно поместить в ваш .bashrc
), который, в отличие от его, действительно работает в среде, такой как WSL (где каталог /tmp
не очищается, на чем основывается его решение):
source ~/.ssh/agent_out &> /dev/null
if ! ps -p $SSH_AGENT_PID &> /dev/null
then
ssh-agent > ~/.ssh/agent_out
source ~/ssh/agent_out &> /dev/null
fi
Для понимания того, что делает этот скрипт, давайте рассмотрим, что он будет делать в первый раз после запуска:
- Он запускает SSH-агент, сохраняет вывод команды
ssh-agent
в файл под названиемagent_out
в каталоге.ssh
пользователя для последующего использования. Вывод командыssh-agent
содержит утверждения, которые присваивают правильные значения переменным окружения, таким какSSH_AUTH_SOCK
иSSH_AGENT_PID
. - Для каждой новой сессии оболочки он сначала выполняет вывод последней команды
ssh-agent
, который был сохранен в файле~/.ssh/agent_out
, а затем проверяет, существует ли процесс с ID, включенным вSSH_AGENT_PID
, или нет. Если это не так, он выполняет первый шаг.
Это, вместе с новой опцией конфигурации SSH AddKeysToAgent
— см. мануал —, обеспечит приятный пользовательский опыт и, в большинстве случаев, устранит необходимость в сторонних инструментах, таких как keychain
и ssh-ident
:
~/.ssh/config
:
AddKeysToAgent yes
Моя настройка на macOS выглядит следующим образом (в .zshrc
или .bash_profile
для пользователей bash):
# Убить и перезапустить ssh-agent и установить необходимые переменные среды, которые он выводит
sshRestart() {
# если ничего не получится
# pkill -u $(whoami) ssh-agent;
if [ -n "$SSH_AUTH_SOCK" ] ; then
eval `/usr/bin/ssh-agent -k`
fi
eval `ssh-agent -s`
ssh-add ~/.ssh/YOUR_KEY_FILE
echo "SSH-агент перезапущен"
}
if [ -z "$SSH_AUTH_SOCK" ] || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]] ; then
eval `ssh-agent -s` > /dev/null 2>&1
ssh-add ~/.ssh/YOUR_KEY_FILE > /dev/null 2>&1
fi
Часть || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]]
необходима на macOS, потому что значение по умолчанию — /private/tmp/com.apple.launchd.SOMETHINGHERE/Listeners
. В противном случае всеобъемлющий ответ @Thomas Nyman не сработает, потому что $SSH_AUTH_SOCK
всегда установлен на что-то.
Затем в .zlogout
(или .bash_logout
для пользователей bash):
if [ -n "$SSH_AUTH_SOCK" ] ; then
eval `/usr/bin/ssh-agent -k`
fi
Тестировалось на macOS Mojave 10.14.5
Это было очень хорошо объяснено GitHub в Автоматический запуск ssh-agent на Git для Windows, который также работает для Linux.
Вы можете автоматически запускать ssh-agent
, когда открываете bash или Git-оболочку. Скопируйте следующие строки и вставьте их в ваш ~/.profile
или ~/.bashrc
файл в Git-оболочке:
env=~/.ssh/agent.env
agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }
agent_start () {
(umask 077; ssh-agent >| "$env")
. "$env" >| /dev/null ; }
agent_load_env
# agent_run_state: 0=агент запущен с ключом; 1=агент без ключа; 2= агент не запущен
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)
if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
agent_start
ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
ssh-add
fi
unset env
Если ваш закрытый ключ не хранится в одном из мест по умолчанию (таких как ~/.ssh/id_rsa
), вам нужно будет сообщить вашему ssh-агенту, где его найти. Чтобы добавить ваш ключ в ssh-agent, введите ssh-add ~/path/to/my_key
.
Совет: Если вы хотите, чтобы ssh-agent
забыл ваш ключ через какое-то время, вы можете настроить это, запустив ssh-add -t <seconds>
.
Самое простое решение не должно быть плохим.
Вам не нужны ни ssh-agent
, ни ssh-add
, когда вы используете закрытый ключ без пароля, смотрите https://stackoverflow.com/a/48290333/11154841.
Это не обязательно должно быть небезопасным: вам просто нужно удалить оба ключа ключевой пары сразу после использования. Это означает, что вы должны удалить открытый ключ на сервере и удалить закрытый ключ на клиенте. Само собой разумеется: не используйте их снова, не храните их даже в резервной копии где-либо.
Имейте в виду, что вы можете создать открытый ключ из закрытого ключа, но не наоборот. Обычно достаточно просто удалить открытый ключ из зарегистрированных ключей на вашем git-портале, но лучше удалить оба, чтобы тот же открытый ключ больше никогда не мог быть использован. Даже если кто-то украл ваш закрытый ключ, он будет бесполезен, если вы просто никогда больше не будете использовать его открытый ключ.
С закрытым ключом без пароля вы даже можете использовать его в Docker, чтобы избежать запроса пароля. Вы можете клонировать git-репозиторий без пароля, вам нужен только закрытый ключ без пароля. Смотрите Dockerfile: клонирование репозитория с закрытым ключом без пароля. Ошибки: “аутентификационный агент” или “read_passphrase: can't open /dev/tty” в качестве примера.
Мне действительно нравится этот ответ @Колина Андерсона, и я его повысил. Затем я добавил изменённую версию к моей личной документации по ssh здесь. Среди моих изменений есть команды для вывода, объясняющие, что происходит, и if
оператор, чтобы заменить эту строчку (ssh-add -l > /dev/null || ssh-add
), чтобы сделать более ясным, что на самом деле происходит.
Вот моя версия ниже.
Описание:
Автоматически запускает ssh-агент и добавляет необходимые ключи один раз за перезагрузку.
Рекомендуется добавить это в ваш ~/.bash_aliases
(предпочтительно) или ~/.bashrc
файл на любом
удалённом ssh-сервере, на который вы обычно заходите по ssh и с которого вы должны зайти
на другие машины или серверы, например, чтобы загрузить код на GitHub по ssh. Если вы только графически
входите на эту машину, однако, в этом нет нужды, так как, например, менеджер окон Gnome в Ubuntu
автоматически стартует и управляет ssh-agent
за вас.
Код:
if [ ! -S ~/.ssh/ssh_auth_sock ]; then
echo "'ssh-agent' не был запущен с последней перезагрузки." \
"Запускаю 'ssh-agent' сейчас."
eval "$(ssh-agent -s)"
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
# Проверим, были ли ключевые файлы уже добавлены к ssh-agent, и если нет, добавим их
ssh-add -l > /dev/null
if [ "$?" -ne "0" ]; then
echo "Ключи ssh не были добавлены к вашему 'ssh-agent' с последней" \
"перезагрузки. Добавляем ключи по умолчанию."
ssh-add
fi
Не рекомендую, но вы можете просто сразу удалить пароль с помощью:
ssh-keygen -p
Затем оставьте новый пароль пустым
Добавьте это в ваш ~/.bashrc
файл:
ssh-add -L|grep identities > /dev/null && ssh-add /path/to/ssh/private/key
Чтобы добавить ключ (возможно, без пароля) и убедиться, что ssh-add
не будет запрашивать пароль, независимо от того, что , даже при запуске под X:
DISPLAY= ssh-add -k /path/to/key </dev/null &>/dev/null
Код возврата указывает на успех или неудачу.
Лучший способ, который мне известен, — использовать сценарий входа PAM, который я адаптировал из предыдущих работ, поскольку я не мог найти удовлетворительный ответ на этот вопрос.
Ваш пароль хранится в зашифрованном виде с вашим системным паролем и тяжелой функцией деривации. При входе ваш системный пароль используется для расшифровки вашего пароля и добавления его в агент.
https://github.com/capocasa/systemd-user-pam-ssh
Преимущество перед каждым другим предложенным решением в том, что оно сочетает в себе безопасность, эквивалентную запуску ssh-add вручную при загрузке, с нулевыми усилиями. Это не требует дополнительных инструментов и имеет одну дополнительную зависимость, которая уже установлена по умолчанию на большинстве систем (OpenSSL).
Отвечая в качестве будущей заметки для себя: на Fedora ничего не делайте!
Просто получите git-репозиторий с этим ключом.
Затем интерфейс автоматически выведет и спросит, следует ли сохранить его в хранилище ключей. Теперь вы можете использовать этот ключ автоматически после входа.
Это можно сделать безопасно, если у вас есть хороший менеджер паролей.
Используя вариант ответа albfan на другой вопрос, мы обманом заставляем ssh-add
принимать ввод с stdin, используя setsid
, а также устанавливая переменные DISPLAY
и SSH_ASKPASS
. Последняя устанавливается на путь к скрипту, который выводит пароль.
% cat > add_key.sh <<EOF
#!/bin/zsh
export DISPLAY
export OP_SERVICE_ACCOUNT_TOKEN
DISPLAY=dummy
export SSH_ASKPASS="./echo_op.sh"
setsid ssh-add /home/foo/.ssh/path/keyfile < /dev/null
EOF
А в echo_op.sh
вы ссылаетесь на свой менеджер паролей (в данном случае 1Password и его инструмент командной строки op
):
#!/bin/zsh
echo $(op read "op://VaultName/EntryName/SectionName/PasswordFieldName")
Чтобы добавить ключ, вызовите ./add_key.sh
.
Если кто-то с лучшими знаниями оболочки сможет предложить способ сделать это более гибким через переданные аргументы (пути к ключам, например), это было бы очень полезно.
Единственный способ избежать запроса пароля каждый раз, когда вы входите, — это удалить пароль с закрытого ключа (не рекомендуется)
Я управляю кластерами и мне нужно регулярно входить на много машин. Эти удаленные хосты также перезагружаются каждые 1-2 дня для применения программного обеспечения/безопасных обновлений (MicroOS) - поэтому мне нужен способ регулярно автоматически входить и su
на каждый хост в кластерах с минимальными усилиями.
В Linux ваш рабочий стол обычно работает неделями без перезагрузки, поэтому вводить свой пароль раз в несколько недель — это приемлемый компромисс для безопасности. Эти инструкции должны работать на Linux / Mac или BSD.
- Я решил это в XFCE автоматически запустив
ssh
агент в Сессии и запуск:
- Я также добавил
autostart
приложение в Сессиях и запуске, чтобы один раз запуститься при входе и открыть небольшое терминальное окно для запроса моего пароля и автоматически закрыться:
xfce4-terminal -T "Кэширование SSH ключа" --geometry 75x5+1500+500 -x ssh-add /home/stuart/.ssh/id_ed25519
- Мой
~/.ssh/config
настроен для автоматическогоAddKeysToAgent
:
Host *
AddKeysToAgent yes
- Я потратил некоторое время на настройку кроссплатформенного tty
kitty
с этой конфигурацией, которая логирует меня иsu
кroot
на нескольких хостах:
-
В XFCE я также создал горячую клавишу в клавиатуре, чтобы запустить
kitty --session my-session-file
, чтобы я мог нажать клавишу раз в 1-2 дня, чтобы повторно войти в удалённые системы -
В течение года вышеуказанное дает мне около 24 часов сэкономленного времени (5 минут в день * 365 дней)
Вот окончательный скрипт.
Обновите $PASSW, затем скопируйте и вставьте это в свой терминал
# <sshpass> через typinator
# Обновлено: 2017-01-18_21h36
#
# apt-get update -y; apt-get install expect -qy
# Передайте это значение в ssh-add
PASSW="myfancypass123"
# Определите имя для этого скрипта
THIS_SCRIPT="$(date +%Y-%m-%d_%H-%M-%S-%N)".sh
# Создайте свежий каталог для работы / Очистите
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la
# Выводим наш bash-скрипт - НАЧАЛО
cat <<< '
#!/bin/bash
set -u # Остановить выполнение, если используется неопределенная переменная
set -e # Остановить выполнение при первой ошибке
export HISTIGNORE="expect*";
# Обычные команды
echo && echo "Этот процесс должен занять примерно 10 секунд:" && echo
eval "$(ssh-agent -s)"; sleep 0.5;
# Определите переменную, переданную при запуске этого bash-скрипта
password="$@"
# Запустите магию ожидания
expect -c "
spawn ssh-add /root/.ssh/id_rsa
expect "?assword:"
send \"$password\r\"
expect "?password:"
send \"$password\r\"
expect eof"
export HISTIGNORE="";
export password="";
' > $THIS_SCRIPT
# Выводим наш bash-скрипт - КОНЕЦ
# Убедитесь, что мы находимся в правильном пути
cd ~/temp; ls -la; sleep 1;
# Запустите bash-скрипт
chmod +x ./$THIS_SCRIPT; ./$THIS_SCRIPT "$PASSW"; unset password;
# Очистка
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la
Ответ или решение
Конечно! Вот полное решение вашей проблемы с автоматическим запуском ssh-add
без необходимости ввода пароля при каждом входе:
Способы автоматизации ssh-add
без запроса пароля
-
Использование
ssh-agent
:
Чтобы минимизировать необходимость ввода пароля, вы можете использоватьssh-agent
для управления вашими ключами. Для этого добавьте следующий код в ваш файл~/.bash_profile
или~/.bashrc
:if [ -z "$SSH_AUTH_SOCK" ]; then eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_rsa # Замените на ваш ключ fi
Это позволит
ssh-agent
запуститься и добавить ваш SSH-ключ при входе в систему. Однако, вам все равно придется вводить пароль при первом входе после перезагрузки. -
Использование
keychain
:
keychain
— это утилита для управленияssh-agent
. Она позволяет не вводить пароль на каждой сессии, а только при первой включенной сессии после перезагрузки.Установите
keychain
, а затем добавьте следующее в ваш~/.bash_profile
или~/.bashrc
:eval `keychain --eval --agents ssh ваш_ключ`
После этого выведите ваш пароль только при первой аутентификации.
-
Удаление пароля с ключа:
Если вы не против компромисса безопасности, вы можете удалить пароль с вашего ключа SSH. Для этого выполните:ssh-keygen -p
При этом просто оставьте пустым для нового пароля. Это не рекомендуется, так как ваш ключ в таком случае будет полностью незащищён в случае его компрометации.
-
Использование менеджера ключей:
Если вы используете среду рабочего стола (например, GNOME), то можно использовать менеджеры ключей, такие какseahorse
. Они могут автоматически добавлять ключи вssh-agent
и запрашивать пароль только при первом использовании ключа в сессии. -
Использование PAM:
Если вы хотите более безопасное решение, возможно, стоит рассмотреть использованиеPAM
(Pluggable Authentication Module) для автоподключения ключей при входе в систему, используя зашифрованные пароли.Рекомендуется рассмотреть решение «pam_ssh», которое позволит вам хранить запрашиваемый пароль зашифрованным и использовать его при подключении.
Заключение
Выбор подходящего метода зависит от ваших потребностей в безопасности и удобстве. Если вам нужна высокая безопасность, сохраняйте пароль на ключе и вводите его вручную. Если удобство важнее, используйте keychain
или удалите пароль с ключа — но это менее безопасно.