Назад | Перейти на главную страницу

настроить OpenSSH для предпочтения аутентификации с открытым ключом, вернуться к аутентификации с пустым паролем

Я хотел бы настроить OpenSSH 6.2p2 для учетной записи службы (назовем ее «serviceacct») с пустым паролем, который выполняет следующие действия:

  1. Сначала попробуйте аутентификацию с открытым ключом; в случае успеха выполните принудительную команду, указанную в файле authorized_keys.
  2. Вернитесь к аутентификации с пустым паролем и запустите принудительную команду, указанную в другом месте.

По сути, это даст одно поведение для известных пользователей и другое для анонимных пользователей.

В идеальном мире эти настройки в sshd_config будут делать то, что я хочу:

PubkeyAuthentication yes
PasswordAuthentication yes
Match User serviceacct
  PermitEmptyPasswords yes
  ForceCommand /my/program

Но у меня есть пара проблем:

  1. ForceCommand /my/program отменяет принудительную команду, заданную в файле authorized_keys.
  2. Кажется, что использование пустого пароля имеет приоритет над аутентификацией с открытым ключом.

Есть ли способ обойти эти две проблемы, кроме модификации сервера OpenSSH? Один очевидный обходной путь, который я могу придумать, - это просто использовать две учетные записи служб: одну для известных пользователей, использующих только аутентификацию с открытым ключом, и другую для анонимных пользователей, использующих только аутентификацию с пустым паролем. По возможности я стараюсь избегать двух учетных записей пользователей.

Изменить - почему мне нужно такое поведение

Я создаю службу, в которой размещаются различные типы репозиториев системы контроля версий (Subversion, Git и Mercurial). Подумайте, GitHub или Bitbucket, но размещены локально (это ключ, поскольку часть нашей работы не может покинуть наш сайт). Возможно, самый простой метод доступа, который является общим для каждой из этих систем контроля версий, - это SSH.

В каждом репозитории есть настраиваемые правила доступа для известных и анонимных пользователей. Я хотел бы иметь возможность поддерживать как известных, так и анонимных пользователей, использующих один и тот же URL-адрес для любой из систем контроля версий. Поскольку пользователь, который размещает репозиторий, является частью URL-адреса (например, ssh://user@host/path) для двух разных пользователей - одного для известных пользователей и одного для анонимных пользователей - потребуются два разных URL-адреса.

Я должен уточнить одну техническую деталь: на самом деле я использую AuthorizedKeysCommand в sshd_config, которая указывает sshd использовать вывод внешней программы вместо чтения файла ~ / .ssh / authorized_keys.

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

ИМО, это можно сделать так, первая серверная часть:

$ sshd --help 2>&1 | sed -n '2p'
OpenSSH_7.9, LibreSSL 2.8.2
$ grep ^Expose /etc/ssh/sshd_config                                                                               
ExposeAuthInfo yes

$ man sshd_config | col -b | sed -n '/ExposeAuthInfo/,/^$/p'
     ExposeAuthInfo
             Writes a temporary file containing a list of authentication
             methods and public credentials (e.g. keys) used to authenticate
             the user.  The location of the file is exposed to the user
             session through the SSH_USER_AUTH environment variable.  The
             default is no.

Вам также необходимо настроить sshd_config для входа без пароля. Я бы рекомендовал использовать что-то подобное, оставьте PermitEmptyPasswords no в глобальной части конфигурационного файла!

Match User specialuser
    PermitEmptyPasswords yes
    AuthenticationMethods publickey none
    ForceCommand /path/to/wrapper

И давайте сделаем тестовую оболочку (для удобства я пока помещаю ее в ~ / .ssh / authorized_keys) ...

$ grep ^command $HOME/.ssh/authorized_keys
command="$HOME/test.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILleQxrJU7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ cat ~/test.sh
#!/bin/sh
set -x
printenv | egrep "^(SSH_ORIGINAL_COMMAND|SSH_USER_AUTH)"

if [[ -r ${SSH_USER_AUTH} ]]; then
    cat ${SSH_USER_AUTH}
    if grep -q ^publickey ${SSH_USER_AUTH} ; then
        echo "XXX I've logged with a public key!"
    else
        echo "XXX I've NOT logged with a public key!"
    fi
fi

if [[ -z "${SSH_ORIGINAL_COMMAND}" ]]; then
    exec ${SHELL}
else
    exec ${SHELL} -c "${SSH_ORIGINAL_COMMAND}"
fi

Попробуем ssh с открытым ключом.

$ ssh -l specialuser remote_server
+ printenv
+ egrep ^(SSH_ORIGINAL_COMMAND|SSH_USER_AUTH)
SSH_USER_AUTH=/tmp/sshauth.UTmBQYIadWVem97
+ cat /tmp/sshauth.UTmBQYIadWVem97
publickey ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILleQxrxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ grep -q ^publickey /tmp/sshauth.UTmBQYIadWVem97
+ echo XXX I've logged with a public key!
XXX I've logged with a public key!
+ exec /bin/ksh
$

Я не собираюсь тестировать для вас вход без пароля, но думаю, у нас есть все необходимые детали;)

Не правда ли?

- man /etc/ssh/sshd_config:

  • AuthenticationMethods
    • Задает методы проверки подлинности, которые должны быть успешно выполнены, чтобы пользователю был предоставлен доступ. Этот вариант необходимо соблюдать одним или несколькими Списки имен методов аутентификации, разделенных запятыми. Успешная аутентификация требует завершения каждого метода как минимум в один из этих списков.
    • Например, аргумент publickey,password publickey,keyboard-interactive потребует от пользователя пройти аутентификацию с открытым ключом, за которой следует интерактивная аутентификация с помощью пароля или клавиатуры. На каждом этапе предлагаются только методы, которые идут следующими в одном или нескольких списках, поэтому в этом примере будет невозможно попытаться выполнить аутентификацию с использованием пароля или интерактивную клавиатуру до открытого ключа.