Перейти к содержанию

shibboleth: Модуль Shibboleth Auth Request для NGINX

Установка

Вы можете установить этот модуль в любом дистрибутиве на базе RHEL, включая, но не ограничиваясь:

  • RedHat Enterprise Linux 7, 8, 9 и 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-shibboleth
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-shibboleth

Включите модуль, добавив следующее в верхнюю часть файла /etc/nginx/nginx.conf:

load_module modules/ngx_http_shibboleth_module.so;

Этот документ описывает nginx-module-shibboleth v2.0.2, выпущенный 26 мая 2023 года.


image

Этот модуль позволяет Nginx работать с Shibboleth через FastCGI авторизатор Shibboleth. Для корректной работы этого модуля требуется специфическая конфигурация, а также наличие приложения FastCGI авторизатора Shibboleth на системе. Он стремится быть похожим на части Apache's mod_shib, хотя настройки авторизации и аутентификации Shibboleth конфигурируются через shibboleth2.xml, а не в конфигурации веб-сервера.

С этим модулем, настроенным для блока location, входящие запросы авторизуются в Nginx на основе результата субзапроса к FastCGI авторизатору Shibboleth. В этом процессе модуль может быть использован для копирования атрибутов пользователя из успешного ответа авторизатора в оригинальный запрос Nginx в виде заголовков или параметров окружения для использования любым бэкенд-приложением. Если авторизация не удалась, статус ответа авторизатора и заголовки возвращаются клиенту, отказывая в доступе или перенаправляя браузер пользователя соответственно (например, на страницу WAYF, если она настроена).

Этот модуль работает на этапе доступа и, следовательно, может быть комбинирован с другими модулями доступа (такими как access, auth_basic) через директиву satisfy. Этот модуль также может быть скомпилирован вместе с ngx_http_auth_request_module, хотя использование обоих этих модулей в одном блоке location не тестировалось и не рекомендуется.

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

Для получения дополнительной информации о том, почему это отдельный модуль, смотрите https://forum.nginx.org/read.php?2,238523,238523#msg-238523.

Директивы

Следующие директивы добавляются в ваши конфигурационные файлы Nginx. Указанные контексты показывают, где их можно добавить.

shib_request \<uri>|off | Контекст: http, server, location По умолчанию: off

Включает модуль Shibboleth auth request и устанавливает URI, который будет запрашиваться для авторизации. Настроенный URI должен ссылаться на блок местоположения Nginx, который указывает на ваш FastCGI авторизатор Shibboleth.

HTTP статус и заголовки ответа, полученные в результате субзапроса к настроенному URI, будут возвращены пользователю в соответствии со спецификацией FastCGI Authorizer. Единственное (возможно, значительное) предостережение заключается в том, что из-за того, как Nginx работает в настоящее время в отношении субзапросов (что фактически требуется авторизатору), тело запроса не будет передано авторизатору, и аналогично, тело ответа от авторизатора не будет возвращено клиенту.

Настроенные URI не ограничены использованием FastCGI бэкенда для генерации ответа. Это может быть полезно во время тестирования или в других случаях, так как вы можете использовать встроенные директивы Nginx return и rewrite, чтобы создать подходящий ответ. Кроме того, этот модуль может использоваться с любым FastCGI авторизатором, хотя работа может быть затронута вышеупомянутым предостережением.

[!WARNING] Директива shib_request больше не требует флага shib_authorizer. Этот флаг должен быть удален, чтобы Nginx мог запуститься. Другие изменения не требуются.

shib_request_set \<variable> \<value> Контекст: http, server, location По умолчанию: none

Устанавливает variable в указанное value после завершения запроса на авторизацию. value может содержать переменные из ответа на запрос авторизации. Например, $upstream_http_*, $upstream_status и любые другие переменные, упомянутые в документации nginx_http_upstream_module.

Эта директива может быть использована для введения атрибутов Shibboleth в окружение бэкенд-приложения, таких как $_SERVER для FastCGI PHP приложения и является рекомендуемым методом для этого. Смотрите документацию Конфигурация для примера.

shib_request_use_headers on|off | Контекст: http, server, location По умолчанию: off

[!NOTE] Добавлено в v2.0.0.

Копирует атрибуты из ответа авторизатора Shibboleth в основной запрос в виде заголовков, делая их доступными для upstream серверов и приложений. Используйте эту опцию только если ваш upstream/приложение не поддерживает серверные параметры через shib_request_set.

С включенной этой настройкой, заголовки ответа авторизатора, начинающиеся с Variable-\*, извлекаются, удаляя подстроку Variable- из имени заголовка, и копируются в основной запрос перед его отправкой на бэкенд. Например, заголовок ответа авторизатора, такой как Variable-Commonname: John Smith, приведет к добавлению Commonname: John Smith в основной запрос и, таким образом, будет отправлен на бэкенд.

Остерегайтесь подделки - вы должны убедиться, что ваше бэкенд-приложение защищено от инъекции заголовков. Обратитесь к примеру Конфигурации о том, как это сделать.

Конфигурация

Для получения полной информации о конфигурации окружения Nginx/Shibboleth смотрите документацию по адресу https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst.

Пример блока server состоит из следующего:

#FastCGI authorizer for Auth Request module
location = /shibauthorizer {
    internal;
    include fastcgi_params;
    fastcgi_pass unix:/opt/shibboleth/shibauthorizer.sock;
}

#FastCGI responder
location /Shibboleth.sso {
    include fastcgi_params;
    fastcgi_pass unix:/opt/shibboleth/shibresponder.sock;
}

## Используя директиву ``shib_request_set``, мы можем ввести атрибуты как
## переменные окружения для бэкенд-приложения. В этом примере мы
## устанавливаем ``fastcgi_param``, но это может быть любой тип бэкенда Nginx, который
## поддерживает параметры (используя соответствующую опцию *_param)
#
## ``shib_fastcgi_params`` - это необязательный набор параметров по умолчанию,
## доступный в директории ``includes/`` в этом репозитории.
#
## Выбирайте этот тип конфигурации, если ваше бэкенд-приложение
## не поддерживает серверные параметры или требует заголовков.
location /secure-environment-vars {
    shib_request /shibauthorizer;
    include shib_fastcgi_params;
    shib_request_set $shib_commonname $upstream_http_variable_commonname;
    shib_request_set $shib_email $upstream_http_variable_email;
    fastcgi_param COMMONNAME $shib_commonname;
    fastcgi_param EMAIL $shib_email;
    fastcgi_pass unix:/path/to/backend.socket;
}

## Защищенное местоположение. Все входящие запросы запрашивают FastCGI авторизатор Shibboleth.
## Будьте внимательны к проблемам с производительностью и подделкой!
#
## Выбирайте этот тип конфигурации для приложений ``proxy_pass``
## или бэкендов, которые не поддерживают серверные параметры.
location /secure {
    shib_request /shibauthorizer;
    shib_request_use_headers on;

    # Атрибуты из Shibboleth вводятся как заголовки FastCGI
    # авторизатором, поэтому мы должны предотвратить подделку.
    # ``shib_clear_headers`` - это набор директив заголовков по умолчанию,
    # доступный в директории `includes/` в этом репозитории.
    include shib_clear_headers;

    # Добавьте *все* атрибуты, которые использует ваше приложение, включая все
    # вариации.
    more_clear_input_headers 'displayName' 'mail' 'persistent-id';

    # Это бэкенд-приложение будет получать переменные Shibboleth как заголовки запроса
    # (от FastCGI авторизатора Shibboleth)
    proxy_pass http://localhost:8080;
}

Обратите внимание, что мы используем headers-more-nginx-module для очистки потенциально опасных входящих заголовков и предотвращения возможности подделки. Последний пример с переменными окружения не подвержен подделке заголовков, при условии, что бэкенд читает данные только из параметров окружения.

Доступна конфигурация по умолчанию для очистки основных заголовков от авторизатора Shibboleth, но вы должны убедиться, что написали свои собственные директивы очистки для всех атрибутов, которые использует ваше приложение. Имейте в виду, что некоторые приложения будут пытаться читать атрибут Shibboleth из окружения, а затем возвращаться к заголовкам, поэтому проверьте код вашего приложения, даже если вы не используете shib_request_use_headers.

При использовании shib_request_set доступен файл параметров по умолчанию, который вы можете использовать как include в nginx, чтобы гарантировать, что все основные переменные Shibboleth передаются от FastCGI авторизатора к приложению. Включены многочисленные атрибуты по умолчанию, поэтому удалите те, которые не требуются вашему приложению, и добавьте атрибуты Федерации или IDP, которые вам нужны. Этот файл параметров по умолчанию можно повторно использовать для upstream, которые не являются FastCGI, просто изменив директивы fastcgi_param на uwsgi_param, scgi_param и так далее.

Подводные камни

  • Субзапросы, такие как запрос авторизации Shibboleth, не обрабатываются через фильтры заголовков. Это означает, что встроенные директивы, такие как add_header, не будут работать, если они настроены как часть блока /shibauthorizer. Если вам нужно манипулировать заголовками субзапроса, используйте more_set_headers из модуля headers-more.

Смотрите https://forum.nginx.org/read.php?29,257271,257272#msg-257272.

Поведение

Этот модуль следует спецификации FastCGI Authorizer, где это возможно, но имеет некоторые заметные отклонения - по уважительной причине. Поведение таково:

  • Субзапрос авторизатора состоит из всех аспектов оригинального запроса, за исключением тела запроса, так как Nginx не поддерживает буферизацию тел запросов. Поскольку FastCGI авторизатор Shibboleth не учитывает тело запроса, это не является проблемой.

  • Если субзапрос авторизатора возвращает статус 200, доступ разрешен.

Если shib_request_use_headers включен, и заголовки ответа, начинающиеся с Variable-\*, извлекаются, удаляя подстроку Variable- из имени заголовка, и копируются в основной запрос. Другие заголовки ответа авторизатора, не начинающиеся с Variable-, и тело ответа игнорируются. Спецификация FastCGI требует, чтобы пары имя-значение Variable-* включались в окружение FastCGI, но мы делаем их заголовками, чтобы они могли использоваться с любым бэкендом (таким как proxy_pass), а не ограничиваться только FastCGI приложениями. Передавая данные Variable-* в виде заголовков, мы фактически следуем поведению ShibUseHeaders On в mod_shib для Apache, который передает эти атрибуты пользователя в виде заголовков.

Чтобы передать атрибуты как переменные окружения (эквивалентно ShibUseEnvironment On в mod_shib), атрибуты должны быть вручную извлечены с помощью директив shib_request_set для каждого атрибута. Это не может (в настоящее время) быть сделано массово для всех атрибутов, так как каждый бэкенд может принимать параметры по-разному (fastcgi_param, uwsgi_param и т.д.). Запросы на изменение кода приветствуются для автоматизации этого поведения.

  • Если субзапрос авторизатора возвращает любой другой статус (включая перенаправления или ошибки), статус и заголовки ответа авторизатора возвращаются клиенту.

Это означает, что при 401 Unauthorized или 403 Forbidden доступ будет запрещен, и заголовки (такие как WWW-Authenticate) от авторизатора будут переданы клиенту. Все другие ответы авторизатора (такие как 3xx перенаправления) передаются обратно клиенту, включая статус и заголовки, позволяя таким образом корректно работать перенаправлениям, таким как на страницы WAYF и ответчик Shibboleth (Shibboleth.sso).

Спецификация FastCGI требует, чтобы тело ответа возвращалось клиенту, но так как Nginx в настоящее время не поддерживает буферизацию ответов субзапросов (NGX_HTTP_SUBREQUEST_IN_MEMORY), тело ответа авторизатора фактически игнорируется. Обходной путь - заставить Nginx обслуживать собственную страницу error_page, как показано ниже:

location /secure {
   shib_request /shibauthorizer;
   error_page 403 /shibboleth-forbidden.html;
   ...
}

Это обслуживает указанную страницу ошибки, если авторизатор Shibboleth отказывает пользователю в доступе к этому местоположению. Без указанной error_page Nginx будет обслуживать свои общие страницы ошибок.

Обратите внимание, что это не относится к ответчику Shibboleth (обычно размещенному по адресу Shibboleth.sso), так как это FastCGI ответчик, и Nginx полностью совместим с этим, так как субзапросы не используются.

Для получения дополнительной информации смотрите https://forum.nginx.org/read.php?2,238444,238453.

Хотя этот модуль специально предназначен для FastCGI авторизатора Shibboleth, он, вероятно, будет работать и с другими авторизаторами, учитывая отклонения от спецификации выше.

Тесты

Тесты автоматически запускаются на GitHub Actions (с использованием этой конфигурации) всякий раз, когда в репозиторий вносятся новые коммиты или открываются новые запросы на слияние. Если что-то сломается, вы будете уведомлены, и результаты будут сообщены на GitHub.

Тесты написаны с использованием комбинации простого Bash-скрипта для компиляции нашего модуля с различными версиями и конфигурациями Nginx и Perl тестового каркаса Test::Nginx для интеграционного тестирования. Обратитесь к предыдущей ссылке для получения информации о том, как расширить тесты, а также ознакомьтесь с документацией Test::Base по аспектам, таким как функция blocks().

Интеграционные тесты автоматически запускаются CI, но также могут быть запущены вручную (требуется установка Perl и CPAN):

cd nginx-http-shibboleth
cpanm --notest --local-lib=$HOME/perl5 Test::Nginx
## nginx должен быть в PATH и собран с отладочными символами
PERL5LIB=$HOME/perl5/lib/perl5 prove

Помощь и поддержка

Запросы на поддержку конфигурации Shibboleth и настройки Nginx или веб-сервера должны направляться на список рассылки пользователей сообщества Shibboleth. Смотрите https://www.shibboleth.net/community/lists/ для получения подробной информации.

Отладка

Из-за сложной природы стека nginx/FastCGI/Shibboleth отладка проблем конфигурации может быть сложной. Вот несколько ключевых моментов:

  1. Подтвердите, что nginx-http-shibboleth успешно собран и установлен в nginx. Вы можете проверить это, запустив nginx -V и проверив вывод на наличие --add-module=[path]/nginx-http-shibboleth или --add-dynamic-module=[path]/nginx-http-shibboleth.

  2. Если вы используете динамические модули для nginx, подтвердите, что вы использовали директиву load_module для загрузки этого модуля. Ваше использование shib_request и других директив будет неудачным, если вы забыли загрузить модуль.

  3. Если вы используете версию nginx, отличную от тех, с которыми мы тестируем, или если вы используете другие сторонние модули, вам следует запустить тестовый набор выше, чтобы подтвердить совместимость. Если какие-либо тесты не проходят, проверьте вашу конфигурацию или подумайте о обновлении версии nginx.

  4. Конфигурация Shibboleth: проверьте ваш shibboleth2.xml и связанную конфигурацию, чтобы убедиться, что ваши хосты, пути и атрибуты правильно освобождаются. Пример конфигурации может помочь вам выявить ключевые "подводные камни" в конфигурации shibboleth2.xml для работы с FastCGI авторизатором.

  5. На уровне приложения: в вашем коде всегда начинайте с самого простого возможного вывода отладки (например, печати окружения запроса) и работайте оттуда. Если вы хотите создать базовое, автономное приложение, ознакомьтесь с конфигурацией Bottle на вики.

  6. Отладка внутренних модулей: если вы внимательно проверили все вышеперечисленное, вы также можете отлаживать поведение самого этого модуля. Вам нужно будет скомпилировать nginx с поддержкой отладки (через ./auto/configure --with-debug ...), и при запуске nginx будет проще, если вы сможете запустить его в переднем плане с включенной отладочной записью. Добавьте следующее в ваш nginx.conf:

    daemon off;
    error_log stderr debug;
    

    и запустите nginx. При запуске nginx вы должны увидеть строки, содержащие [debug], и по мере выполнения запросов консольная запись будет продолжаться. Если этого не происходит, проверьте вашу конфигурацию nginx и процесс компиляции.

    Когда вы в конечном итоге сделаете запрос, который попадает (или должен вызывать) блок местоположения shib_request, вы увидите в выводе строки, подобные следующим:

    [debug] 1234#0: shib request handler
    [debug] 1234#0: shib request set variables
    [debug] 1234#0: shib request authorizer handler
    [debug] 1234#0: shib request authorizer allows access
    [debug] 1234#0: shib request authorizer copied header: "AUTH_TYPE: shibboleth"
    [debug] 1234#0: shib request authorizer copied header: "REMOTE_USER: [email protected]"
    ...
    

    Если вы не видите таких строк, содержащих shib request ..., или если вы видите некоторые из вышеперечисленных строк, но не там, где копируются заголовки/переменные, то дважды проверьте вашу конфигурацию nginx. Если вы все еще не добились успеха, вы можете добавить свои собственные строки отладки в исходный код (следуя примерам этого модуля), чтобы в конечном итоге определить, что идет не так и когда. Если вы это сделаете, не забудьте перекомпилировать nginx и/или nginx-http-shibboleth каждый раз, когда вы вносите изменения.

Если вы считаете, что нашли ошибку в коде основного модуля, пожалуйста, создайте проблему.

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

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-shibboleth.