Настройка аутентификации NGINX через LDAP с помощью модуля SPNEGO

Thank you for reading this post, don't forget to subscribe!

Модуль SPNEGO для NGINX — это про­грамм­ный ком­по­нент для воз­мож­но­сти про­хож­де­ния аутен­ти­фи­ка­ции (Single Sign-On или SSO) через сер­вер LDAP.

1. Имя сервера

В про­цес­се настрой­ки аутен­ти­фи­ка­ции через LDAP нам необ­хо­ди­мо будет задать в каче­стве прин­ци­па­ла имя наше­го сервера:

hostnamectl set-hostname nginx.domain.local

* пред­по­ла­га­ет­ся, что в нашем слу­чае имя сер­ве­ра будет nginx.domain.local (домен domain.local).

2. Настройка времени

Для рабо­ты с LDAP нам необ­хо­ди­мо, что­бы вре­мя на послед­нем сов­па­да­ло с вре­ме­нем на нашем веб-сер­ве­ре. Самый пра­виль­ный спо­соб это­го добить­ся — настро­ить синхронизацию.

Для нача­ла настра­и­ва­ем вре­мен­ную зону:

timedatectl set-timezone Europe/Moscow

* в дан­ном при­ме­ре мы зада­ем зону по мос­ков­ско­му вре­ме­ни. Спи­сок все доступ­ных зон мож­но посмот­реть коман­дой timedatectl list-timezones.

Уста­нав­ли­ва­ем ути­ли­ту для син­хро­ни­за­ции вре­ме­ни, настра­и­ва­ем ее, раз­ре­ша­ем запуск демо­на и стар­ту­ем его. Набор команд будет зави­сеть от дис­три­бу­ти­ва Linux.

а) если на систе­ме Ubuntu / Debian:

apt-get install chrony

vi /etc/chrony/chrony.conf

 

* в дан­ном при­ме­ре мы ука­за­ли в каче­стве сер­ве­ра син­хро­ни­за­ции любой кон­трол­лер доме­на. Осталь­ные настрой­ки pool необ­хо­ди­мо закомментировать.

systemctl enable chrony

systemctl restart chrony

б) если на систе­ме CentOS / Red Hat:

yum install chrony

vi /etc/chrony.conf

* в дан­ном при­ме­ре мы ука­за­ли в каче­стве сер­ве­ра син­хро­ни­за­ции любой кон­трол­лер доме­на. Осталь­ные настрой­ки pool необ­хо­ди­мо закомментировать.

systemctl enable chronyd --now

3. Настройка безопасности

Для кор­рект­ной рабо­ты наше­го веб-сер­ве­ра необ­хо­ди­мо открыть пор­ты http и https. Дей­ствия будут отли­чать­ся в зави­си­мо­сти от исполь­зу­е­мо­го брандмауэра.

а) Iptables (как пра­ви­ло, на Ubuntu/Debian или ран­них вер­си­ях CentOS):

iptables -I INPUT -p tcp --match multiport --dports 80,443 -j ACCEPT

Для сохра­не­ния пра­вил уста­нав­ли­ва­ем iptables-persistent и запус­ка­ем утилиту:

apt-get install iptables-persistent

netfilter-persistent save

б) Firewalld (как пра­ви­ло, на позд­них вер­си­ях CentOS):

firewall-cmd --permanent --add-service=http{,s}

firewall-cmd --reload

Так­же на систе­мах с акти­ви­ро­ван­ным SELinux (как правило, )

setenforce 0

sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

Сборка и установка NGINX с модулем SPNEGO

Встро­ен­ных средств NGINX недо­ста­точ­но для реа­ли­за­ции нашей зада­чи, поэто­му необ­хо­ди­мо исполь­зо­вать бес­плат­ный модуль SPNEGO. Мы можем выпол­нить это дву­мя методами:

  1. Собрать NGINX с добав­ле­ни­ем модуля.
  2. Собрать дина­ми­че­ский модуль SPNEGO и под­клю­чить его к уже рабо­та­ю­ще­му NGINX.

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

Сборка NGINX с модулем SPNEGO

Выпол­ня­ем сбор­ку в несколь­ко эта­пов. Раз­бе­рем их по очереди:

1. Установка зависимостей

Для сбор­ки нам нуж­ны паке­ты, от кото­рых зави­сит про­цесс кон­фи­гу­ри­ро­ва­ния. В зави­си­мо­сти от опе­ра­ци­он­ной систе­мы, коман­ды будут отличаться.

а) для Ubuntu/Debian:

apt-get update

apt-get install wget git build-essential libpcre++-dev zlib1g-dev libkrb5-dev libssl-dev libxslt-dev libgd-dev

б) для CentOS:

yum install epel-release

yum install wget git pcre-devel openssl-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed gperftools-devel

2. Загрузка исходников

Загру­зим исход­ник для nginx и моду­ля SPNEGO.

Пере­хо­дим на стра­ни­цу загруз­ки nginx и копи­ру­ем ссыл­ку на нуж­ную вер­сию веб-сервера:

* в дан­ном при­ме­ре мы будем загру­жать nginx вер­сии 1.20.0.

С помо­щью ско­пи­ро­ван­ной ссыл­ки, загру­жа­ем исход­ник веб-сервера:

wget https://nginx.org/download/nginx-1.20.0.tar.gz

После рас­па­ко­вы­ва­ем его:

tar zxvf nginx-*.tar.gz

Пере­хо­дим в рас­па­ко­ван­ную папку:

cd nginx-*/

Кло­ни­ру­ем репо­зи­то­рий для моду­ля SPNEGO:

git clone https://github.com/stnoonan/spnego-http-auth-nginx-module.git

Мы гото­вы к сборке.

3. Сборка и установка пакета

Для раз­ных систем мы выпол­ним раз­ные коман­ды кон­фи­гу­ри­ро­ва­ния пакета.

а) на Ubuntu/Debian:

б) на Centos:


 

Соби­ра­ем пакет:

make

Выпол­ня­ем установку:

make install

4. Завершение настройки системы

Что­бы nginx мог кор­рект­но запу­стить­ся, выпол­ним несколь­ко пред­ва­ри­тель­ных действий.

Созда­дим поль­зо­ва­те­ля nginx:

useradd --no-create-home nginx

Созда­дим ката­лог /var/lib/nginx:

mkdir -p /var/lib/nginx

Про­ве­рим, что nginx  про­хо­дит про­вер­ку кон­фи­гу­ра­ци­он­но­го файла:

nginx -t

Мы долж­ны увидеть:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

5. Создаем юнит в systemd и стартуем сервис

Для запус­ка nginx в каче­стве сер­ви­са, созда­ем файл:

vi /lib/systemd/system/nginx.service

Пере­чи­ты­ва­ем кон­фи­гу­ра­ци­он­ные фай­лы в systemd:

systemctl daemon-reload

Раз­ре­ша­ем авто­за­пуск сер­ви­са и стар­ту­ем его:

systemctl enable nginx

systemctl start nginx

Сборка и подключение динамического модуля

Дан­ный спо­соб немно­го отли­ча­ет­ся по дей­стви­ям и кон­фи­гу­ри­ро­ва­нию, но суть про­цес­са та же. Рас­смот­рим его по шагам.

1. Установка NGINX

Пред­по­ла­га­ет­ся, что nginx уста­нов­лен в систе­ме. Ина­че, уста­нов­ку мож­но выпол­нить из репо­зи­то­рия в зави­си­мо­сти от дис­три­бу­ти­ва Linux.

а) Для Ubuntu/Debian:

apt-get update

apt-get install nginx

б) Для CentOS:

yum install epel-release

yum install nginx

Запус­ка­ем NGINX и раз­ре­ша­ем авто­старт сервиса:

systemctl start nginx

systemctl enable nginx

2. Установка зависимостей

Для сбор­ки нам нуж­ны паке­ты, от кото­рых зави­сит про­цесс кон­фи­гу­ри­ро­ва­ния. В зави­си­мо­сти от опе­ра­ци­он­ной систе­мы, коман­ды будут отличаться.

а) для Ubuntu/Debian:

apt-get install wget git build-essential libpcre++-dev zlib1g-dev libkrb5-dev libssl-dev libxslt-dev libgd-dev

б) для CentOS:

yum install wget git pcre-devel openssl-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed gperftools-devel redhat-rpm-config

3. Загрузка исходников

Загру­зим исход­ник для nginx и моду­ля SPNEGO.

Для нача­ла, смот­рим вер­сию уста­нов­лен­но­го NGINX:

nginx -v

Пере­хо­дим на стра­ни­цу загруз­ки nginx и копи­ру­ем ссыл­ку на уста­нов­лен­ную вер­сию в нашей системе:

* в дан­ном при­ме­ре мы будем загру­жать nginx вер­сии 1.16.1.

С помо­щью ско­пи­ро­ван­ной ссыл­ки, загру­жа­ем исход­ник веб-сервера:

wget https://nginx.org/download/nginx-1.16.1.tar.gz

После рас­па­ко­вы­ва­ем его:

tar zxvf nginx-*.tar.gz

Пере­хо­дим в рас­па­ко­ван­ную папку:

cd nginx-*/

Кло­ни­ру­ем репо­зи­то­рий для моду­ля SPNEGO:

git clone https://github.com/stnoonan/spnego-http-auth-nginx-module.git

Мы гото­вы к сборке.

4. Сборка и установка модуля

Смот­рим, с каки­ми опци­я­ми собран уста­нов­лен­ный NGINX:

nginx -V

В ответ мы полу­чим спи­сок опций — нам нуж­но все, что идет после configure arguments, например:


Нам нуж­но вве­сти коман­ду с синтаксисом:

./configure <спи­сок опций nginx -V> --add-dynamic-module=<путь до модуля>

В моем слу­чае, это:

Соби­ра­ем модуль:

make modules

Гото­во. В ката­ло­ге objs появит­ся файл ngx_http_auth_spnego_module.so. Нам нуж­но его ско­пи­ро­вать в ката­лог с биб­лио­те­ка­ми. В зави­си­мо­сти от систе­мы и опций сбор­ки, этот ката­лог может нахо­дить­ся по раз­но­му пути.

а) Для Ubuntu/Debian (как правило):

cp objs/ngx_http_auth_spnego_module.so /usr/lib/nginx/modules/

б) Для CentOS (как правило):

cp objs/ngx_http_auth_spnego_module.so /usr/lib64/nginx/modules/

* более точ­ный путь мож­но посмот­реть коман­дой nginx -V — сре­ди полу­чен­ных опций най­ти --modules-path.

5. Подключение модуля в NGINX

Наш модуль в нуж­ном ката­ло­ге, но что­бы веб-сер­вер его мог исполь­зо­вать, необ­хо­ди­мо вне­сти изме­не­ния в кон­фи­гу­ра­ци­он­ный файл. Пути немно­го отли­ча­ют­ся для раз­ных дис­три­бу­ти­вов Linux.

а) Ubuntu/Debian:

vi /etc/nginx/modules-enabled/spnego-http-auth-nginx-module.conf

load_module "/usr/lib/nginx/modules/ngx_http_auth_spnego_module.so";

б) CentOS:

vi /usr/share/nginx/modules/spnego-http-auth-nginx-module.conf

load_module "/usr/lib64/nginx/modules/ngx_http_auth_spnego_module.so";

* напом­ню, что точ­ный путь до фай­ла ngx_http_auth_spnego_module.so может быть другим.

Про­ве­ря­ем, кор­рект­ность настрой­ки nginx:

nginx -t

Мы долж­ны увидеть:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Мож­но пере­за­пус­кать NGINX:

systemctl restart nginx

Создание учетной записи в AD и файла keytab

Для под­клю­че­ния к кон­трол­ле­ру доме­на нам необ­хо­ди­мо под­твер­ждать под­лин­ность. Это выпол­ня­ет­ся с помо­щью учет­ной запи­си в LDAP и фай­ла keytab.

Создание учетной записи

Откры­ва­ем кон­соль управ­ле­ния поль­зо­ва­те­ля­ми и добав­ля­ем ново­го со стан­дарт­ны­ми пра­ва­ми. От этой учет­ной запи­си будут выпол­нять­ся запро­сы к AD DS.

В сво­ем при­ме­ре мы созда­ем поль­зо­ва­те­ля spnego.

Учет­ная запись долж­на быть раз­ме­ще­на по пути, в кото­ром при­сут­ству­ют назва­ния толь­ко на лати­ни­це. Под­раз­де­ле­ния и кон­тей­не­ры не долж­ны быть на рус­ском. В про­тив­ном слу­чае, при выпол­не­нии коман­ды ниже мы полу­чим ошиб­ку «Password set failed! 0x00000020».

Создание keytab-файла

В двух сло­вах, дан­ный файл поз­во­ля­ет прой­ти иден­ти­фи­ка­цию в Kerberos без запро­са паро­ля. Он содер­жит пары имен субъ­ек­тов Kerberos и зашиф­ро­ван­ные клю­чи, полу­чен­ные из паро­ля Kerberos.

Мы созда­дим дан­ный файл на кон­трол­ле­ре доме­на и ско­пи­ру­ем на сер­вер NGINX. Для это­го на кон­трол­ле­ре доме­на и от име­ни адми­ни­стра­то­ра запус­ка­ем Powershell или обыч­ную команд­ную стро­ку. Вводим:

* где:

  • nginx.domain.local — пол­ное имя наше­го nginx-сервера;
  • DOMAIN.LOCAL — наш домен;
  • spnego@DOMAIN.LOCAL — учет­ная запись в AD для выпол­не­ния запро­сов (созда­на на шаге выше);
  • pass * — пароль, кото­рый будет задан поль­зо­ва­те­лю (дол­жен соот­вет­ство­вать тре­бо­ва­нию AD). Систе­ма запро­сит его ввод дважды.

* регистр важен.

В нашем при­ме­ре, после выпол­не­ния коман­ды на кон­трол­ле­ре доме­на в корне дис­ка С появит­ся файл spnego.keytab. Его копи­ру­ем на Linux-сер­вер, напри­мер, при помо­щи WinSCP.

Настройка Linux для интеграции с AD

Для инте­гра­ции Linux с нашим LDAP (в дан­ном при­ме­ре, на осно­ве Active Directory) уста­но­вим необ­хо­ди­мые паке­ты и настро­им Kerberos.

Установка пакетов

Необ­хо­ди­мые паке­ты ста­вим из репозиториев.

а) на Ubuntu/Debian:

apt-get install heimdal-clients

б) на Centos:

yum install krb5-workstation

Проверка файла

Пере­хо­дим в ката­лог с фай­лом keytab и выпол­ня­ем команду:

kinit -kt spnego.keytab HTTP/nginx.domain.local@DOMAIN.LOCAL

* напом­ним, что spnego.keytab — имя наше­го фай­ла; HTTP/nginx.domain.local@DOMAIN.LOCAL — прин­ци­пал, для кото­ро­го сге­не­ри­ро­ван файл.

Коман­да нам ниче­го не долж­на вер­нуть. Это зна­чит, что она выпол­не­на корректно.

Теперь выпол­ним:

klist

Мы долж­ны уви­деть что-то на подобие:


В дан­ном отве­те мы видим, что нам выдан билет для прин­ци­па­ла HTTP/nginx.domain.local@DOMAIN.LOCAL. Идем дальше.

Настройка kerberos

Откры­ва­ем на редак­ти­ро­ва­ние файл:

vi /etc/krb5.conf

При­во­дим его к виду (осталь­ные стро­ки не трогаем):

DOMAIN.LOCAL — наш домен; kdc — пере­чень кон­трол­ле­ров доме­на; admin_server — пер­вич­ный кон­трол­лер (в дан­ном при­ме­ре будет исполь­зо­вать­ся случайный).

Настройка аутентификации на NGINX

Пере­хо­дим к настрой­ке само­го веб-сер­ве­ра. Для нача­ла, пере­не­сем наш файл keytab в ката­лог NGINX:

mv spnego.keytab /etc/nginx/

Откры­ва­ем файл nginx с настрой­ка­ми для вир­ту­аль­но­го доме­на или глав­ный кон­фи­гу­ра­ци­он­ный файл.

а) при­мер для Ubuntu/Debian:

vi /etc/nginx/sites-enabled/default

б) при­мер для CentOS:

vi /etc/nginx/nginx.conf

В сек­ции server добавляем:


Пере­за­пус­ка­ем NGINX:

systemctl restart nginx

Гото­во. Про­бу­ем зай­ти на наш сайт.

1. В каче­стве аль­тер­на­тив­но­го моду­ля для осу­ществ­ле­ния basic-аутен­ти­фи­ка­ции через ldap может исполь­зо­вать­ся nginx-ldap-auth. Он так­же дол­жен быть загру­жен и добав­лен при сборке.

2. В инструк­ции исполь­зу­ет­ся при­мер сбор­ки паке­та на целе­вом сер­ве­ре. Это не совсем пра­виль­но, так как остав­ля­ет после себя мно­го мусо­ра. Сбор­ку луч­ше осу­ществ­лять на дру­гом ком­пью­те­ре или в кон­тей­не­ре Docker.