0

1c linux

NGINX как обратный прокси для веб-публикации 1С:Предприятие

04.07.2023

Почему именно NGINX и именно обратный прокси? Давайте разберем простой пример: в нашей сети есть два условных сервера 1С, каждый из которых имеет веб-публикации, допустим на IIS и Apache. Оба сервера используют одни и те же порты и просто так одновременный доступ к ним организовать не получится, как минимум один из них придется размещать на нестандартном порту, что не добавляет удобства в эксплуатации.

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

В общем чем дальше – тем больше проблем. Все их можно решить при использовании обратного прокси-сервера. Если обычный прокси-сервер обеспечивает доступ множества внутренних клиентов к внешнему миру, то обратный прокси-сервер решает противоположную задачу, помогая внешним клиентам получить доступ ко множеству внутренних ресурсов через один внешний адрес.

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

В нашей условной сети есть два веб-сервера на которых опубликованы информационные базы 1С:Предприятия:

  • IIS-SRV-1C.LOC – IIS, информационные базы Зарплата и Управление персоналом
  • APH-SRV-1C.LOC – Apache, информационные базы Бухгалтерия предприятия

Также есть внешний адрес, с которым сопоставлено доменное имя 1с.it-31.lab, наличие доменного имени является обязательным условием для использования сертификатов Let’s Encrypt. Использовать самоподписанные сертификаты для доступа внешних пользователей мы категорически не советуем, так как это поощряет использование нежелательных практик игнорирования ошибок сертификатов, что негативно сказывается на безопасности.

Кроме того, именно NGINX будет дополнительно заниматься парольной аутентификацией, что позволит иметь единую базу пользователей и паролей.

Данная инструкция предназначена для актуальных версий Debian или Ubuntu, все указанные команды следует выполнять с правами суперпользователя root.

Установка и первичная настройка NGINX

Существует два варианта получения NGINX: из репозиториев дистрибутива или из репозитория разработчиков. В первом случае вы можете получить довольно старую версию продукта, что нежелательно для сервиса, смотрящего во внешний мир. И дело тут не только в уязвимостях, как раз об этом можно не беспокоиться, обновления безопасности будут выходить до конца срока поддержки дистрибутива. Гораздо важнее может оказаться отсутствие поддержки ряда современных технологий, например, новых шифров или алгоритмов.

Поэтому мы рекомендуем подключить репозитории разработчика и установить пакет оттуда. В настоящий момент поддерживаются версии Debian 11 и 12, а также Ubuntu 20.04 и 22.04.

Прежде всего установим необходимые зависимости:

apt install curl gnupg2

Затем получим и установим в хранилище ключ репозитория:

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor > /usr/share/keyrings/nginx-archive-keyring.gpg

И подключим дополнительный репозиторий.

Для Debian:

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian `lsb_release -cs` nginx"  > /etc/apt/sources.list.d/nginx.list

Для Ubuntu:

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" > /etc/apt/sources.list.d/nginx.list

Затем обновим список пакетов и установим NGINX:

apt update
apt install nginx

Запустим службу и проверим ее состояние:

systemctl start nginx
systemctl status nginx

Теперь можете набрать в браузере адрес сервера и вам будет показана стандартная заглушка NGINX.

Создадим некоторые дополнительные директории, в которых мы будем размещать наши конфигурационные файлы:

mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled

Теперь откроем файл /etc/nginx/nginx.conf и после строки:

include /etc/nginx/conf.d/*.conf;

Добавим:

include /etc/nginx/sites-enabled/*;

Проверим правильность конфигурации и перезапустим веб-сервер:

nginx -t 
nginx -s reload

На этом первичная установка и настройка NGINX закончена.

Получение сертификата Let’s Encrypt и настройка SSL-шифрования

Вопрос защиты в наше время стоит достаточно остро и варианты без шифрования сегодня даже не рассматриваются, поэтому займемся этим вопросом в первую очередь. Сначала установим Certbot для работы с сертификатами Let’s Encrypt:

apt install certbot

Теперь создадим файл конфигурации нашего виртуального хоста и приступим к его редактированию, мы будем использовать для этого редактор nano, если вы предпочитаете редактор MC, то замените в команде nano на mcedit:

nano /etc/nginx/sites-available/00-1c.it-31.lab.conf

Имя файла может быть произвольным, но мы советуем называть их по имени обслуживаемого домена.

Затем внесем в него следующий текст:

server {

listen 80;
server_name 1c.it-31.lab;

location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}

location = /.well-known/acme-challenge/ {
return 404;
}

return 301 https://$host$request_uri;
}

В данной конфигурации мы указываем, что на порту 80 следует принимать запросы для узла 1c.it-31.lab, ниже идут параметры для работы с Let’s Encrypt, а все остальные запросы будут перенаправляться на защищенную версию ресурса.

Сохраняем конфигурацию и создаем символическую ссылку на нее в директорию /etc/nginx/sites-enabled:

ln -s  /etc/nginx/sites-available/00-1c.it-31.lab.conf /etc/nginx/sites-enabled

Проверяем конфигурацию и перезапускаем веб-сервер:

nginx -t 
nginx -s reload

Создадим указанную в конфигурации директорию и сделаем ее владельцем веб-сервер:

mkdir /var/www/letsencrypt
chown -R nginx:nginx /var/www/letsencrypt

Теперь запустим Certbot и получим сертификат для нашего домена:

certbot certonly --webroot -w /var/www/letsencrypt -d 1c.it-31.lab

После успешного получения сертификата откроем файл с настройками домена /etc/letsencrypt/renewal/1c.it-31.lab.conf и внесем в секцию [renewalparams] следующую опцию:

[renewalparams]
...
renew_hook = nginx -s reload

Это обеспечит перезапуск NGINX после успешного обновления сертификата.

Для режима совершенной прямой секретности создадим файл параметров Диффи-Хелмана:

openssl dhparam -out /etc/ssl/private/dhparam.pem 2048

Теперь откроем /etc/nginx/sites-available/00-1c.it-31.lab.conf и добавим в него секцию:

server {

listen 443 ssl http2;
server_name 1c.it-31.lab;

ssl_certificate /etc/letsencrypt/live/1c.it-31.lab/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/1c.it-31.lab/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_dhparam /etc/ssl/private/dhparam.pem;

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;
ssl_prefer_server_ciphers off;

add_header Strict-Transport-Security "max-age=63072000" always;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/1c.it-31.lab/chain.pem;
resolver 8.8.8.8;
}

Еще раз проверим конфигурацию и перезапустим сервер:

nginx -t 
nginx -s reload

Если теперь снова набрать в браузере адрес сервера, то мы снова попадем на страницу-заглушку, но уже через HTTPS-протокол.

Настройка переадресации запросов для веб-публикации 1С:Предприятие

Перед тем, как приступать к настройке необходимо выяснить по каким адресам работают уже существующие публикации, в нашем случае это:

http://IIS-SRV-1C.LOC/HRM-1
http://APH-SRV-1C.LOC/ACC-30

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

1c-nginx-reverse-proxy-002.pngДля работы обратного прокси мы должны для каждой базы создать отдельный URL с ее именем. Снова откроем /etc/nginx/sites-available/00-1c.it-31.lab.conf и добавим внутрь секции server вложенную секцию:

location /HRM-1/ {
proxy_pass http://IIS-SRV-1C.LOC/HRM-1/;
proxy_redirect off;
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 https;
}

Первая строка определяет адрес куда мы перенаправляем все запросы пришедшие на URL 1c.it-31.ru/HRM-1, обратите внимание на закрывающие слеши, они обязательны. Остальные опции определяют необходимый режим работы и передачу проксируемому серверу служебных заголовков.

Для второй базы добавим еще одну секцию:

location /ACC-30/ {
proxy_pass http://APH-SRV-1C.LOC/ACC-30/;
proxy_redirect off;
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 https;
}

Повторяем данные действия для всех остальных публикаций, теперь они будут доступны извне по адресам:

https:// 1c.it-31.ru/HRM-1
https:// 1c.it-31.ru/ACC-30

Чтобы применить изменения сохраните файл конфигурации, проверьте и перезапустите NGINX:

nginx -t 
nginx -s reload

Основная задача выполнена, мы опубликовали для внешних пользователей информационные базы 1С:Предприятие с разных серверов и защитили их надежным шифрованием.

Настройка дополнительной аутентификации по паролю

У нас нет основания сомневаться во встроенном механизме аутентификации 1С:Предприятия, во всяком случае в онлайн-сервисах дополнительной аутентификации не предусмотрено, но есть слабое место – пользователи. Во многих базах могут использоваться простые пароли или не использоваться вообще, часть таких паролей могут использоваться скриптами и средствами автоматизации, поэтому взять и установить сразу всем сложные пароли будет не так-то просто.

Ситуация усугубляется, если администрирование 1С выполняют другие сотрудники, они вполне могут, пойдя на поводу пользователей снова установить им слабые пароли, что сильно снижает безопасность собственного механизма аутентификации. Поэтому мы пойдем другим путем и установим дополнительную аутентификацию на уровне веб-сервера, тут уже точно без нас никто пароль не изменит. Основная его цель – оградить собственный механизм аутентификации 1С от доступа всех желающих, которым достаточно будет просто узнать ссылку.

Для этого установим дополнительный набор утилит:

apt install apache2-utils

Теперь создадим базу пользователей, первого пользователя заводим с использованием ключа -с, в этом случае будет создан новый файл паролей, а существующий перезаписан:

htpasswd -c /etc/nginx/.htpasswd glavbuch

Для следующих пользователей используйте команду:

htpasswd /etc/nginx/.htpasswd buch1

После чего в каждую секцию с информационной базой в /etc/nginx/sites-available/00-1c.it-31.lab.conf добавим строки:

location /HRM-1/ {
auth_basic "1C users only";
auth_basic_user_file /etc/nginx/.htpasswd;

Еще раз проверим конфигурацию и перезапустим сервер:

nginx -t 
nginx -s reload

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

Свежие комментарии

Подписка

Лучшие статьи


Fatal error: Uncaught Error: Call to a member function have_posts() on null in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php:380 Stack trace: #0 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/widget.php(257): fox56_blog_grid(NULL, Array) #1 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/register.php(33): include('/home/host18670...') #2 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/class-wp-widget.php(394): Wi_Widget_Latest_Posts->widget(Array, Array) #3 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/widgets.php(837): WP_Widget->display_callback(Array, Array) #4 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(417): dynamic_sidebar('sidebar') #5 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(136): fox56_single_sidebar() #6 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(7): fox56_single_inner() #7 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/single.php(23): fox56_single() #8 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/template-loader.php(106): include('/home/host18670...') #9 /home/host1867038/the-devops.ru/htdocs/www/wp-blog-header.php(19): require_once('/home/host18670...') #10 /home/host1867038/the-devops.ru/htdocs/www/index.php(17): require('/home/host18670...') #11 {main} thrown in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php on line 380