Ошибка Kerberos 401 с PHP скриптом Curl

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

У меня есть сервер Ubuntu с Apache, где папка защищена через Kerberos с использованием GSSAPI. Мне удалось настроить это с нашим сервером AD, и я могу видеть созданные билеты с помощью Klist -e.
Внутри защищенной папки находится PHP-скрипт, который выполняет команду post на сервер Windows. Это приводит к ошибке в журнале Apache:
gss_init_sec_context() не удалось: не были предоставлены учётные данные или учётные данные были недоступны или недостижимы. SPNEGO не может найти механизмы для ведения переговоров.

Я могу запустить этот скрипт вручную без проблем после создания билета, который хранится в кэше учётных данных (KRB5CACHE), и получить 200OK. Я читал, что кэш учётных данных должен быть доступен любой программе, включая PHP, но, похоже, он не может найти билет. Есть идеи, как я мог бы предоставить его либо в коде, либо через конфигурацию Apache? Этот PHP-скрипт также был перенесен с уже выведенного из эксплуатации Windows веб-сервера, где он работал нормально, так что код работал в какой-то момент. Спасибо.

пример кода php

Я читал, что кэш учётных данных должен быть доступен любой программе, включая PHP

Любая программа, включая PHP, запускаемая под вашей учётной записью. Кэши билетов Kerberos являются пользовательскими — естественно, поскольку они хранят учётные данные, специфичные для пользователя; вы бы не хотели, чтобы ваш пароль для входа был доступен другим учётным записям, и то же самое касается Kerberos.

Поэтому вам следует создать отдельный кэш билетов для UID, под которым работает PHP. (Программа k5start является удобным способом сделать это, но, конечно, вы можете использовать kinit и chown вручную.)

k5start -K 30 -a -H 30 -f $KEYTAB -U -b -L -c /tmp/krb5cc_for_php -o www-data
kinit -c /tmp/krb5cc... && chown ...

Кэш билетов может быть предоставлен PHP двумя способами: по умолчанию в пути /tmp/krb5cc_<uid> или переменной окружения KRB5CCNAME. Если вы разместите кэш в нестандартном месте, отредактируйте сервис PHP (php-fpm.service или apache2.service или другой) для установки этой переменной окружения — вероятно, не рекомендуется делать это с помощью putenv() из самого веб-приложения, так как это может негативно повлиять на другие веб-приложения.

systemctl edit php-fpm.service
[Service] Environment=KRB5CCNAME=/tmp/krb5cc_for_webapp
/etc/php/xxx/php-fpm.d/www.conf
env[KRB5CCNAME] = /tmp/krb5cc_for_webapp

Третий способ — использовать сервис gss-proxy, который позволит PHP использовать билеты, но не извлекать их, как ssh-agent или LSASS в Windows. В этом случае PHP будет нужна переменная GSS_USE_PROXY=1.

Не указывайте имя пользователя или пароль в CURLOPT_USERPWD, просто укажите ":".

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

При возникновении ошибки Kerberos 401 при выполнении PHP Curl скрипта на сервере Ubuntu, работающем с Apache и защищенном с помощью GSSAPI, проблему может вызывать неправильная обработка учетных данных Kerberos. Рассмотрим данный вопрос более подробно.

Теория

Kerberos работает на основе билетной системы, в которой учетные данные хранятся в билетном кеше, уникальном для каждого пользователя. PHP скрипты, выполняемые через Apache, запускаются от имени определенного пользователя (например, www-data). Такой подход обеспечивает безопасность, предотвращая доступ сторонних приложений к пользовательским данным.

Пример

В вашем случае скрипт PHP, который осуществляет HTTP-запросы, не может найти соответствующий билет в кеше. При ручном запуске скрипта под вашим пользовательским аккаунтом проблем не возникает, так как ваш аккаунт уже имеет доступ к кешу учетных данных.

Применение

  1. Создание билетного кеша для PHP:
    Используйте команду k5start или kinit для генерации необходимого кеша билетов от имени того пользователя, под которым запускается PHP:

    k5start -K 30 -a -H 30 -f /путь/к/файлу.keytab -U -b -L -c /tmp/krb5cc_for_php -o www-data
  2. Конфигурация PHP для использования билетов:
    Задайте переменную окружения KRB5CCNAME, указывая путь к нужному кешу:

    • Для php-fpm.service, выполните:

      systemctl edit php-fpm.service
      # Содержимое:
      [Service]
      Environment=KRB5CCNAME=/tmp/krb5cc_for_php
    • Для конфигурации www.conf:

      /etc/php/xxx/php-fpm.d/www.conf
      env[KRB5CCNAME] = /tmp/krb5cc_for_php
  3. Использование GSS-Proxy:
    Если не хотите вручную управлять кешем билетов, рассмотрите использование gss-proxy, который позволяет PHP работать с билетами, не извлекая их напрямую, наподобие ssh-agent в Linux. Для этого используйте GSS_USE_PROXY=1 в конфигурации PHP.

  4. Корректировка запросов:
    Избегайте передачи логина и пароля в CURLOPT_USERPWD. Достаточно указать просто ":", чтобы Curl понимал, что используется Kerberos-аутентификация.

Эти действия должны помочь в решении проблемы с ошибкой 401, обеспечив корректное управление учетными данными Kerberos для PHP Curl скриптов.

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

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