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/
Добавить комментарий