Проблема с получением ввода пользователя через скрипт, вызываемый pam_exec

Вопрос или проблема

Я пытался использовать pam_exec.so на Ubuntu, чтобы вызвать скрипт, запросить ввод пользователя и позволить пользователю войти через SSH, если скрипт завершился с кодом 0. Мне не удалось это сделать. Поэтому я написал простой скрипт, чтобы протестировать pam_exec.so и выяснить, в чем была проблема с моим оригинальным скриптом. Однако я сталкиваюсь с теми же проблемами даже с этим простым скриптом.

/usr/local/bin/test.sh

#!/bin/bash
echo -n "Пожалуйста, введите ваше имя:"
read name
echo "Здравствуйте, $name"

Я вызвал его, добавив следующую строку после @include common-auth в /etc/pam.d/sshd

auth    required        pam_exec.so stdout /usr/local/bin/test.sh

Но когда я подключаюсь по SSH к этой системе, как видно ниже, я не получаю запроса на ввод. Как только я ввожу пароль, я захожу в систему. Однако вывод скрипта виден.
введите описание изображения здесь

Затем я изменил вышеуказанный скрипт следующим образом, чтобы он завершался с кодом 1, если ввод не был предоставлен.

#!/bin/bash
echo -n "Пожалуйста, введите ваше имя:"
read name
if [ -z "$name" ]
then
        exit 1
else
        echo "Здравствуйте, $name"
        exit 0
fi

После этого я не смог подключиться по SSH к системе (скриншот ниже), даже когда вводил правильный пароль, и я не вижу никакого вывода скрипта.

введите описание изображения здесь

Так что я хочу знать, как я могу исправить эту проблему и использовать pam_exec.so для запуска скрипта, получения ввода пользователя и разрешения авторизации по ssh только в том случае, если этот скрипт завершился с кодом 0?

Я не знаком с реализацией pam_exec.so, но я сделал небольшой PAM, и я думаю, что это сложная задача для любого модуля, чтобы обрабатывать интерактивную сессию с внешним скриптом из-за того, как работает взаимодействие PAM (pam_conv_* функции) и необходимости знать, когда внешний скрипт будет считывать из stdin или нет (поскольку скрипт не просто exec по модулю в фоновом режиме).

В зависимости от того, сколько усилий вы готовы предпринять, создание PAM не является сложным, и у вас есть примеры, которые легко читать, в python или golang.

Еще один (возможно, более быстрый) вариант – использовать опцию stdin в pam_exec.so.
Оставляя в стороне вопросы безопасности и в зависимости от вашего случая использования, этого может быть достаточно, так как это отправляет пароль в стандартный ввод скрипта.

Если для вас приемлемо, чтобы ввод вашего скрипта был объединен с паролем (как в некоторых реализациях 2FA, где вы вводите пароль + OTP в поле для пароля):

  • Добавьте опцию stdin в свою строку pam_exec.so
  • В вашем скрипте разделите пароль и ваш второй ввод
  • Обработайте аутентификацию пароля самостоятельно (так как pam_unix не сможет это сделать с дополнительным вводом)
  • Используйте ваш дополнительный ввод

Ответ или решение

Проблема запросов пользовательского ввода через скрипт, вызываемый pam_exec

Использование pam_exec.so в системе Ubuntu для вызова скриптов может стать сложной задачей, особенно когда требуется взаимодействие с пользователем через терминал SSH. Давайте рассмотрим, почему ваш скрипт не работает как ожидалось, и как можно исправить эту ситуацию.

Суть проблемы

Вы пытаетесь вызвать скрипт, который запрашивает ввод пользователя и должен позволять SSH доступ только в том случае, если скрипт возвращает код завершения 0. Однако, скрипт, который вы написали, не вызывает ожидаемого взаимодействия через stdin в контексте PAM, что и приводит к указанным вами проблемам.

Причины неудачи

  1. PAM и взаимодействие с пользователем: PAM (Pluggable Authentication Modules) не предназначен для обработки интерактивных сеансов с помощью внешних скриптов в том виде, как вы это хотели сделать. Когда pam_exec.so запускает ваш скрипт, он не может правильно установить для него управление, чтобы позволить пользователю вводить данные.

  2. Конфигурация PAM: Ваша конфигурация (строка auth required pam_exec.so stdout /usr/local/bin/test.sh) не позволяет скрипту эффективно взаимодействовать с пользователем. pam_exec запускает скрипт в контексте, где ввод из терминала может не направляться в скрипт.

Рекомендации по решению проблемы

Есть несколько способов обойти найденную вами проблему:

  1. Использование параметра stdin: В случае, если вы хотите передать ввод пользователя, вы можете использовать параметр stdin в конфигурации вашего вызова pam_exec.so. Это позволит отправить пароль пользователя в стандартный ввод вашего скрипта.

    Обновите вашу строку конфигурации в /etc/pam.d/sshd на следующую:

    auth required pam_exec.so stdin /usr/local/bin/test.sh

    В этом случае вам потребуется модифицировать ваш скрипт, чтобы разобрать входящие данные. Например, вы можете ожидать, что первая часть ввода будет паролем, а вторая — именем пользователя.

  2. Создание пользовательского модуля PAM: Создание собственного модуля PAM с использованием языка программирования, такого как Python или Go, может дать вам больший контроль над взаимодействием с пользователем. Это более сложный путь, который требует разработки, но позволит более гибко управлять авторизацией.

  3. Реализация альтернативного метода ввода: Если два вышеописанных решения для вас не подходят, можно рассмотреть возможность использования сторонних средств, таких как SSH-ключи в сочетании с дополнительной аутентификацией (например, TOTP), что может исключить необходимость запрашивать ввод пользователя из PAM-скрипта.

Заключение

Работа с PAM и pam_exec.so может быть непростой, особенно когда речь идет о вводе от пользователя. Однако, используя параметры stdin или разрабатывая собственный модуль, вы сможете добиться желаемого взаимодействия и обеспечить корректную аутентификацию в вашей системе. Рекомендуется тестировать измененные конфигурации на тестовых машинах перед тем, как внедрять их в рабочую среду, чтобы избежать непредсказуемых последствий и обеспечить безопасность.

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

Капча загружается...