Вопрос или проблема
У нас есть сервис, который управляет файлами как через веб-интерфейс, так и требует доступа к файлам через rsync. Один из способов решить эту проблему – предоставить каждому пользователю учетную запись UNIX в системе и разрешать доступ только в том случае, если программа, запущенная через ssh, является принимающей стороной rsync, так как эти пользователи не должны иметь возможность использовать сервер как удаленное вычислительное устройство.
Управление ключами через веб-интерфейс было достаточно простым благодаря использованию директивы AuthorizedKeyProgram в конфигурации sshd, но мне интересно, как настроить систему, где есть только ОДИН логин, как у github есть единственный пользователь “github” для их ssh git соединения, а затем изменять базовый каталог, к которому есть доступ у соединения, в зависимости от ssh-ключа, который использовался для открытия соединения.
Как я могу комбинировать AuthorizedKeyProgram sshd с другими программами, такими как ssh-команда и другие системы ограничения, чтобы сделать один логин для нескольких пользователей в ssh, как github, кажется, используют для своих репозиториев и программы “git”?
Сейчас AuthorizedKeyProgram извлекает ssh-ключи из базы данных и затем добавляет скрипт “only-rsync.sh” в качестве принудительной команды:
print("command=\"only_rsync\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty" + key)
Скрипт “only-rsync.sh” просто выполняет следующие действия:
#!/bin/bash
if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
if [[ "$SSH_ORIGINAL_COMMAND" =~ ^rsync\ ]]; then
exec $SSH_ORIGINAL_COMMAND --chmod=a+rwX
fi
fi
.
Ответ или решение
Создать систему SSH-доступа, подобную той, что используется GitHub с одним пользователем и множеством ключей для разных пользователей, может показаться сложной задачей, но она осуществима при условии понимания некоторых ключевых механизмов SSH и Linux. В этой системе, вместо предоставления отдельного UNIX-аккаунта для каждого пользователя, мы создаем одну учетную запись и используем механизм авторизации через открытые ключи для распределения прав доступа и разграничения директорий, к которым каждый пользователь может получить доступ.
Теория
Основная идея заключается в том, чтобы использовать директиву AuthorizedKeysCommand
в конфигурации SSH демона (sshd_config), которая позволяет динамически обрабатывать запросы на авторизацию через SSH, выполняя программу, которая возвращает разрешенные ключи. Эта программа может быть написана на любом языке программирования и позволяет реализовать любую логистику авторизации, которая вам необходима, включая выполнение определенных команд, ограничаивающих доступ.
Преимущества подхода:
- Упрощенное управление доступом: Все ключи пользователя управляются в одном месте (например, в базе данных), что упрощает добавление или удаление пользователей.
- Делегирование правого управления: Можно точно определить, какой пользователь получает доступ к какой директории на сервере.
- Упрощенная конфигурация серверов: Один пользователь SSH на сервере означает меньшие накладные расходы на управление учетными записями.
Пример
Рассмотрим конкретный пример настройки. Представим, что у вас есть база данных, в которой хранятся SSH-ключи пользователей и сопоставленная директория. Программа, указанная в AuthorizedKeysCommand
, должна принимать аргументы пользователя и возвращать строку, содержащую SSH-ключ и необходимые опции.
Конфигурация sshd:
AuthorizedKeysCommand /etc/ssh/authorize_keys.sh
AuthorizedKeysCommandUser root
Содержание authorize_keys.sh:
#!/bin/bash
USER=$1
# Запрос к базе данных для получения ключа и директории
RESULT=$(query_database_for_key_and_directory $USER)
# EXPECTED OUTPUT: "/home/sftp_users/username/.ssh/keys/key.pub /path/to/directory"
if [ -z "$RESULT" ]; then
exit 1
fi
KEY=$(echo $RESULT | awk '{print $1}')
DIR=$(echo $RESULT | awk '{print $2}')
echo "command=\"cd $DIR && only_rsync.sh\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty $KEY"
В этом скрипте происходит следующая логика:
- Используется аргумент
$1
, чтобы получить имя пользователя, для которого извлекаем SSH-ключ и директорию. - Производится запрос в базу данных для получения соответствующих данных.
- Скрипт возвращает строку, применяющую команду и ключ с необходимыми ограничениями.
Применение
Чтобы завершить настройку, вам понадобится скрипт only_rsync.sh
, который был у нас в примере. Он будет выполнять проверку передаваемой команды и обеспечивать, что пользователь может выполнять только команды rsync
, которые вы ему разрешили. Если команда соответствует правилам, rsync
выполняется и пользователь получает доступ к своим файлам в предварительно указанной директории.
Основные шаги для развертывания:
- Разработайте и протестируйте базу данных для хранения SSH-ключей и путей директорий.
- Напишите
authorize_keys.sh
для извлечения ключей и настройки директорий. - Проверьте правильность скрипта
only_rsync.sh
и убедитесь в защищенности через ограничение команд. - Обновите конфигурацию SSH (sshd_config) и перезапустите SSH-сервер для применения изменений.
Заключение
Этот подход предоставляет возможность масштабируемого и управляемого управления доступом нескольких пользователей через одну учетную запись SSH, позволяя разным SSH-ключам получать доступ к различным ресурсам, таким образом эффективно имитируя модель доступа, используемую GitHub. Это решение требует внимательной настройки и тестирования, но оно может значительно сократить административные расходы и улучшить безопасность системы.