Продолжение истории про Nginx и jwt-авторизацию. На этот раз ставим другой сторонний модуль jwt-авторизации для того чтобы у Nginx появилась возможность извлекать токен не только из заголовка или куки, но также из строки запроса.
Интродукция
Модуль https://github.com/kjdev/nginx-auth-jwt похож на оригинальный модуль и умеет извлекать токен из строки запроса. Согласно документации он зависит от библиотек jansson и openssl. Значит порядок установки будет следующий:
- Установим jansson
- Установим openssl
- Качаем JWT-модуль
- Качаем Echo-модуль
- Качаем исходный код Nginx
- Компилируем Nginx с модулями и включенным debug
Установим jansson
# zypper in libjansson-devel
Проверим установку
# pkg-config --modversion jansson
Установим openssl
# zypper in libopenssl-devel
Качаем JWT и Echo модули
установим git
# zypper in git
переходим в директорию куда будем качать все исходники
# cd /usr/local/src
клонируем jwt модуль
# git clone https://github.com/kjdev/nginx-auth-jwt
клонируем Echo модуль
# git clone https://github.com/openresty/echo-nginx-module
Установим необходимые библиотеки для компиляции
# zypper in gcc
# zypper in make
# zypper in pcre-devel
# zypper in libxml2-devel
# zypper in libxslt-devel
# zypper in gd-devel
Установка Nginx
Установим коробочный Nginx
# zypper in nginx
# systemctl enable nginx
# systemctl start nginx
# systemctl status nginx
Сохраним куда-нибудь себе параметры сборки коробочного Nginx:
# nginx -V
Берем все что после configure arguments:
--prefix=/usr/ --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/nginx.lock --http-client-body-temp-path=/var/lib/nginx/tmp/ --http-proxy-temp-path=/var/lib/nginx/proxy/ --http-fastcgi-temp-path=/var/lib/nginx/fastcgi/ --http-uwsgi-temp-path=/var/lib/nginx/uwsgi/ --http-scgi-temp-path=/var/lib/nginx/scgi/ --user=nginx --group=nginx --without-select_module --without-poll_module --with-threads --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-perl=/usr/bin/perl --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module --with-pcre --with-pcre-jit --with-cc-opt='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -D_GNU_SOURCE' --with-ld-opt='-Wl,-z,relro,-z,now -pie' --with-compat
Качаем исходный код Nginx:
# cd /usr/local/src
# wget https://nginx.org/download/nginx-1.21.5.tar.gz
# tar -xvf nginx-1.21.5.tar.gz
# cd /usr/local/src/nginx-1.21.5
Добавим (допишем в конец) новые параметры сборки --with-debug --add-module=/usr/local/src/echo-nginx-module --add-dynamic-module=/usr/local/src/nginx-auth-jwt к параметрам коробочного Nginx, сохраненным ранее. Выполним ./configure с нашим объединенным большим списком параметров:
# ./configure --prefix=/usr/ --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/nginx.lock --http-client-body-temp-path=/var/lib/nginx/tmp/ --http-proxy-temp-path=/var/lib/nginx/proxy/ --http-fastcgi-temp-path=/var/lib/nginx/fastcgi/ --http-uwsgi-temp-path=/var/lib/nginx/uwsgi/ --http-scgi-temp-path=/var/lib/nginx/scgi/ --user=nginx --group=nginx --without-select_module --without-poll_module --with-threads --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-perl=/usr/bin/perl --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module --with-pcre --with-pcre-jit --with-cc-opt='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -D_GNU_SOURCE' --with-ld-opt='-Wl,-z,relro,-z,now -pie' --with-compat --with-debug --add-module=/usr/local/src/echo-nginx-module --add-dynamic-module=/usr/local/src/nginx-auth-jwt
Затем компилируем и устанавливаем.
# make
# make install
Активируем jwt-модуль в конфиге nginx.conf. После успешной компиляции в директории /usr/lib64/nginx/modules должен появиться файл ngx_http_auth_jwt_module.so, который необходимо подключить в файле nginx.conf с помощью директивы load_module:
load_module lib64/nginx/modules/ngx_http_auth_jwt_module.so;
Настройка firewall
Без разрешения http-трафика в правилах фаервола мы не получим ответ от Nginx и не увидим результат нашей работы. OpenSUSE использует FirewallD для управления правилами фаервола. Чтобы разрешить http-трафик, выполните следующую команду:
# firewall-cmd --permanent --add-service=http
# firewall-cmd --reload
или с помощью консольной утилиты yast в зоне public добавьте http в список allowed для этого:
# yast
- Перемещайте курсор с помощью tab и стрелок на клавиатуре, установите курсор на зоне public и нажмите Enter
- Перемещаясь таким же образом, в списке known отметьте (нажать Enter) крестиком протокол http и, если необходимо, протокол https, например: [x] http.
- Добавтье отмеченные протоколы в список allowed. Для этого установите курсор на Add и нажмите Enter.
- Установите курсор на Accept и нажмите Enter
Проверим работу Nginx
В конфигурационном файле nginx.conf создадим локацию /hello в которой echo-модуль отвечает клиенту строкой "hello!"
location /hello {
echo "hello!";
}
Перезагрузим Nginx
# systemctl restart nginx
теперь сервер должен ответить hello!
Проверим работу jwt-модуля Nginx.
Добавим в локацию /hello директивы для обработки jwt-токена:
location /hello {
auth_jwt "closed site" token=$arg_token;
auth_jwt_key_file /etc/nginx/nginx.jwt.key.json keyval;
auth_jwt_validate_exp on;
echo "hello!";
}
Добавим еще одну локацию, отдающую mp4 файлы из папки media в обмен на токен:
location ~ \.(mp3|mp4) {
auth_jwt "closed site" token=$arg_token;
auth_jwt_key_file /etc/nginx/nginx.jwt.key.json keyval;
auth_jwt_validate_exp on;
root /srv/www/htdocs/media;
}
Генерируем ключ в терминале:
# openssl rand -hex 32
fc3ee9546f6e4bc0523f57d61859cc137aefeb8a6e2a7930b06a95c0135205a5
Согласно документации, ключ в формате keyval необходимо положить в файл, например сюда: /etc/nginx/nginx.jwt.key.json. Содержимое файла:
{"kid": "fc3ee9546f6e4bc0523f57d61859cc137aefeb8a6e2a7930b06a95c0135205a5"}
Снова перезагрузим Nginx
# systemctl restart nginx
Теперь можно проверить доступ по токену.