Reverse proxy
Для возможности гибкого управления маршрутизацией http-запросов, а также для возможности распределения запросов по разным нодам приложения при использовании кластерной конфигурации, необходимо использовать обратный прокси сервер (Reverse proxy). В качестве обратного прокси и балансировщика http-запросов рекомендуем использовать Nginx.
Установка Reverse proxy
Установите Nginx на Ubuntu, выполнив команду:
sudo apt install nginx
Установите Nginx на Oracle Linux, выполнив команду:
sudo dnf install nginx
Для установки актуальной версии Nginx рекомендуем обратиться к инструкции на сайте Nginx (ссылка на документацию).
Настройка Reverse proxy
Во всех случаях мы настоятельно рекомендуем настраивать доступ по протоколу https с использованием SSL-сертификата.
Настройки проксирования запросов рекомендуем выполнять в отдельном файле с расширением conf, размещенном в каталоге /etc/nginx/conf.d.
Для работы по HTTPS-протоколу необходимо настроить обратный прокси сервер.
Получить сертификат для доменного имени информационной системы можно одним из следующих способов:
- Приобрести в любом доверенном центре сертификации, пройдя процедуру валидации.
- Получить бесплатно в некоторых центрах сертификации.
- Сгенерировать самостоятельно (самоподписанный сертификат).
- Получить у администратора удостоверяющего центра, если в организации развернута инфраструктура открытых ключей (PKI) и имеется свой удостоверяющий центр.
Рекомендуется во всех случаях использовать корректно подписанные сертификаты. Если используется сертификат, не подписанный доверенным центром сертификации (самоподписанный) или подписанный удостоверяющим центром организации, сертификат которого не загружен в хранилище доверенных сертификатов ОС, то браузеры пользователей будут предупреждать о ненадежном подключении к узлу.
Требования к сертификату для работы по https:
- Сертификат должен иметь формат pem (plain-text);
- Приватный ключ сертификата должен быть не зашифрован (т.е. не должен требовать пароль при использовании);
- Сертификат должен быть валидным (не просроченным и не поврежденным).
Рекомендуется:
- Использовать сертификаты, подписанные доверенными центрами сертификации;
- Использовать сертификаты с алгоритмом хэширования SHA-2, т.к. более ранние алгоритмы не обеспечивают должной безопасности соединения.
Для настройки HTTPs в Nginx выполните следующие действия:
-
Поместите файлы сертификата и закрытого ключа в любое место на сервере, к которому будет доступ у Nginx. Например в /etc/nginx/ssl/.
-
В параметрах ssl_certificate и ssl_certificate_key конфигурационного файла Nginx укажите полный путь к файлам сертификата и закрытого ключа.
-
Проверьте корректность конфигурации Nginx:
sudo nginx -t
-
Перечитайте конфигурацию Nginx:
sudo nginx -s reload
-
Скачайте с сайта NAUMEN (ссылка для скачивания) подготовленный шаблон конфигурационного файла nginx, соответствующий вашим потребностям и поместите его в каталог /etc/nginx/conf.d/.
-
В данном файле в двух блоках server установите значение параметра server_name равным DNS-имени, по которому пользователи будут подключаться к приложению (это DNS-имя должно входить в параметр baseurl в файле dbaccess.properties).
-
В блоках upstream вместо SD_SERVER_IP:TOMCAT_PORT укажите IP-адрес сервера, на котором установлен SMP (или серверов, если используется кластерная конфигурация ИС) и порт Tomcat.
-
В параметрах ssl_certificate и ssl_certificate_key укажите полный путь к файлам сертификата и закрытого ключа, см. Настройка работы по HTTPS.
-
Проверьте корректность конфигурации Nginx:
sudo nginx -t
-
Перечитайте конфигурацию Nginx:
sudo nginx -s reload
Описание шаблонов конфигурационных файлов
Ниже приводятся примеры шаблонов конфигурационных файлов под различные нужды. На основе этих примеров можно формировать настройки под конкретные цели.
-
sd1.conf — простое проксирование запросов пользователей в приложение:
-
Подключение к приложению по ссылке, указанной в параметре baseurl конфигурационного файла dbaccess.properties;
-
При подключении по http пользователей автоматически перенаправляет на https;
-
Таймаут при чтении ответа проксированного сервера — 300s;
-
Ограничение размера загружаемого файла — 50 МБ;
-
При подключении по ссылке без указания пути (https://SYSTEM_DNS_NAME) происходит автоматическое дописывание /sd/ и пользователь попадает на страницу аутентификации.
Copyupstream sd {
server SD_SERVER_IP:TOMCAT_PORT;
}
server {
listen 80; # слушать порт 80
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
location / {
return 302 https://$host$request_uri; # автоматическое перенаправление на https
}
}
server {
listen 443 ssl; # слушать порт 443, включить шифрование
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
ssl_certificate SSL_CERT; # путь к файлу сертификата или bundle на сервере
ssl_certificate_key SSL_KEY; # путь к файлу закрытого ключа. Ключ не должен требовать пароля.
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 512k;
large_client_header_buffers 4 256k;
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-Server $host;
proxy_set_header Host $http_host;
keepalive_timeout 20s;
proxy_read_timeout 300s; # Таймаут при чтении ответа проксированного сервера
proxy_send_timeout 300s;
client_max_body_size 50m; # Ограничение размера загружаемого файла
location ~ ^/$ {
return 302 $scheme://$host/sd/; # автоматически дописывать /sd/
}
location /sd {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_pass http://sd;
}
} -
-
sd2.conf — настройки для работы Портала самообслуживания:
Отличия от sd1.conf:
-
Проксирование запросов на Портал;
-
При подключении по ссылке без указания пути (https://SYSTEM_DNS_NAME) происходит автоматическое дописывание /portal/login.html и пользователь попадает на страницу аутентификации Портала самообслуживания.
Copyupstream sd {
server SD_SERVER_IP:TOMCAT_PORT;
}
map_hash_max_size 32768;
map_hash_bucket_size 32768;
map $arg_func $nocache {
modules.portalRest.getFeedbackData 0;
modules.portalRest.getServiceCallFilters 0;
modules.portalRest.getSimilarArticles 0;
modules.portalRest.listAllUserArticles 0;
modules.portalRest.listAllUserNews 0;
modules.portalRest.listAllUserObjects 0;
modules.portalRest.listNewsByService 0;
~modules.portalRest.* 1;
~modules.dynamicFields.* 1;
default 1;
}
proxy_cache_path /usr/share/nginx/cache levels=1:2 keys_zone=cache:100m inactive=720m max_size=1G;
proxy_ignore_headers Cache-Control Expires; # без этого почему-то файлы не кэшируются, все время MISS
server {
listen 80; # слушать порт 80
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
location / {
return 302 https://$host$request_uri; # автоматическое перенаправление на https
}
}
server {
listen 443 ssl; # слушать порт 443, включить шифрование
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
ssl_certificate SSL_CERT; # путь к файлу сертификата или bundle на сервере
ssl_certificate_key SSL_KEY; # путь к файлу закрытого ключа. Ключ не должен требовать пароля.
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 512k;
large_client_header_buffers 4 256k;
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-Server $host;
proxy_set_header Host $http_host;
keepalive_timeout 20s;
proxy_read_timeout 300s; # Таймаут при чтении ответа проксированного сервера
proxy_send_timeout 300s;
client_max_body_size 50m; # Ограничение размера загружаемого файла
location ~ ^/$ {
return 302 https://$host/portal/login.html; # автоматически переводить на Portal
}
location /portal {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_pass http://sd/sd/application-portal;
add_header Cache-Control no-cache;
}
location /sd/services/portalrest/ {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_pass http://sd;
proxy_no_cache $nocache;
proxy_cache_methods GET POST;
proxy_cache_key "$http_Authorization$arg_func$arg_params$request_body";
proxy_cache cache;
proxy_cache_valid 200 60m; # без этого не работало, все время был miss
}
location /sd {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_pass http://sd;
}
} -
-
sd3.conf — настройки для работы WebSocket-соединений, с помощью которых реализован механизм отслеживания изменений объектов системы.
Отличия от sd1.conf:
- Настроено преобразование соединения из HTTP/1.1 в WebSocket и проксирование запросов по пути /sd/ws для работы вебсокетов.
- Данную настройку нужно выполнять с учетом настройки приложения SMP, касающейся отслеживания изменений объектов системы (см. Отслеживание изменений объектов системы).
Copyupstream sd {
server SD_SERVER_IP:TOMCAT_PORT;
}
# Раскомментировать в случае использования в внешнего Artemis в качестве STOMP-брокера
# upstream websocket {
# server ARTEMIS_SERVER_IP:ARTEMIS_PORT;
# }
server {
listen 80; # слушать порт 80
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
location / {
return 302 https://$host$request_uri; # автоматическое перенаправление на https
}
}
server {
listen 443 ssl; # слушать порт 443, включить шифрование
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
ssl_certificate SSL_CERT; # путь к файлу сертификата или bundle на сервере
ssl_certificate_key SSL_KEY; # путь к файлу закрытого ключа. Ключ не должен требовать пароля.
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 512k;
large_client_header_buffers 4 256k;
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-Server $host;
proxy_set_header Host $http_host;
keepalive_timeout 20s;
proxy_read_timeout 300s; # Таймаут при чтении ответа проксированного сервера
proxy_send_timeout 300s;
client_max_body_size 50m; # Ограничение размера загружаемого файла
location ~ ^/$ {
return 302 $scheme://$host/sd/; # автоматически дописывать /sd/
}
location /sd {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_pass http://sd;
}
location /sd/ws {
# proxy_pass http://websocket; # Раскомментировать в случае использования в внешнего Artemis в качестве STOMP-брокера
proxy_pass http://sd; # Закомментировать в случае использования внешнего Artemis в качестве STOMP-брокера
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
}В случае использования в качестве STOMP-брокера внешнего Apache Artemis, в конфигурационном файле Nginx нужно настроить соответствующий upstream и настроить проксирование запросов в него.
Copy# Раскомментировать в случае использования в внешнего Artemis в качестве STOMP-брокера
# upstream websocket {
# server ARTEMIS_SERVER_IP:ARTEMIS_PORT;
# }
...
location /sd/ws {
# proxy_pass http://websocket; # Раскомментировать в случае использования в внешнего Artemis в качестве STOMP-брокера
proxy_pass http://sd; # Закомментировать в случае использования внешнего Artemis в качестве STOMP-брокера
...Вместо ARTEMIS_SERVER_IP:ARTEMIS_PORT укажите IP-адрес сервера с развернутым брокером очередей и порт Artemis.
-
sd4.conf — доступ к основному интерфейсу приложения только из внутренней сети, обеспечение доступа пользователей мобильного приложения из Интернета.
Отличия от sd1.conf:
Настраиваются правила обработки HTTP-запросов на основе IP-адреса клиента и его User-Agent.
Copy# user_agent (Мобильный Клиент - приложение) MC , (браузер мобильного телефона) MOBILE, OTHER - остальное
map $http_user_agent $user_agent {
~*ru\.naumen.+(Android|iOS).* MC; # Мобильное приложение (Мобильный клиент, МК)
~*(Mobile|mobile).* MOBILE; # Браузер мобильного телефона (Мобльный браузер)
default OTHER; # Любой другой клиент
}
# netw (Модуль geo, определяем диапазоны локальной сети, которым разрешаем работать в web версии приложения) INTERNAL, EXTERNAL
geo $netw {
91.232.196.0/24 INTERNAL; # Описание сетевых диапазонов внутренней сети
10.0.0.0/8 INTERNAL; #
192.168.0.0/16 INTERNAL; #
100.64.2.0/24 INTERNAL; #
default EXTERNAL; # Внешние сети (в т.ч. Интернет)
}
# Разрешения для uri для МК и мобильного браузера
map "$uri" $rights {
~^/$ ROOT; # Корень
~^/sd/?$ SD; # /sd
~/sd/services/rest-mobile ALLOWMC; # Разрешенный адрес для МК
~/sd/jwt-mobile ALLOWMC; # Разрешенный адрес для МК
~/sd/services/eamobile ALLOWMC; # Разрешенный адрес для МК
~^/sd/application-.* ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/operator/cache/apps ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/services/earest ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/services/rest-mobile/authentication/callback ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/callback ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/externalError ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/logout ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/operator/cache/direct ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/operator/apps ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
/sd/direct/direct.jsp ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
/sd/mobile/direct.jsp ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/fonts ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/images/logo ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~^/sd/.+.(png|svg|ico)$ ALLOWMOBILE; # Разрешенный адрес для мобильного браузера
~/sd/operator REWRITEDIRECT; # Адрес, при обращении к которому мобильный браузер перенаправляется на direct.jsp
/sd/index.jsp REWRITEDIRECT; # Адрес, при обращении к которому мобильный браузер перенаправляется на direct.jsp
default 0;
}
# Действие
map "$netw:$user_agent:$rights" $action {
~INTERNAL:OTHER:* ALLOW; # Из внутренней сети разрешаем все для не мобильных пользователей
~EXTERNAL:OTHER:* DENY; # Из внешней сети запрещаем все для не мобильных пользователей
~*:MOBILE:ROOT TOSD; # Из любой сети мобильный браузер с / перенаправляем на /sd/
~*:MOBILE:SD TODIRECT; # Из любой сети мобильный браузер при обращении на /sd/ перенаправляем на direct.jsp
~*:MOBILE:REWRITEDIRECT TODIRECT; # Из любой сети мобильный браузер по заданным адресам перенаправляем на direct.jsp
EXTERNAL:MOBILE:ALLOWMOBILE ALLOW; # Из внешней сети мобильный браузер пускаем по заданным адресам
~INTERNAL:MOBILE:* ALLOW; # Из внутренней сети мобильный браузер пускаем по любым адресам
~*:MC:ROOT TOSD; # Из любой сети МК с / перенаправляем на /sd/
~*:MC:SD RETURN204; # Из любой сети МК при обращении на /sd/ возвращаем 204
~*:MC:ALLOWMC ALLOW; # Из любой сети МК пускаем по заданным адресам
default DENY; #
}
upstream sd {
server SD_SERVER_IP:TOMCAT_PORT;
}
server {
listen 80; # слушать порт 80
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
location / {
return 302 https://$host$request_uri; # автоматическое перенаправление на https
}
}
server {
listen 443 ssl; # слушать порт 443, включить шифрование
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
ssl_certificate SSL_CERT; # путь к файлу сертификата или bundle на сервере
ssl_certificate_key SSL_KEY; # путь к файлу закрытого ключа. Ключ не должен требовать пароля.
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 512k;
large_client_header_buffers 4 256k;
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-Server $host;
proxy_set_header Host $http_host;
keepalive_timeout 20s;
proxy_read_timeout 300s; # Таймаут при чтении ответа проксированного сервера
proxy_send_timeout 300s;
client_max_body_size 50m; # Ограничение размера загружаемого файла
if ($action = DENY) {
return 403;
}
if ($action = TOSD) {
return 302 https://$host/sd;
}
if ($action = RETURN204) {
return 204;
}
if ($action = TODIRECT) {
return 302 https://$host/sd/direct/direct.jsp;
}
location ~ ^/$ {
return 302 $scheme://$host/sd/; # автоматически дописывать /sd/
}
location /sd {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_pass http://sd;
}
} -
sd5.conf — балансировка запросов для кластерной конфигурации системы.
Отличия от sd1.conf:
В блоке upstream указываются все серверы, между которыми необходимо осуществлять балансировку запросов.
Подробнее о настройках этого блока описано в документации Nginx (ссылка на документацию).
Ниже приводятся примеры настройки upstream для различных потребностей:
-
Один сервер основной, второй резервный.
При обычной работе все запросы пользователей направляются на первый сервер, а в случае возникновения 3-х (задается max_fails=3) ошибок в течение 30 с. (задается fail_timeout=30s) — на второй.
Copyupstream sd {
server SD_SERVER1_IP:TOMCAT_PORT max_fails=3 fail_timeout=30s;
server SD_SERVER2_IP:TOMCAT_PORT max_fails=3 fail_timeout=15s backup;
} -
Балансировка пользователей на две ноды в зависимости от IP-адреса клиента.
В качестве ключа для хэширования используются первые три октета IPv4-адреса клиента или IPv6-адрес клиента целиком.
Copyupstream sd {
ip_hash;
server SD_SERVER1_IP:TOMCAT_PORT;
server SD_SERVER2_IP:TOMCAT_PORT;
}
Пример полного конфигурационного файла для организации горячего резервирования приложения sd5.conf.
Copyupstream sd {
server SD_SERVER1_IP:TOMCAT_PORT max_fails=3 fail_timeout=30s;
server SD_SERVER2_IP:TOMCAT_PORT max_fails=3 fail_timeout=15s backup;
}
server {
listen 80; # слушать порт 80
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
location / {
return 302 https://$host$request_uri; # автоматическое перенаправление на https
}
}
server {
listen 443 ssl; # слушать порт 443, включить шифрование
server_name SYSTEM_DNS_NAME; # указать имя хоста, по которому возможно подключение
server_tokens off; # отключаем вывод версии nginx при ошибках
ssl_certificate SSL_CERT; # путь к файлу сертификата или bundle на сервере
ssl_certificate_key SSL_KEY; # путь к файлу закрытого ключа. Ключ не должен требовать пароля.
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 512k;
large_client_header_buffers 4 256k;
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-Server $host;
proxy_set_header Host $http_host;
keepalive_timeout 20s;
proxy_read_timeout 300s; # Таймаут при чтении ответа проксированного сервера
proxy_send_timeout 300s;
client_max_body_size 50m; # Ограничение размера загружаемого файла
location ~ ^/$ {
return 302 $scheme://$host/sd/; # автоматически дописывать /sd/
}
location /sd {
###limit_conn addr 1; # раскомментировать при необходимости ограничить количество подключений
###return 503; # раскомментировать при необходимости закрыть доступ (заглушка)
proxy_next_upstream error timeout http_503; # Определяет, в каких случаях запрос будет передан следующему серверу
proxy_pass http://sd;
}
} -
Отключение индексирования сайта поисковыми системами
Если приложение доступно из Интернета, и при этом требуется, чтобы поисковые системы не хранили у себя информацию о приложении, рекомендуем настроить запрет на индексирование сайта с помощью файла robots.txt.
Добавьте в блок server, описывающий подключение по 443 порту следующий блок location:
location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
Подробнее о robots.txt вы можете прочитать, например, на сайте robotstxt.ru.
Установка заглушки
При проведении регламентных работ, например, при обновлении системы, может потребоваться закрыть доступ пользователей в систему, а также закрыть доступ для интеграционного взаимодействия REST/SOAP.
-
Для этого в конфигурационном файле nginx в location:
- /portal
- /sd
- /sd/services/rest/
- /sd/services/portalrest/
раскомментируйте строку ###return 503.
-
Проверьте корректность конфигурации Nginx:
sudo nginx -t
-
Перечитайте конфигурацию Nginx
sudo nginx -s reload
Снятие заглушки
По окончании работ, для возобновления полноценного доступа к приложению снимите ограничения на доступ.
-
Для этого в конфигурационном файле nginx в location
- /portal
- /sd
- /sd/services/rest/
- /sd/services/portalrest/
закомментируйте строку return 503;
-
Проверьте корректность конфигурации Nginx:
sudo nginx -t
-
Перечитайте конфигурацию Nginx
sudo nginx -s reload