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

teslagov-jwt: Защитите ваши местоположения NGINX с помощью JWT

Установка для Debian/Ubuntu

Эти документы применимы к APT пакету nginx-module-teslagov-jwt, предоставляемому репозиторием GetPageSpeed Extras.

  1. Настройте APT репозиторий, как описано в настройке APT репозитория.
  2. Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-teslagov-jwt
Показать дистрибутивы и архитектуры
| Дистрибутив | Версия            | Компонент  | Архитектуры    |
|-------------|-------------------|------------|-----------------|
| debian      | bookworm          | main       | amd64, arm64    |
| debian      | bookworm-mainline | main       | amd64, arm64    |
| debian      | trixie            | main       | amd64, arm64    |
| debian      | trixie-mainline   | main       | amd64, arm64    |
| ubuntu      | focal             | main       | amd64, arm64    |
| ubuntu      | focal-mainline    | main       | amd64, arm64    |
| ubuntu      | jammy             | main       | amd64, arm64    |
| ubuntu      | jammy-mainline    | main       | amd64, arm64    |
| ubuntu      | noble             | main       | amd64, arm64    |
| ubuntu      | noble-mainline    | main       | amd64, arm64    |

Это модуль NGINX для проверки действительности JWT и проксирования на сервер выше или перенаправления на страницу входа. Он поддерживает дополнительные функции, такие как извлечение утверждений из JWT и их размещение в заголовках запроса/ответа.

Ломающее изменение с v2

Ветка v2, которая теперь объединена с master, включает ломающее изменение. Пожалуйста, ознакомьтесь с первоначальным релизом v2 для деталей.

Директивы

Этот модуль требует несколько новых директив nginx.conf, которые могут быть указаны на уровнях http, server или location. Смотрите пример конфигурационного файла NGINX для получения дополнительной информации.

Директива Описание
auth_jwt_key Ключ, который следует использовать для декодирования/проверки JWT, в формате binhex -- см. ниже.
auth_jwt_redirect Установите в "on", чтобы перенаправить на auth_jwt_loginurl, если аутентификация не удалась.
auth_jwt_loginurl URL для перенаправления, если auth_jwt_redirect включен и аутентификация не удалась.
auth_jwt_enabled Установите в "on", чтобы включить проверку JWT.
auth_jwt_algorithm Алгоритм, который следует использовать. Один из: HS256, HS384, HS512, RS256, RS384, RS512
auth_jwt_location Указывает, где находится JWT в запросе -- см. ниже.
auth_jwt_validate_sub Установите в "on", чтобы проверить утверждение sub (например, идентификатор пользователя) в JWT.
auth_jwt_extract_var_claims Установите в список утверждений, разделенных пробелами, для извлечения из JWT и предоставления в качестве переменных NGINX. Эти переменные будут доступны через, например: $jwt_claim_sub
auth_jwt_extract_request_claims Установите в список утверждений, разделенных пробелами, для извлечения из JWT и установки в качестве заголовков запроса. Эти заголовки будут доступны через, например: $http_jwt_sub
auth_jwt_extract_response_claims Установите в список утверждений, разделенных пробелами, для извлечения из JWT и установки в качестве заголовков ответа. Эти заголовки будут доступны через, например: $sent_http_jwt_sub
auth_jwt_use_keyfile Установите в "on", чтобы считать ключ из файла, а не из директивы auth_jwt_key.
auth_jwt_keyfile_path Установите путь, из которого должен считываться ключ, когда auth_jwt_use_keyfile включен.

Алгоритмы

Алгоритм по умолчанию - HS256, для проверки с симметричным ключом. При использовании одного из алгоритмов HS* значение для auth_jwt_key должно быть указано в формате binhex. Рекомендуется использовать не менее 256 бит данных (32 пары шестнадцатеричных символов или 64 символа в целом). Обратите внимание, что использование более 512 бит не повысит безопасность. Для рекомендаций по ключам смотрите Специальную публикацию NIST 800-107 Рекомендации для приложений, использующих утвержденные хеш-алгоритмы, Раздел 5.3.2 Ключ HMAC.

Чтобы сгенерировать 256-битный ключ (32 пары шестнадцатеричных символов; 64 символа в целом):

openssl rand -hex 32

Дополнительные поддерживаемые алгоритмы

Конфигурация также поддерживает проверку RSA с помощью открытого ключа (например,) auth_jwt_algorithm RS256. При использовании алгоритмов RS* поле auth_jwt_key должно быть установлено в ваш открытый ключ ИЛИ auth_jwt_use_keyfile должно быть установлено в on, а auth_jwt_keyfile_path должно указывать на открытый ключ на диске. NGINX не стартует, если auth_jwt_use_keyfile установлено в on, и файл ключа не предоставлен.

При использовании алгоритма RS* с встроенным ключом обязательно укажите в auth_jwt_key открытый ключ, а не сертификат PEM. Например:

auth_jwt_key "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0aPPpS7ufs0bGbW9+OFQ
RvJwb58fhi2BuHMd7Ys6m8D1jHW/AhDYrYVZtUnA60lxwSJ/ZKreYOQMlNyZfdqA
rhYyyUkedDn8e0WsDvH+ocY0cMcxCCN5jItCwhIbIkTO6WEGrDgWTY57UfWDqbMZ
4lMn42f77OKFoxsOA6CVvpsvrprBPIRPa25H2bJHODHEtDr/H519Y681/eCyeQE/
1ibKL2cMN49O7nRAAaUNoFcO89Uc+GKofcad1TTwtTIwmSMbCLVkzGeExBCrBTQo
wO6AxLijfWV/JnVxNMUiobiKGc/PP6T5PI70Uv67Y4FzzWTuhqmREb3/BlcbPwtM
oQIDAQAB
-----END PUBLIC KEY-----";

При использовании алгоритма RS* с файлом открытого ключа, сделайте следующее:

auth_jwt_use_keyfile on;
auth_jwt_keyfile_path "/path/to/pub_key.pem";

Типичный случай использования заключается в том, чтобы указать ключ и URL для входа на уровне http, а затем включить аутентификацию JWT только для тех местоположений, которые вы хотите защитить (или наоборот). Неавторизованные запросы приведут к ответу 302 Moved Temporarily с заголовком Location, установленным на URL, указанный в директиве auth_jwt_loginurl, и с параметром строки запроса return_url, значение которого - текущий / предполагаемый URL.

Если вы предпочитаете возвращать 401 Unauthorized вместо перенаправления, вы можете отключить auth_jwt_redirect:

auth_jwt_redirect off;

Местоположения JWT

По умолчанию заголовок Authorization используется для предоставления JWT для проверки. Тем не менее, вы можете использовать директиву auth_jwt_location, чтобы указать имя заголовка или cookie, который предоставляет JWT:

auth_jwt_location HEADER=auth-token;  # получить JWT из заголовка "auth-token"
auth_jwt_location COOKIE=auth-token;  # получить JWT из cookie "auth-token"

Валидация sub

По желанию, модуль может проверить, существует ли утверждение sub (например, идентификатор пользователя) в JWT. Вы можете включить эту функцию следующим образом:

auth_jwt_validate_sub on;

Извлечение утверждений из JWT

Вы можете указать утверждения, которые будут извлекаться из JWT и помещаться в заголовки запроса и/или ответа. Это особенно удобно, потому что затем эти утверждения также будут доступны как переменные NGINX.

Если вы хотите получить доступ к утверждению только как к переменной NGINX, вам следует использовать auth_jwt_extract_var_claims, чтобы утверждение не было отправлено клиенту как заголовок ответа. Однако, если вы хотите, чтобы утверждение было отправлено клиенту в ответе, вы можете использовать вместо этого auth_jwt_extract_response_claims.

Пожалуйста, обратите внимание, что на данный момент не поддерживаются утверждения типа number, boolean, array и object -- поддерживаются только утверждения типа string. Ошибка будет выброшена, если вы попытаетесь извлечь небазовый тип.

Использование утверждений

Например, вы можете настроить местоположение NGINX, которое перенаправляет на профиль текущего пользователя. Предположим, что sub=abc-123, ниже представленная конфигурация перенаправит на /profile/abc-123.

location /profile/me {
    auth_jwt_extract_var_claims sub;

    return 301 /profile/$jwt_claim_sub;
}

Использование ответных утверждений

Ответные утверждения используются аналогично, с единственными отличиями: - переменные доступны через шаблон $sent_http_jwt_*, например, $sent_http_jwt_sub, и - заголовки отправляются клиенту.

Извлечение нескольких утверждений

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

auth_jwt_extract_request_claims sub firstName lastName;
auth_jwt_extract_request_claims sub;
auth_jwt_extract_request_claims firstName;
auth_jwt_extract_request_claims lastName;

Клонирование libjwt

  1. Клонируйте этот репозиторий следующим образом (замените <target_dir>): git clone [email protected]:benmcollins/libjwt.git <target_dir>
  2. Перейдите в каталог и переключитесь на последнюю метку: git checkout $(git tag | sort -Vr | head -n 1)
  3. Обновите includePath, показанный выше, в соответствии с выбранным вами расположением.

Клонирование libjansson

  1. Клонируйте этот репозиторий следующим образом (замените <target_dir>): git clone [email protected]:akheron/jansson.git <target_dir>
  2. Перейдите в каталог и переключитесь на последнюю метку: git checkout $(git tag | sort -Vr | head -n 1)
  3. Обновите includePath, показанный выше, в соответствии с выбранным вами расположением.

Проверка компиляции

После того, как вы сохраните изменения в .vscode/c_cpp_properties.json, вы должны увидеть, что предупреждения и ошибки в панели проблем исчезают, по крайней мере, временно. Надеюсь, они не вернутся, но если это произойдет, убедитесь, что ваши пути включения установлены правильно.

Для систем Linux с systemd (опционально)

export LOG_DRIVER=journald

Для других систем или если вы предпочитаете журналы на основе файлов (по умолчанию)

export LOG_DRIVER=json-file

перестроить тестовые образы

./scripts rebuild_test

запустить тесты

./scripts test

проверьте журналы -- при необходимости скорректируйте имя контейнера

Для journald (системы Linux):

journalctl -eu docker CONTAINER_NAME=nginx-auth-jwt-test-nginx

Для драйвера json-file (все системы):

docker logs nginx-auth-jwt-test-nginx

Теперь вы сможете видеть журналы из предыдущих запусков тестов. Лучший способ воспользоваться этим - открыть два терминала: один для запуска тестов и один для отслеживания журналов:

```shell
## терминал 1
./scripts test

## терминал 2 - выберите в зависимости от вашей настройки LOG_DRIVER:

## Для journald:
journalctl -fu docker CONTAINER_NAME=jwt-nginx-test

## Для json-file (по умолчанию):
docker logs -f nginx-auth-jwt-test-nginx