teslagov-jwt: Защитите свои локации NGINX с помощью JWT
Установка
Вы можете установить этот модуль в любой дистрибутив на базе 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-teslagov-jwt
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-teslagov-jwt
Включите модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_auth_jwt_module.so;
Этот документ описывает nginx-module-teslagov-jwt v2.4.0, выпущенный 17 сентября 2025 года.
Это модуль 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 Special Publication 800-107 Recommendation for Applications Using Approved Hash Algorithms, Раздел 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
- Клонируйте этот репозиторий следующим образом (замените
<target_dir>):git clone [email protected]:benmcollins/libjwt.git <target_dir> - Войдите в каталог и переключитесь на последнюю метку:
git checkout $(git tag | sort -Vr | head -n 1) - Обновите записи
includePath, показанные выше, чтобы они соответствовали выбранному вами местоположению.
Клонирование libjansson
- Клонируйте этот репозиторий следующим образом (замените
<target_dir>):git clone [email protected]:akheron/jansson.git <target_dir> - Войдите в каталог и переключитесь на последнюю метку:
git checkout $(git tag | sort -Vr | head -n 1) - Обновите записи
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
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub nginx-module-teslagov-jwt.