Неинтерактивная SSH-аутентификация

от автора

SSH предлагает несколько форм аутентификации, в том числе пароли и открытые ключи. Последние считаются более безопасными. Однако аутентификация по паролю по-прежнему остаётся самой популярной, особенно в сетевом оборудовании.

Чтобы не вводить пароль каждый раз вручную, есть специальные инструменты для автоматизации логина, то есть для неинтерактивной SSH-аутентификации. Это классическая утилита sshpass и её «исправленный» вариант passh (подробнее о причине «исправления» см. здесь).

▍ Парольный менеджер pass

Например, в случае passh применяется следующая конструкция с обёрткой для консоли Zsh. Пароль извлекается напрямую из парольного менеджера pass, где он хранится в зашифрованном виде:

pssh() {   passh -p <(pass show network/ssh/password | head -1) ssh "$@" } compdef pssh=ssh

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

Pass считается стандартным парольным менеджером, который соответствует философии Unix. Каждый пароль хранится в зашифрованном gpg-файле, имя которого — название сайта или ресурса, для которого предназначен пароль:

zx2c4@laptop ~ $ pass Password Store ├── Business │   ├── some-silly-business-site.com │   └── another-business-site.net ├── Email │   ├── donenfeld.com │   └── zx2c4.com └── France     ├── bank     ├── freebox     └── mobilephone

Эти зашифрованные файлы можно организовывать в иерархии папок, копировать с компьютера на компьютер и работать с ними с помощью стандартных утилит управления файлами командной строки:

zx2c4@laptop ~ $ pass -c Email/zx2c4.com Copied Email/jason@zx2c4.com to clipboard. Will clear in 45 seconds.

Pass очень просто управляет этими файлами. Все они хранятся в ~/.password-store, а в парольном менеджере есть несколько удобных команд для добавления, редактирования, генерации и получения паролей:

zx2c4@laptop ~ $ pass generate Email/jasondonenfeld.com 15 The generated password to Email/jasondonenfeld.com is: $(-QF&Q=IN2nFBx

Можно редактировать хранилище паролей, используя обычные команды юникс-консоли с командой pass. То есть не используется дополнительные форматы файлов или новые парадигмы, которые нужно изучать. Сообщество создало множество клиентов, графических интерфейсов и расширений для самого pass. Например, на КДПВ скриншоты клиента passforios под iOS. А ниже QtPass, мультиплатформенный GUI для pass:

▍ Продвинутая работа с паролями

Швейцарский разработчик Винсент Бернат (Vincent Bernat) разработал более продвинутый скрипт для неинтерактивной аутентификации по SSH: см. его репозиторий ssh.zsh. Он поясняет, что начиная с версии OpenSSH 8.4 мы можем использовать методы SSH_ASKPASS и SSH_ASKPASS_REQUIRE. Это устраняет некоторые недостатки стандартной команды passh: здесь отсутствует парсинг выдачи ssh и не вызывается парольный менеджер, когда пароль не требуется:

ssh() {   set -o localoptions -o localtraps   local passname=network/ssh/password   local helper=$(mktemp)   trap "command rm -f $helper" EXIT INT   > $helper <<EOF #!$SHELL pass show $passname | head -1 EOF   chmod u+x $helper   SSH_ASKPASS=$helper SSH_ASKPASS_REQUIRE=force command ssh "$@" }

Если пароль неправильный, на втором экране выводится подсказка:

ssh() {   set -o localoptions -o localtraps   local passname=network/ssh/password   local helper=$(mktemp)   trap "command rm -f $helper" EXIT INT   > $helper <<EOF #!$SHELL if [ -k $helper ]; then   {     oldtty=\$(stty -g)     trap 'stty \$oldtty < /dev/tty 2> /dev/null' EXIT INT TERM HUP     stty -echo     print "\rpassword: "     read password     printf "\n"   } > /dev/tty < /dev/tty   printf "%s" "\$password" else   pass show $passname | head -1   chmod +t $helper fi EOF   chmod u+x $helper   SSH_ASKPASS=$helper SSH_ASKPASS_REQUIRE=force command ssh "$@" }

Разные варианты ввода пароля в зависимости от удалённого узла:

ssh() {   # Grab login information   local -A details   details=(${=${(M)${:-"${(@f)$(command ssh -G "$@" 2>/dev/null)}"}:#(host|hostname|user) *}})   local remote=${details[host]:-details[hostname]}   local login=${details[user]}@${remote}    # Get password name   local passname   case "$login" in     admin@*.example.net)  passname=company1/ssh/admin ;;     bernat@*.example.net) passname=company1/ssh/bernat ;;     backup@*.example.net) passname=company1/ssh/backup ;;   esac    # No password name? Just use regular SSH   [[ -z $passname ]] && {     command ssh "$@"     return $?   }    # Invoke SSH with the helper for SSH_ASKPASS   # […] }

Скрипт целиком можно взять здесь.

Почему пароли до сих пор доминируют в качестве основной формы аутентификации? Дело в том, что отдельные сетевые устройства затрудняют привязку ключа SSH к пользователю. Многие просто не поддерживают аутентификацию на основе ключей/сертификатов. Таким образом, сертификаты не всегда можно использовать.

Способы неинтерактивной аутентификации SSH помогают автоматизировать ввод паролей, которые хранятся в стандартном парольном менеджере pass.


ссылка на оригинал статьи https://habr.com/ru/articles/846888/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *