Глава 6. Аутентификация

Введение

NGINX обладает возможностью выполнять аутентификацию клиентов. Запросы аутентификации клиента при помощи NGINX разгружает работу и предоставляет возможность прекращать попадание на ваши серверы запросов без аутентификации. Доступные для NGINX с открытым исходным кодом модули включают базовую аутентификацию и подзапросы аутентификации. Имеющийся исключительно в NGINX Plus модуль проверки JWT (JSON Web Tokens) делает возможной интеграцию со сторонними производителями аутентификации, которые применяют стандарт OpenID Connect.

Базовая аутентификация HTTP

Задача

Вам требуется сделать безопасным ваше приложение или содержимое посредством базовой аутентификации HTTP.

Решение

Создайте некий файл с приводимым ниже форматом, в котором пароль зашифрован или хэширован в одном из допустимых форматов:


# comment
name1:password1
name2:password2:comment
name3:password3
 	   

Значением имени пользователя является самое первое поле, в качетсве пароля выступает второе поле, а разделителем является двоеточие. Существует необязательный третий параметр, который вы можете применять в качестве комментария для каждого пользователя. NGINX способен понимать несколько различных форматов для паролей, причём один из них состоит в том зашифрован ли пароль при помощи функции C crypt(). Эта функция выставляется в командной строке через соотвествующую команду openssl passwdю Когда установлен openssl, вы можете создавать строки зашифрованных паролей с использованием такой команды:


$ openssl passwd MyPassword1234
 	   

Её выводом будет некая трока, которую NGINX способен применять в вашем файле паролей.

Для включения базовой аутентификации в рамках своей конфигурации NGINX применяйте имеющиеся директивы auth_basic и auth_basic_user_file:


location / {
    auth_basic "Private site";
    auth_basic_user_file conf.d/passwd;
}
 	   

Вы можете применять директивы auth_basic в контекстах HTTP, server, location. Эта директива auth_basic получает некий строковый параметр, который отображается в базовом всплывающем окне аутентификации при появлении пользователя без аутентификации. Значение auth_basic_user_file определяет путь к надлежащему файлу пользователей.

Обсуждение

Вы можете вырабатывать пароли базовой аутентификации несколькими способами в ряде различных форматов с отличающимися степенями безопасности. Для выработки паролей также может применяться и команда htpasswd из Apache. И команда openssl, и команда htpasswd способны вырабатывать пароли с применением алгоритма apr1, который также способен понимать и NGINX. Этот пароль также может быть в формате Соли SHA-1, который применяется в LDAP (Lightweight Directory Access Protocol) и Dovecot. NGINX поддерживает дополнительные форматы и алгоритмы хэширования; однако многие из них рассматриваются как не безопасные, так как они запросто могут быть побеждены силовой атакой в лоб.

Вы можете применять базовую аутентификацию для защиты своего содержимого всего хоста NGINX целиком, определённых виртуальных серверов или даже конкретных блоков location. Базовая аутентификация на заменяет аутентификацию пользователя для веб- приложения, но она способствует поддержанию безопасности частной информации.

Под своим капотом базовая аутентификация выполняется путём возврата самим сервером некого кода HTTP 401 unauthorized с заголовком отклика WWW-Authenticate. Этот заголовок будет иметь некое значение Basic realm="your string". Такой отклик вызывает у браузера приглашение на ввод имени пользователя и пароля. Значения имени пользователя соединяются при помощи разделителя двоеточием, после этого кодируются в base64 и затем отправляются в неком заголовке запроса с названием Authorization. Этот заголовок запроса Authorization определит Basic и зашифрованную строку user:password. Сам сервер расшифровывает полученный заголовок и проверяет его по предоставленному файлу auth_basic_user_file. По той причине, что строки имени пользователя и пароля шифруются лишь base64, рекомендуется для базовой аутентификации использовать HTTPS.

Подзапросы аутентификации

Задача

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

Решение

Для осуществления запросов к внешней службе аутентификации на предмет проверки подлинности перед обслуживанием полученного запроса воспользуйтесь модулем http_auth_request_module:


location /private/ {
    auth_request /auth;
    auth_request_set $auth_status $upstream_status;
}

location = /auth {
    internal;
    proxy_pass http://auth-server;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}
 	   

Первая директива auth_request получает некий параметр URI, который обязан быть неким локальным внутренним location. Следующая директива auth_request_set позволяет вам устанавливать переменные из последующего подзапроса аутентиыфикации.

Обсуждение

Обсуждаемый http_auth_request_module делает возможной аутентификацию всех обрабатываемых вашим сервером NGINX запросов. Этот модуль выполняет некий подзапрос прежде чем обслуживать первоисточник для выяснения того имеет ли этот запрос доступ к запрашиваемому ресурсу. Весь первоначальный запрос целиком выставляется в посредник (прокси) в location такого подзапроса. Имеющийся location аутентификации действует как типичный посредник для получаемого подзапроса и отправляет сам первоначальный запрос, включая полученное тело первоначального запроса и заголовки. Получаемое значение кода состояния HTTP данного подзапроса является тем, что определяет будет ли предоставлен доступ или нет. Если этот подзапрос возвращает некий код состояния HTTP 200, данный процесс аутентификации успешен и сам запрос выполняется. Если же наш подзапрос возвращает HTTP 401 или 403, это же значение будет возвращено в сам первоначальный запрос.

Когда ваша служба аутентификации не запрашивает поступившее тело запроса, вы можете откинуть такое тело запроса с помощью отражённой в примере директивыproxy_pass_request_body. Такая практика снизит размер и время запроса аутентификации. Так как само тело отклика отбрасывается, его заголовок Content-Length должен быть снабжён пустой строкой. Если ваша служба аутентификации нуждается в знании того URI, который запрашивается данным запросом, вы пожелаете помещать это значение в неком индивидуальном заголовке который будет проверять и подтверждать ваша служба аутентификации. Если имеются некие моменты, которые вы бы хотели оставлять в своём подзапросе к службе аутентификации, например заголовки отклика или прочая информация, вы можете воспользоваться директивой auth_request_set для создания новых переменных из данных отклика.

JWT подтверждение

Задача

Вам требуется удостовериться в неком JWT прежде чем данный запрос обрабатывается при помощи NGINX Plus.

Решение

Для проверки допустимости соответствующей подписи маркера (token) и встроенных заявок и заголовков JWT в качестве переменных NGINX воспользуйтесь модулем аутентификации HTTP JWT NGINX Plus:


location /api/ {
    auth_jwt          "api";
    auth_jwt_key_file conf/keys.json;
}
 	   

Данная конфигурация делает возможной проверку допустимости JWT для данного location. Сама директива auth_jwt передаётся в качестве строки, которая применяется в качестве сферы аутентификации. Данная auth_jwt получает некий необязательный параметр маркера (token) какой- то переменной, которая содержит требуемый JWT. По умолчанию для стандартного JWT применяется соответствующий заголовок Authentication. Сама директива auth_jwt также может применяться для прекращения имеющихся действий запрашиваемой аутентификации наследуемых конфигураций. Для переключения off аутентификации передайте само ключевое слово в необходимой директиве auth_jwt без сопровождения чего бы то ни было. Для прекращения унаследованных требований аутентификации передайте само ключевое слово off в соответствующей директиве auth_jwt и ничего более. Директива auth_jwt_key_file получает единственный параметр. Этим параметром является значение пути к файлу ключей в стандартном формате JSON Web Key.

Обсуждение

NGINX Plus обладает способностью подтверждения виды маркеров (token) веб подписи JSON в отличие от типа веб шифрования JSON, когда зашифрован весь маркер. NGINX Plus имеет возможность удостоверять сигнатуры, которые подписываются алгоритмами HS256, RS256 и ES256. Наличие для валидации маркеров NGINX Plus может сберегать значительное время и ресурсы, требуемые для выполнения подзапросов к некой службе аутентификации. NGINX Plus дешифрует получаемые заголовок и полезную нашрузку JWT и подставляет значения стандартных заголовков и заявок во встроенные переменные для их применения вами.

Также ознакомьтесь

RFC Standard Documentation of JSON Web Signature

RFC Standard Documentation of JSON Web Algorithms

RFC Standard Documentation of JSON Web Token

NGINX Embedded Variables

Detailed NGINX Blog

Создание веб ключей JSON

Задача

Для применения в NGINX Plus вам требуется веб ключ JSON.

Решение

NGINX Plus применяется определённый в соответствующем RFC стандарте формат значения JWK (JSON Web Key). Этот стандарт допускает внутри такого файла JWK некий массив объектов ключей.

Ниже приводится некий образец того как может выглядеть подобный файл ключей:


{"keys":
  [
    {
        "kty":"oct",
        "kid":"0001",
        "k":"OctetSequenceKeyValue"
    },
    {
        "kty":"EC",
        "kid":"0002"
        "crv":"P-256",
        "x": "XCoordinateValue",
        "y": "YCoordinateValue",
        "d": "PrivateExponent",
        "use": "sig"
    },
    {
        "kty":"RSA",
        "kid":"0003"
        "n": "Modulus",
        "e": "Exponent",
        "d": "PrivateExponent"
    }
  ]
}
 	   

Приведённый файл JWK демонстрирует определённое дерево изначальных типов ключей, упомянутых в самом стандарте RFC. Описание формата этих ключей также является частью указанного стандарта RFC. Значением атрибута kty тип ключа. Данный файл отображает три типа ключей: Последовательность октетов (oct, Octet Sequence), координаты Эллиптической кривой (EC, EllipticCurve) и значение типа RSA. Значением атрибута kid является идентификатор ключа. Для получения дополнительных сведений относительно этих стандартов обращайтесь к соответствующей документации RFC.

Обсуждение

Для генерации необходимого веб ключа JSON существует множество доступных во многих разнообразных языках программирования библиотек. Рекомендуется создать некую службу ключа, которая выступает центом авторизации JWK для создания и ротации ваших JWK через систематические интервалы. Для дополнительной безопасности рекомендуется делать ваши JWK настолько же безопасными, как и ваши сертификаты SSL/ TLS. Обезопасьте свой файл ключей соответствующими полномочиями пользователя и группы. Наилучшей практикой будет удержание их в оперативной памяти. Вы можете делать это создавая некую файловую систему в памяти, подобную ramfs. Ротация ключей через систематические интервалы также важно; в качестве варианта вы можете создать некую службу ключей, которая создаёт общедоступные и частные ключи и предлагает их имеющимся приложениям и NGINX через некий API.

Также ознакомьтесь

RFC standardization documentation of JSON Web Key

Аутентификация пользователей посредством имеющегося OpenID Connect SSO

Задача

Вы желаете разгрузить для NGINX Plus удостоверения аутентификации OpenID Connect.

Решение

Для безопасности location или server, а также указания директиве auth_jwt применять в качестве маркера (token) $cookie_auth_token для удостоверения применяйте модуль JWT, который поставляется совместно с NGINX Plus:


location /private/ {
    auth_jwt "Google Oauth" token=$cookie_auth_token;
    auth_jwt_key_file /etc/nginx/google_certs.jwk;
}
 	   

Данная конфигурация направляет NGINX Plus защищать свой путь URI /private/ при помощи удостоверения через JWT. Google OAuth 2.0 OpenID Connect применяет значение ключа auth_token вместо установленного по умолчанию однонаправленного маркера. Таким образом вы должны указать NGINX о необходимости поиска значения данного маркера (token) в данном куки вместо использования установленного по умолчанию в самом NGINX Plus location. Местоположение auth_jwt_key_file настраивается на некий произвольный путь, что является неким этапом, который мы обсуждаем в рецепте Получение значения веб ключей JSON из Google.

Обсуждение

Данная конфигурация демонстрирует как вы можете выполнять удостоверение Google OAuth 2.0 OpenID Connect JSON Web Token через NGINX Plus. Обсуждаемый модуль аутентификации JWT NGINX Plus для HTTP способен выполнять удостоверение любого JWT, который следует указаниям спецификации RFC for JSON Web Signature, что незамедлительно делает возможными любые полномочия SSO которые применяют JSON Web Tokens для удостоверения на уровне NGINX Plus. Сам протокол OpenID 1.0 является неким уровнем поверх протокола аутентификации OAuth 2.0, который добавляет идентификацию, позволяя такое применение JWT для доказательства необходимой идентификации определённого пользователя отправляя соответствующий запрос. Имея подпись конкретного маркера NGINX Plus способен удостоверить что такой маркер не был изменён так как он был подписан. Тем самым Google применяет некий асинхронный метод подписи и позволяет распространять общедоступные JWK отслеживая их частные ключи безопасности JWK.

NGINX Plus способен также контролировать для OpenID Connect 1.0 Поток кода авторизации, включая NGINX Plus в качестве ретранслятора для OpenID Connect. Такая возможность делает возможной интеграцию с большей частью поставщиков идентификации, включая CA Single Sign On (ранее SiteMinder), ForgeRock OpenAM, Keycloak, Okta, OneLogin и Ping Identity. Для получения дополнительных сведений о реализации NGINX Plus в качестве ретранслятора аутентификации OpenID Connect обратитесь к NGINX Inc OpenID Connect GitHub Repository

Также ознакомьтесь

Detailed NGINX Blog on OpenID Connect

OpenID Connect

Получение значения веб ключей JSON из Google

Задача

Вам требуется получать значение Веб ключа JSON из Google для применения при удостоверении маркеров (token) OpenID Connect в NGINX Plus.

Решение

Для постоянного обеспечения современности ваших ключей каждый час применяйте Cron для запросов свежего набора ключей:


0 * * * * root wget https://www.googleapis.com/oauth2/v3/ \
  certs-O /etc/nginx/google_certs.jwk
		

Данный фрагмент кода является некой строкой из файла crontab. Подобные Unix системы имеют множество вариантов того где могут обитать файлы crontab. Всякий пользователь будет иметь некий особый для пользователя crontab, а также множество файлов и каталогов в своём каталоге /etc/.

Обсуждение

Cron является распространённым способом выполнения задач по расписанию в подобных Unix системах. Веб ключи JSON обязаны ротироваться на систематической основе для обеспечения безопасности своим ключам и в конечном счёте безопасности вашей системы. Для гарантии того что у вас всегда самый последний ключ от Google, вы захотите проверять через систематические промежутки времени наличие новых JWK. Одним из вариантов этого является данное решение Cron.

Также ознакомьтесь

Cron