Настройка Indeed IDP аутентификации на RDweb / Webclient через OAuth2 Proxy + NGINX
Содержание:
- Предварительные требования
- Описание процесса
- Подготовка
- Настройка OAuth сервера
- Настройка NGINX сервера
- Настройка IDP сервера
- Настройка Redis DB
Предварительные требования:
Cхема взаимодействия и установки Nginx и OAuth2-proxy на разных машинах

Предполагается что установлен и настроен Indeed AM версии 8.1.5 и выше,
установлен и настроен rdweb\webclient.
Описание процесса:
На интернет шлюзе (internetgate.indeed.local) открывается порт 443, и пробрасывается на машину nginx.indeed.local, на 443 порт.
На nginx.indeed.local установлен nginx, для которого настроены правила публикации 3х порталов:
- Indeed IdP
- Rdweb
- oauth2-proxy
В Зависимости от URL, по которому происходит обращение, nginx распределяет запросы на конечные сервера.
Для URL, вида
- Rdweb\webclient
- /remoteDesktopGateway
Происходит проверка cookie авторизации, и в случае их отсутствия, все запросы с этих URL перенаправляются на oauth2-proxy.
oauth2-proxy делает запрос к Indeed IdP, на машину am1.indeed.local, через URL nginx.indeed.local (rdweb.indeed.local\am\idp), где пользователь проходит аутентификацию.
Затем, Indeed IdP отправляет ответ на rdweb.indeed.local\oauth2\, который перенаправляется на oauth2-proxy.
В случае успешной аутентификации, oauth2-proxy отправляет на nginx cookie пользователя, для доступа к закрытым ресурсам.
Nginx.indeed.local, получив cookie, пропускает пользователя к изначально запрошенному ресурсу.
Подготовка:
Cинхронизируем время на nginx, oauth, idp
apt-get install ntp -y nano /etc/ntp.conf

меняем на внутренний сервер времени
server 10.10.10.11 prefer iburst

Задаем часовой пояс
sudo timedatectl set-timezone Europe/Moscow
запускаем клиент времени
systemctl restart ntp
Настройка OAuth сервера
На сервере oauth.indeed.local
Т.к. rdweb публикуется с таким же именем, что и внутри домена, потребуется жесткая привязка имени rdweb.indeed.local ко внутреннему ip nginx
sudo nano /etc/hosts
укажем
10.10.10.8 oauth.indeed.local 10.10.10.7 rdweb.indeed.local

Устанавливаем oauth2-proxy актуальной версии (можно увидеть по ссылке https://github.com/oauth2-proxy/oauth2-proxy/releases)
wget https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.5.1/oauth2-proxy-v7.5.1.linux-amd64.tar.gz
tar xvzf oauth2-proxy-v7.5.1.linux-amd64.tar.gz
mv oauth2-proxy-v7.5.1.linux-amd64 /opt
Для удобства работы, сделаем символьную ссылку
ln -s /opt/oauth2-proxy-v7.5.1.linux-amd64 /opt/oauth2-proxy
Создадим файл конфигурации
sudo nano /etc/oauth2-proxy.cfg
provider="oidc"
client_id="nginx_oauth"
client_secret="Qq123456"
login_url="https://rdweb.indeed.local/am/idp/connect/authorize"
profile_url="https://rdweb.indeed.local/am/idp/connect/userinfo"
redeem_url="https://rdweb.indeed.local/am/idp/connect/token"
redirect_url="https://rdweb.indeed.local/oauth2/callback"
oidc_jwks_url="https://rdweb.indeed.local/am/idp/.well-known/jwks"
oidc_issuer_url="https://rdweb.indeed.local/am/idp"
provider_display_name="Indeed IdP"
custom_sign_in_logo="https://download.indeed-company.ru/s/fWgurqdspwkZJYN/download"
cookie_secret="UklyW3dPZTlRVW05OGorJn1Beno3QXpPT0tfTTNOYXs="
pass_access_token="true"
set_authorization_header="true"
insecure_oidc_allow_unverified_email="true"
scope="openid"
oidc_email_claim="email"
email_domains='*'
cookie_secure="true"
cookie_httponly="true"
cookie_name="oauth2_cookie"
cookie_samesite="lax"
cookie_csrf_per_request="true"
cookie_csrf_expire="15m0s"
cookie_expire="6h0m0s"
cookie_refresh="1h0m0s"
cookie_domains=".indeed.local"
force_https="true"
ssl_upstream_insecure_skip_verify="true"
ssl_insecure_skip_verify="true"
https_address=":4180"
tls_cert_file="/etc/ssl/certs/indeed.crt"
tls_key_file="/etc/ssl/certs/indeed.key"
tls_min_version="TLS1.2"
code_challenge_method="S256"
errors_to_info_log="true"
Таким образом, oauth2-proxy будет общаться с Indeed IdP, через nginx, т.к. потребуется пересылка данных, в том числе, через браузер пользователя.
Параметр “custom_sign_in_logo” - опционален, может ссылаться на любую картинку с логотипом.
Параметр “cookie_secret”- сгенерирован командой
openssl rand -base64 22
где 22 - число символов
Поместим файлы сертификата по пути /etc/ssl/certs/
/etc/ssl/certs/indeed.crt /etc/ssl/certs/indeed.key
Примечание - В составе indeed.crt, также должна быть вся цепочка сертификатов, во избежании проблем с nginx.
Для CA файла домена, в debian потребуются доп. действия:
apt install easy-rsa apt install ca-certificates
CA файл поместим по пути
/usr/local/share/ca-certificates/ca.crt
и добавим его в хранилище
update-ca-certificates
Создадим пользователя для запуска службы
export PATH="$PATH:/sbin:/usr/sbin:usr/local/sbin"
useradd -d /dev/null -s /usr/sbin/nologin oauth2-proxy
или
sudo adduser oauth2-proxy --system --no-create-home
Добавим группу
groupadd oauth2-proxy
usermod -a -G oauth2-proxy oauth2-proxy
Выдадим права на каталог
chmod -R 775 /opt/oauth2-proxy
chown -R oauth2-proxy:oauth2-proxy /opt/oauth2-proxy/
chmod 755 /etc/oauth2-proxy.cfg
Создадим службу oauth2-proxy
sudo systemctl edit --full --force oauth2-proxy.service
[Unit]
Description=reverse proxy
[Service]
Type=simple
User=oauth2-proxy
WorkingDirectory=/opt/oauth2-proxy
EnvironmentFile=/etc/oauth2-proxy.cfg
ExecStart=/opt/oauth2-proxy/oauth2-proxy --config=/etc/oauth2-proxy.cfg
Restart=always
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=process
[Install]
WantedBy=multi-user.target
systemctl daemon-reload systemctl enable oauth2-proxy systemctl start oauth2-proxy
Просмотреть файл конфигурации службы oauth2-proxy, можно командой: sudo nano /etc/systemd/system/oauth2-proxy.service
Настройка NGINX сервера
Переходим к серверу nginx.indeed.local
Используется ОС Ubuntu 22.04 LTS
Обновляем установленные пакеты:
apt-get update -y && apt-get upgrade -y && apt-get dist-upgrade -y
Устанавливаем nginx:
sudo apt install nginx -y
Подготовим файлы сертификатов для работы.
Каталог для хранения:
mkdir /etc/nginx/ssl
Сохраним файлы
/etc/nginx/ssl/proxy.crt; /etc/nginx/ssl/proxy_private.key;
где:
proxy.crt - открытая часть сертификата,
proxy_private.key - приватный ключ сертификата без пароля.
Сгенерируйте свой файл dhparam, для алгоритмов семейства DHE/EDH (рекомендуемая минимальная длина ключа 4096 бит)
Этот процесс займёт несколько минут. Ключи DH будут помещены в /etc/nginx/ssl/dhparam.pem
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
или скачайте общедоступный 2048 битный
wget -O /etc/nginx/ssl/dhparam.pem https://ssl-config.mozilla.org/ffdhe2048.txt
Создадим файл настроек:
nano /etc/nginx/sites-available/rdweb.indeed.local
С Содержимым:
#ddos protect
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
#end ddos protect
#proxy_cache_path /cache/validate levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off;
server {
listen 80;
server_name rdweb.indeed.local www.rdweb.indeed.local indeed.local;
#return 301 https://$server_name$request_uri;
return 301 https://$server_name/RDWeb/webclient/;
}
server {
large_client_header_buffers 8 64k;
proxy_buffering on;
proxy_buffer_size 64k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 64k;
#proxy tune
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 64k;
#end proxy tune
listen 443 ssl;
# http2;
server_name rdweb.indeed.local www.rdweb.indeed.local indeed.local;
#logs
access_log /var/log/nginx/access.log ;
error_log /var/log/nginx/error.log ;
# SSL config
ssl_certificate /etc/nginx/ssl/proxy.crt;
ssl_certificate_key /etc/nginx/ssl/proxy_private.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# intermediate configuration
ssl_protocols TLSv1.2;
# TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' ;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
location /am/idp {
#ddos
limit_req zone=one burst=10 nodelay;
limit_req_status 444;
#end ddos
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
### This is the header referenced above ###
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' data: ;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_connect_timeout 120s;
send_timeout 120s;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_pass https://am1.indeed.local$request_uri;
proxy_ssl_session_reuse on;
proxy_ssl_protocols TLSv1.2;
resolver 10.10.10.11;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
location /oauth2/ {
proxy_pass https://oauth.indeed.local:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
resolver 10.10.10.11;
#ddos
limit_req zone=one burst=10 nodelay;
limit_req_status 444;
#end ddos
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
### This is the header referenced above ###
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' https://download.indeed-company.ru;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_connect_timeout 120s;
send_timeout 120s;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
location = /oauth2/auth {
proxy_pass https://oauth.indeed.local:4180;
resolver 10.10.10.11;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
#аутентификация и меню доступных приложений
location /RDWeb/webclient {
#oauth2
#старт требование аутентификации
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
#auth_request_set $email $upstream_http_x_auth_request_email;
#proxy_set_header X-Email $email;
auth_request_set $user $upstream_http_x_auth_request_user;
proxy_set_header X-User $user;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
#конец требование аутентификации
#ddos
limit_req zone=one burst=20 nodelay;
limit_req_status 444;
#end ddos
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
### This is the header referenced above ###
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' ;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_connect_timeout 120s;
send_timeout 120s;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://rdweb.indeed.local/RDWeb/webclient/;
proxy_ssl_session_reuse on;
proxy_ssl_protocols TLSv1.2;
resolver 10.10.10.11;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
#удаленка по html5
location ~^/remoteDesktopGateway(.*)$ {
#oauth2
#старт требование аутентификации
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
#auth_request_set $email $upstream_http_x_auth_request_email;
#proxy_set_header X-Email $email;
auth_request_set $user $upstream_http_x_auth_request_user;
proxy_set_header X-User $user;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
#конец требование аутентификации
#ddos
limit_req zone=one burst=10 nodelay;
limit_req_status 444;
#end ddos
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
### This is the header referenced above ###
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' blob: data: ;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_connect_timeout 120s;
send_timeout 120s;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto https;
#proxy_set_header X-Forwarded-Port 443;
proxy_pass https://rdweb.indeed.local$request_uri;
#proxy_pass $scheme://rdweb.indeed.local/RDWeb/webclient/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#proxy_read_timeout 86400;
proxy_ssl_session_reuse on;
proxy_ssl_protocols TLSv1.2;
resolver 10.10.10.11;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
#классический rdweb
location /RDWeb {
#ddos
limit_req zone=one burst=20 nodelay;
limit_req_status 444;
#end ddos
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
### This is the header referenced above ###
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' ;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_connect_timeout 120s;
send_timeout 120s;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_pass https://rdweb.indeed.local/RDWeb/;
proxy_ssl_session_reuse on;
proxy_ssl_protocols TLSv1.2;
resolver 10.10.10.11;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
#поведение по умолчанию
location / {
#ddos
#limit_req zone=one burst=5 nodelay;
#limit_req_status 444;
#end ddos
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
#Expect-CT
add_header Expect-CT 'enforce; max-age=604800';
#header The anti-clickjacking X-Frame-Options SAMEORIGIN / DENY
add_header X-Frame-Options SAMEORIGIN always;
#X-XSS-Protection
add_header X-XSS-Protection "1; mode=block";
#X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "connect-src 'self' ;
font-src 'self' ;
frame-src 'self' ;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' ;
manifest-src 'self';
media-src 'self';
object-src 'self';
worker-src 'self';
frame-ancestors 'self';
form-action 'self';" always;
#переадресуем на страницу входа
return 301 https://$server_name/RDWeb/webclient/;
#скрываем на чем запущено
proxy_hide_header X-Powered-By;
}
}
В приведенном файле конфигурации, требуется аутентификация через IdP модуль, для двух URL
/RDWeb/webclient - Основное окно входа в webclient
~^/remoteDesktopGateway(.*)$ - маска URL адреса, для работы RDP через webclient
Для /RDWeb запроса IdP не происходит (в целях примера работы).
Для добавления требования аутентификации, в нужный location добавляется
#старт требование аутентификации
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
#auth_request_set $email $upstream_http_x_auth_request_email;
#proxy_set_header X-Email $email;
auth_request_set $user $upstream_http_x_auth_request_user;
proxy_set_header X-User $user;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
#конец требование аутентификации
Который требует наличия куки аутентификации.
Для пересылки данных аутентификации, в пределах oauth2-proxy и ответа с Indeed IdP, используются:
location /oauth2/
location = /oauth2/auth
Создадим символьную ссылку
ln -s /etc/nginx/sites-available/rdweb.indeed.local /etc/nginx/sites-enabled/rdweb.indeed.local
Удалим default страницу
rm /etc/nginx/sites-available/default
rm /etc/nginx/sites-enabled/default
Проверим файл конфигурации
nginx -t
Отключаем версию nginx
sudo nano /etc/nginx/nginx.conf
добавить
server_tokens off;

В случае отсутствия ошибок, перезапустим службу и добавим в автозагрузку
systemctl restart nginx
systemctl enable nginx
Настройка IDP сервера
Переходим на am1.indeed.local, для настройки Indeed IdP
В файле
C:\inetpub\wwwroot\am\idp\app-settings.json
Добавляем настройку провайдера для работы с oauth2-proxy
,{
"ClientId": "nginx_oauth",
"ClientSecret": "Qq123456",
"DisplayName": "nginx proxy auth request oauth2",
"Permissions": [
"ept:authorization",
"ept:device",
"ept:introspection",
"ept:logout",
"ept:revocation",
"ept:token",
"gt:authorization_code",
"gt:client_credentials",
"gt:urn:ietf:params:oauth:grant-type:device_code",
"gt:implicit",
"gt:password",
"gt:refresh_token",
"rst:code",
"rst:code id_token",
"rst:code id_token token",
"rst:code token",
"rst:id_token",
"rst:id_token token",
"rst:none",
"rst:token",
"scp:address",
"scp:email",
"scp:phone",
"scp:profile",
"scp:roles"
],
"RedirectUris": [
"https://rdweb.indeed.local/oauth2/callback"
]
}
где
"ClientId": "nginx_oauth" - ID oidc клиента, указываемый в client_id на стороне oauth2-proxy
"ClientSecret": "Qq123456" - общий ключ с client_secret на стороне oauth2-proxy
"RedirectUris" - адрес, на который возвращается ответ от IdP, через браузер пользователя

Далее, в том же файле, добавим отправку email адреса в ответе
в секции “CustomAttributes”
добавим:
{
"ServiceProvider": "nginx_oauth",
"Attributes": [
{
"Name": "email",
"UserNameFormat": "Email"
}
]
}

Убедимся, что указан сертификат для работы с oidс, для подписи ответа
"OIDC": {
"IDP": {
"CertificateThumbprint": "d2846fb4d27f1865418501618dbbe51d9e4aae42"
},
где “d2846fb4d27f1865418501618dbbe51d9e4aae42” - сертификат в локальном хранилище системы.
Сохраняем файл.
В файл C:\inetpub\wwwroot\am\idp\Web.config
Вносим изменения:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<!-- Removing server header settings for IIS versions >=10.0
for earlier versions use IIS extension "URL Rewrite"-->
<security>
<requestFiltering removeServerHeader="true">
<verbs>
<add verb="TRACE" allowed="false" />
<add verb="TRACK" allowed="false" />
</verbs>
</requestFiltering>
</security>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\AM.IDP.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
<system.web>
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
</system.web>
</configuration>

Перезапускаем IIS сервер.
Проверяем работу.
При переходе по ссылке:
https://rdweb.indeed.local/RDWeb/webclient/
Происходит внутреннее перенаправление на страницу входа






Настройка Redis DB
Используем БД Redis для хранения пары id-сессии.секрет, вместо хранения секрета в куки.
В качестве примера, будем использовать автономный вариант Redis (возможна настройка кластера Redis Sentinel), установленный на том же сервере, что и Oauth2.
Установка
sudo apt install redis-server -y
Зададим систему управления для службы Redis
sudo nano /etc/redis/redis.conf

меняем
supervised no
на
supervised systemd
Т.к. мы предполагаем локальную установку redis, и к ней доступ должен иметь только oauth2, то убедимся, что подключаться можно только локально
sudo nano /etc/redis/redis.conf
должна быть привязка только
bind 127.0.0.0 ::1

Защитим подключение к Redis, с помощью мастер пароля.
для этого, сгенерируем случайный пароль
openssl rand 128 | openssl base64 -A

и добавим пароль в параметр requirepass

перезапускаем службу
sudo systemctl restart redis.service
добавляем в автозагрузку
sudo systemctl enable redis-server.service
Сконфигурируем Oauth2-Proxy, на работу с Redis
sudo nano /etc/oauth2-proxy.cfg
Оставляем cookie_secret, т.к. этот параметр является обязательным для конфигурационного файла oauth2-proxy
При этом, согласно документации, секреты для куки будут храниться в Redis:
{CookieName}-{ticketID}.{secret}
Where:
- The CookieName is the OAuth2 cookie name (_oauth2_proxy by default)
- The ticketID is a 128 bit random number, hex-encoded
- The secret is a 128 bit random number, base64url encoded (no padding). The secret is unique for every session.
- The pair of {CookieName}-{ticketID} comprises a ticket handle, and thus, the redis key to which the session is stored.
добавляем 3 строки
session_store_type="redis"
redis_password="8wh2Ahz8gIo43ENGiX7rVPhtwU6+5J4HRUEyg6OGD2vzisVaNXOlsy2BbIH90Ksjck9yRpd1WvBKkdN37UzOSC0BquDTkdyA/PLL0Nz8mHdHiXZgh2hg16dGQHBYw1xGQzJp13KB5LRJRXRblOQu2fwWnXeVAzP7YpQEkwgamxY="
redis_connection_url="redis://localhost:6379"

Перезапускаем Oauth2
systemctl start oauth2-proxy
Проверяем.
Размер куки, передаваемых клиенту, значительно уменьшается

в DB Redis появляется соответствующая запись


|