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

Настройка параметров nginx логин центра

Info

В дистрибутиве логин центра идут шаблоны nginx для настройки параметров работы. Все взаимодействие с логин центром идет по защищенному каналу с использованием https протокола. В дистрибутиве базовые настройки выполнены.

Если вам требуется использовать свои параметры по требованиям информационной безопасности, можно использовать данную инструкцию.

Warning

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

lc_https_config_1.png

А настройки HSTS не дадут войти на логин центр.

lc_https_config_2.png

Все файлы конфигурации nginx находятся в каталоге data/nginx/ переходим в каталог логин центра

cd /om/login-center
если его нет, необходимо создать:

mkdir -p /om/{login-center/data/nginx/{cert,templates},login-center-installer}

Генерируем dhparam файл

openssl dhparam -out data/nginx/cert/dhparam.pem 2048

Или используя большую длину ключа.

openssl dhparam -out data/nginx/cert/dhparam.pem 4096

В зависимости от производительности системы это может занять более продолжительное время.

Правки шаблонов конфигурации

Основной шаблон конфигурации логин центра data/nginx/templates/443.conf.template Вносим правки в него приводя к следующему виду

data/nginx/templates/443.conf.template
log_format with_upstream '$remote_addr - $remote_user [$time_local] '
    'UPSTREAM($proxy_host $upstream_addr $upstream_http_location) '
    'WS(ws_name="$ws_name", ws_domain="$ws_domain" ws_schema="$ws_schema", ws_websocket_port="$ws_websocket_port", ws_path="$ws_path", WSURL="$ws_schema://$ws_domain:$ws_websocket_port/", URL="$ws_schema://$ws_domain/$ws_path$is_args$args") '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" "$gzip_ratio"';

map $request_uri $ws_name { "~^/ws/([^/]+)/" $1; }
map $request_uri $ws_path { "~^/ws/[^/]+/([^\?]*)(\?.+)?$" $1; }

map $ws_name $ws_domain {
    include templates/workspace_domains.txt;
    default "127.0.0.1:38882";
    volatile;
}

map $ws_name $ws_schema {
    include templates/workspace_schemas.txt;
    default "https";
    volatile;
}

map $ws_name $ws_websocket_port {
    include templates/workspace_websocket_ports.txt;
    default "8081";
    volatile;
}

# Блок параметров http nginx
# Disable potentially dangerous modules / features
dav_methods off;
gzip        off;

send_timeout           2;
client_header_timeout  10;
client_body_timeout    10;
large_client_header_buffers 8 32k;

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name _;

    ssl_certificate     /etc/nginx/ssl/bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/crt.key;
    return 444;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name ${NGINX_HOST};

    root /var/www/static;

    ssl_certificate     /etc/nginx/ssl/bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/crt.key;

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options SAMEORIGIN always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    if ($request_method !~ ^(GET|POST|PUT|DELETE|PATCH|OPTIONS)$ ) {
        return 405;
    }

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffer_size 8k;
    proxy_buffers 2 8k;
    proxy_busy_buffers_size 8k;

    keepalive_timeout 9;

    location /ws/ {

#        access_log /var/www/static/ws_log.txt with_upstream;

        proxy_cookie_domain $ws_domain ${NGINX_HOST};
        proxy_cookie_path / /ws/$ws_name/;

        # as workspace redirects to an "root url" addr without the trailing slash,
        # we have to capture this special case specially...
        proxy_redirect $ws_schema://$ws_domain/ $scheme://${NGINX_HOST}/ws/$ws_name/;
        proxy_redirect $ws_schema://$ws_domain $scheme://${NGINX_HOST}/ws/$ws_name/;

        location ~ /ws/(?<wsname>[^\/]+)/appConfig\-lc\.js {
            rewrite ^ /workspace/$wsname/appConfig.js last;
        }

        location ~ /ws/[^/]+/ws {
            proxy_pass $ws_schema://$ws_domain:$ws_websocket_port/;
#            rewrite ^ / break;
#            proxy_pass https://echo.websocket.org;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
        }

        location ~ /ws/(?<wsname>[^/]+)$ {
            return 301 https://$host$request_uri/;
        }

        location ~ /ws/(?<wsname>[^/]+)/ {
            proxy_pass $ws_schema://$ws_domain/$ws_path$is_args$args;
        }
    }

    location @error {
        root       /var/www/static;
        try_files /server_down.html =404;
    }

    location /json {
        set $upstream "${FRONTEND_IP}:8885";
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;
        proxy_pass http://$upstream;
    }

    location /socket.io/ {
        set $upstream "${FRONTEND_IP}:8885";
        proxy_pass http://$upstream;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $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-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    location / {
        error_page 502 =502 @error;
        error_page 503 =503 @error;
        error_page 504 =504 @error;
        set $upstream "${FRONTEND_IP}:8885";
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;
        proxy_pass http://$upstream;
    }

    location /ui/ {
        set $upstream "${FRONTEND_IP}:8885";
        proxy_pass http://$upstream;
    }

    location /s/oauth/ {
        set $upstream "${OPENID_PROVIDER}:5542";
        proxy_pass http://$upstream;
    }

    location /api/v1/ {
        set $upstream "${REST_API_IP}:5540";
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  off;
        proxy_pass http://$upstream;
    }

    location /api/ws/v1/ {
        set $upstream "${WORKSPACE_API_IP}:8886";
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  off;
        proxy_pass http://$upstream;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }

    location /api/public/v1/ {
        set $upstream "${PUBLIC_HTTP_GW_IP}:5555";
        rewrite ^/api/public/v1/(.*)$ /$1 break;
        proxy_pass http://$upstream;
    }

    location /api/v2/ {
        set $upstream "${FRONTEND_GW_IP}:5556";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        rewrite ^/api/v2/(.*)$ /$1 break;
        proxy_pass http://$upstream;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        location ^~ /api/v2/socket.io/ {
            set $upstream "${FRONTEND_GW_IP}:5556";
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_pass http://$upstream;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }    

    location /service/ {
        set $upstream "${SERVICE_WS_GW_IP}:5556";
        rewrite ^/service/(.*)$ /$1 break;
        proxy_pass http://$upstream;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        location ^~ /service/socket.io/ {
            set $upstream "${SERVICE_WS_GW_IP}:5556";
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_pass http://$upstream;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }

    location /service-monitor/ {
        set $upstream "${SERVICE_MONITOR_IP}:3000";
        rewrite ^/service-monitor/(.*)$ /$1 break;
        proxy_pass http://$upstream;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

}

# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
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;

server_tokens off;

# see also ssl_session_ticket_key alternative to stateful session cache
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions

ssl_dhparam         /etc/nginx/ssl/dhparam.pem;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

resolver 127.0.0.11 ipv6=off valid=10s;
resolver_timeout 5s;

# Limits per IP
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_req_zone  $binary_remote_addr zone=req_per_ip:10m rate=5r/s;

# Hide proxy headers globally
proxy_hide_header X-Powered-By;
proxy_hide_header Server;

В директиве ssl_dhparam путь до файла указан как /etc/nginx/ssl/dhparam.pem Это нормально. Локальный каталог data/nginx/cert пробрасывается внутрь контейнера по данному пути со всем содержимым. Если вы сгенерировали dhparam файл с отличным от указанного именем, тут можно скорректировать имя, но не путь.

Обратите внимание на директиву add_header Strict-Transport-Security "max-age=63072000" always; Ее следует использовать только с квалифицированными сертификатами. Без нее вы можете в браузере выбрать доверять сертификату и получить доступ к сайту. Этот параметр отключает данную возможность и требует взаимодействовать с браузером только по https протоколу. Если есть сомнения в вашем сертификате, ее лучше отключить или уменьшить для проверки возможности работы max-age до небольшого значения. Например до 300. Задается в секундах. Здесь задано значение в 2 года.

Совместная установка с воркспейсом.

Совместной установке логин центра и воркспейса посвящена отдельная инструкция Изучите ее. Здесь мы остановимся только на нюансах.

В инструкции приведен шаблон конфигурации nginx для проксирования запросов в lxc контейнер воркспейса. Мы можем его тоже скорректировать в соответствии с необходимыми. Например приводим к такому виду файл /om/login-center/data/nginx/templates/ws443.conf.template

/om/login-center/data/nginx/templates/ws443.conf.template
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name ${NGINX_WORKSPACE_HOST};
    server_tokens off;

    ssl_certificate /etc/nginx/ssl/workspace1/bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/workspace1/crt.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ecdh_curve X25519:prime256v1:secp384r1;
    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;
    # Слабые наборы шифров устарели в TLS v1.2 и v1.3, что устраняет необходимость указания сервером предпочтительных шифров.
    ssl_prefer_server_ciphers off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # Resolver
    resolver 127.0.0.11 valid=300s;
    resolver_timeout 15s;

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options SAMEORIGIN always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # Блокировка нестандартных методов
    if ($request_method !~ ^(GET|POST|PUT|DELETE|PATCH|OPTIONS)$ ) {
        return 405;
    }

    client_max_body_size 2G;
    # Buffer settings
    proxy_buffer_size 32k;
    proxy_buffers 8 32k;
    proxy_busy_buffers_size 64k;


    location / {
        proxy_pass ${NGINX_WORKSPACE_PROXY_URL};
        proxy_http_version 1.1;

        # WebSocket upgrade headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Standard proxy headers
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;

        # Timeouts (особенно важны для WebSocket)
        proxy_connect_timeout 30;
        proxy_send_timeout 600;
        proxy_read_timeout 10800;  # Длинные таймауты для WS соединений
        send_timeout 600;

        proxy_pass_request_headers on;
    }
}

Шаблон /om/login-center/data/nginx/templates/ws80.conf.template берем из инструкции по совместной установке. Он нужен только для перенаправления http запросов на https.

Обратите внимание на ssl_dhparam /etc/nginx/ssl/dhparam.pem; Здесь мы используем файл сгенерированный для самого логин центра. Он должен присутствовать.

Применение изменений

Если вы меняли только шаблоны nginx для применения изменений требуется выполнить перезапуск логин центра. Для этого выполняем остановку и последующий запуск. Из каталога логин центра выполняем:

./manage stop && ./manage start

Если вы настраивали совместную установку и изменяли параметры в manifest.yml то для применения параметров следует использовать команду

./configure.sh