Публикация 1С на веб-сервере: установка Apache, публикация базы, HTTPS и IIS

Публикация 1С на веб-сервере: Apache, IIS, SSL и Docker
Видео: Публикация 1С на веб-сервере: Apache, IIS, SSL и Docker

Публикация 1С на веб-сервере — это то, с чего начинается любая интеграция: веб-клиент в браузере, тонкий клиент через интернет, HTTP- и OData-сервисы, обмен с интернет-магазином, мобильное приложение. Пока база доступна только из локальной сети через толстый клиент, все эти сценарии закрыты. В этой статье я по шагам показываю, как поднять веб-сервер 1С на Apache и на IIS под Windows, как опубликовать базу вручную через httpd.conf (а не только галочками в Конфигураторе), и разбираю нюансы, которых нет в других инструкциях: как зашить логин прямо в конфиг Apache, как обойти CORS для HTTP-сервисов и как вынести Apache в Docker, оставив саму 1С на хосте.

Статья собрана из боевого конфига Apache, на котором у меня одновременно опубликованы десяток баз. Поэтому здесь не абстрактные примеры «It works», а те строки, которые реально работают в проде.

Что такое публикация 1С на веб-сервере и зачем она нужна

Публикация — это когда информационная база 1С становится доступна по HTTP. Платформа 1С не умеет сама слушать порт 80: ей нужен веб-сервер (Apache или IIS), а связь между веб-сервером и платформой обеспечивает специальный модуль расширения веб-сервера — библиотека, которую ставят вместе с платформой.

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

  • Веб-клиент — полноценная 1С прямо в браузере, без установки.
  • Тонкий клиент через интернет — то же приложение 1С, но подключается к базе по HTTP/HTTPS, а не по файловому доступу.
  • HTTP-сервисы и OData — программные точки входа для интеграций: интернет-магазин, мобильное приложение, внешний сервис на Python или Node.js.

Всё это работает через один механизм публикации. Разница только в галочках и в тонкой настройке конфига.

Как устроена публикация: модуль, default.vrd и обработчик

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

  1. Модуль веб-сервера 1С загружается в веб-сервер. Для Apache это wsap24.dll (Windows) или wsap24.so (Linux), для IIS — wsisapi.dll. Разрядность модуля обязана совпадать с разрядностью платформы 1С.
  2. В папке базы появляется файл default.vrd — дескриптор публикации: он говорит, какая база публикуется, под каким именем и какие сервисы включены.
  3. В конфиге веб-сервера появляется блок, который на нужном URL-пути включает обработчик 1c-application и указывает на этот default.vrd.

Когда браузер стучится по адресу публикации, Apache видит SetHandler 1c-application, передаёт запрос модулю 1С, модуль читает default.vrd, открывает базу и возвращает веб-клиент. Всё. Дальше — детали каждого шага и ошибки, которые на этих шагах вылезают.

Apache или IIS: что выбрать для 1С

Оба варианта рабочие, и оба 1С поддерживает официально. Коротко: IIS уже встроен в Windows Server и роднее экосистеме Microsoft; Apache кросс-платформенный (тот же конфиг работает и на Linux), правится обычным текстом и легче ложится в Docker. Если вам нужны тонкие вещи — свои заголовки, CORS, зашитая авторизация, несколько баз с разными настройками — на Apache это делается быстрее, потому что всё описывается парой строк в текстовом файле.

Ниже я подробно разбираю сначала Apache (основной сценарий), а потом IIS — со всеми ошибками, которые встретятся по пути.

Где скачать Apache 2.4 для 1С и какую разрядность брать

Первый ступор у тех, кто ставит Apache под 1С впервые: на apache.org нет установщика для Windows. И не появится — фонд Apache выкладывает только исходники, а готовые сборки под Windows делают сторонние сборщики. Рабочих вариантов два: Apache Lounge и Apache Haus. Я беру Lounge, ветку 2.4.x.

Сайт Apache Lounge, раздел загрузки: сборки Apache 2.4 VC15 для Windows 64 и 32 бит

Разрядность должна совпадать с платформой 1С, а не с операционной системой. Это главное правило и самая частая причина, по которой потом «ничего не работает»: Apache x64 не загрузит 32-битный wsap24.dll, а 32-битный Apache — 64-битный. Windows при этом в обоих случаях 64-разрядная, так что ориентироваться на разрядность ОС бессмысленно. Смотрим, какая платформа реально установлена:

:: 64-разрядная платформа ставится сюда
dir "C:\Program Files\1cv8\8.3.27.1508\bin\wsap24.dll"
:: 32-разрядная — сюда
dir "C:\Program Files (x86)\1cv8\8.3.27.1508\bin\wsap24.dll"

Модуль нашёлся в Program Files — качаем сборку win64, в Program Files (x86)win32. Если модуля нет ни там, ни там, дело не в Apache: не установлен компонент платформы «Модули расширения веб-сервера», об этом ниже отдельный раздел.

Второе, на чём спотыкаются, — Visual C++ Redistributable. Сборки Lounge подписаны версией компилятора (VC15, VS16, VS17), и соответствующий распространяемый пакет той же разрядности обязан стоять в системе. Иначе служба Apache не стартует вообще, без внятной причины — просто «не удалось запустить». Пакет ставится за минуту и снимает вопрос целиком.

Про версию ветки: берите текущую стабильную 2.4.x, особых требований у 1С нет — модуль wsap24 рассчитан на всю ветку. А вот Apache 2.2 уже не годится: под него был отдельный wsap22, которого в современных дистрибутивах платформы нет.

Каталог задайте сразу и осмысленно, а не распаковывайте архив в «Загрузки»: путь попадёт и в конфиг, и в параметры службы, менять его потом дороже, чем выбрать один раз. У меня это C:/Server/Bin/Apache24 — отдельная папка Server под весь веб-стек, внутри Bin для бинарников. Туда же потом лягут PHP и MySQL, если понадобятся.

Проводник: каталог C:\Server\Bin, куда переносится папка Apache24

Установка веб-сервера Apache 2.4 под 1С

Дистрибутив выбран — распаковываем архив в постоянную папку (у меня это D:/Server/Bin/Apache24) и правим главный конфиг conf/httpd.conf. Минимум, что нужно поменять:

# Корень, где лежит сам Apache. В Windows — только ПРЯМЫЕ слэши!
Define SRVROOT "D:/Server/Bin/Apache24"
ServerRoot "${SRVROOT}"

# Порт. По умолчанию 80, можно поставить любой — я держу 8080,
# чтобы не конфликтовать с другими сервисами.
Listen 8080

# Имя сервера — для локальной работы достаточно localhost.
ServerName localhost

# Папка, где будут лежать базы и сайты.
DocumentRoot "D:/www"
<Directory "D:/www">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

# Индексные файлы
<IfModule dir_module>
    DirectoryIndex index.php index.html index.htm
</IfModule>

Обратите внимание на слэши: в путях Apache под Windows пишут D:/www, а не D:\www — обратные слэши Apache не понимает. Это ошибка номер один у новичков.

После правки конфига ставим Apache службой. В сборках это делается командой из папки bin (от имени администратора):

httpd.exe -k install
httpd.exe -k start

Проверяем: открываем в браузере http://localhost:8080/. Если видите список каталога или свою индексную страницу — веб-сервер поднялся. Если служба не стартует, почти всегда причина одна из двух: занят порт (смените Listen) или не установлен нужный Visual C++ Redistributable.

Что именно менять в httpd.conf

Главный конфиг лежит в conf/httpd.conf. Правки точечные — ищем строку и меняем:

  • Define SRVROOT "c:/Apache24" → путь, куда вы распаковали Apache. Только прямые слэши — обратные Apache под Windows не понимает, это ошибка номер один.
  • #ServerName www.example.com:80ServerName localhost (для локальной работы этого достаточно).
  • DocumentRoot "${SRVROOT}/htdocs" → папка, где будут лежать сайты и публикации баз, например Z:/www. Тот же путь поменяйте и в блоке <Directory> ниже.
  • DirectoryIndex index.htmlDirectoryIndex index.php index.html index.htm, если рядом планируется PHP.
  • AllowOverride noneAllowOverride All — разрешает .htaccess, то есть переопределение настроек для отдельного подкаталога помимо общего конфига.
  • #LoadModule rewrite_module modules/mod_rewrite.so — снимите решётку. mod_rewrite преобразует URL по правилам-регуляркам, пригодится и для сайта рядом с базой.

Запуск службой Windows и проверка

Apache ставится службой одной командой из каталога bin (командная строка — от администратора):

httpd.exe -k install     # установить службу
httpd.exe -k start       # запустить
httpd.exe -k stop        # остановить
httpd.exe -k restart     # перезапустить после правки конфига
httpd.exe -k uninstall   # удалить службу

Возьмите за правило перед каждым перезапуском проверять синтаксис: httpd.exe -t на Windows, apachectl configtest на Linux. Команда покажет номер строки с ошибкой — это дешевле, чем уронить рабочую публикацию опечаткой и потом гадать, почему служба не поднимается.

Проверка: открываем http://localhost:8080/ — должна отдаться стартовая страница Apache или листинг каталога. В services.msc при этом висит служба Apache2.4 в статусе «Выполняется».

Страница Index of / по адресу localhost и служба Apache2.4 в оснастке «Службы» Windows

Если служба не стартует — почти всегда одно из двух: занят порт (смените Listen) или не установлен Microsoft Visual C++ Redistributable нужной разрядности.

Публикация базы: через Конфигуратор и вручную в httpd.conf

Самый простой способ — из Конфигуратора: Администрирование → Публикация на веб-сервере. Выбираете Apache, указываете папку и имя публикации (латиницей, строчными буквами), снимаете лишние галочки и жмёте «Опубликовать». 1С сама создаст default.vrd и допишет блок в httpd.conf.

Но я советую понимать, что именно она дописывает, — потому что руками это делается надёжнее, и только так можно добавить тонкие настройки. Вот минимальный боевой блок публикации базы:

# Модуль веб-сервера 1С — грузится один раз, путь под вашу версию платформы
LoadModule _1cws_module "C:/Program Files/1cv8/8.3.27.1989/bin/wsap24.dll"

# Публикация базы по адресу /ut11
Alias "/ut11" "D:/www/ut11/"
<Directory "D:/www/ut11/">
    AllowOverride All
    Options None
    Require all granted
    SetHandler 1c-application
    ManagedApplicationDescriptor "D:/www/ut11/default.vrd"
</Directory>

LoadModule _1cws_module — тот самый модуль расширения. Путь указывает на wsap24.dll внутри каталога bin вашей версии платформы; когда обновляете 1С — не забудьте поправить версию в пути, иначе публикация отвалится. SetHandler 1c-application включает обработчик 1С на этом пути, а ManagedApplicationDescriptor показывает, где лежит дескриптор базы.

Чтобы не собирать этот блок вручную каждый раз, я сделал конфигуратор: заполняете путь, папку базы и режим — получаете готовый блок для httpd.conf и заготовку default.vrd.

Публикация 1С на Apache через командную строку: утилита webinst

Конфигуратор — не единственный способ опубликовать базу. Вместе с платформой в каталоге bin ставится консольная утилита webinst, которая делает ровно то же самое: создаёт default.vrd и дописывает блок публикации в конфиг веб-сервера — но без единого клика мышью. Это то, что нужно для автоматизации: развернуть публикацию скриптом при выкатке, поднять её в CI или на Linux-сервере, где Конфигуратора с графикой попросту нет.

Базовый вызов для файловой базы на Apache 2.4 под Windows выглядит так:

"C:/Program Files/1cv8/8.3.27.1989/bin/webinst.exe" -publish -apache24 ^
  -wsdir ut11 ^
  -dir "D:/www/ut11" ^
  -connstr "File=""D:/bases/ut11"";" ^
  -confPath "D:/Server/Bin/Apache24/conf/httpd.conf"

Разбор ключей: -publish — публикуем (для снятия публикации есть -delete с теми же -wsdir и -confPath); -apache24 — тип веб-сервера (ещё бывают -apache22 и -iis); -wsdir — имя публикации, тот самый алиас из URL (/ut11); -dir — физическая папка публикации, куда ляжет default.vrd; -connstr — строка подключения к базе; -confPath — путь к httpd.conf, в который webinst допишет Alias и <Directory>. Для серверной (не файловой) базы меняется только строка подключения: -connstr "Srvr=""server1c"";Ref=""ut11"";".

На Linux та же команда, только пути другие, а webinst лежит в каталоге платформы:

/opt/1cv8/x86_64/8.3.27.1989/webinst -publish -apache24 \
  -wsdir ut11 \
  -dir /var/www/ut11 \
  -connstr 'Srvr="server1c";Ref="ut11";' \
  -confPath /etc/apache2/apache2.conf

После отработки утилиты остаётся перезапустить Apache — и база опубликована. Именно webinst выручает в связке с Docker, о которой я пишу ниже: там Конфигуратор упирается в «веб-серверы не обнаружены», а консольной публикации это безразлично — она просто пишет файлы, которые вы затем скармливаете контейнеру.

Частые ошибки при установке и публикации

Шесть ситуаций, на которые уходит больше всего времени у тех, кто публикует базу впервые.

  • Apache не стартует после правки httpd.conf. В подавляющем большинстве случаев — опечатка в пути или незакрытая директива. Гоняем httpd.exe -t (Windows) или apachectl configtest (Linux): команда покажет строку с ошибкой, вычитывать весь файл руками не нужно.
  • «Cannot load … wsap24.dll into server» при старте. Не совпадает разрядность: Apache x64 не загрузит 32-битный модуль и наоборот. Сверьте разрядность сборки Apache и установленной платформы 1С.
  • Модуль загрузился, но публикация отдаёт 404. Либо блок публикации попал в конфиг выше строки LoadModule _1cws_module, либо Alias не совпадает с тем, что вы запрашиваете в браузере. Проверьте секцию, которую дописал Конфигуратор или webinst.
  • «Ошибка при выполнении файловой операции» или «Недостаточно прав». Учётной записи, под которой работает служба Apache, не хватает прав на каталог файловой базы (или на порт менеджера кластера в клиент-серверном варианте). На Linux это обычно chown на каталог базы в пользу пользователя веб-сервера.
  • После обновления платформы публикация отвалилась. В LoadModule остался путь к bin старой версии — при обновлении 1С номер версии в пути меняется. Правится вручную, затем перезапуск Apache. Это же касается модуля wsisapi.dll на IIS.
  • Служба не появилась после httpd.exe -k install. Команда запущена не от администратора, либо служба Apache2.4 уже существует, но с другим путём: сначала httpd.exe -k uninstall, потом install из нужного каталога.

Отдельно про модуль: он версионируется под ветку веб-сервера — wsap22 для Apache 2.2, wsap24 для 2.4. Брать его нужно из того же дистрибутива платформы, что стоит на сервере 1С.

«Веб-серверы не обнаружены»: что проверить

Открываете Администрирование → Публикация на веб-сервере, а Конфигуратор отвечает, что веб-серверы не обнаружены, и список пуст. При этом Apache стоит и на localhost честно отдаёт страницу. Противоречия тут нет: Конфигуратор не проверяет, «работает ли сайт». Он ищет зарегистрированную в системе службу веб-сервера и свой модуль расширения в каталоге платформы. Нет любого из двух — список будет пустым. Проверять в таком порядке.

1. Не установлен компонент «Модули расширения веб-сервера». В установщике платформы он по умолчанию выключен — это самая частая причина, она же даёт соседнюю формулировку «не установлены модули расширения веб-сервера». Смотрим каталог bin именно той версии, из которой запущен Конфигуратор:

dir "C:\Program Files\1cv8\8.3.27.1508\bin\wsap24.dll"
dir "C:\Program Files\1cv8\8.3.27.1508\bin\wsisapi.dll"

Файлов нет — запускаем установщик платформы повторно в режиме изменения состава компонентов и отмечаем «Модули расширения веб-сервера». Затем перезапускаем Конфигуратор: список веб-серверов он строит на старте.

2. Apache работает, но не зарегистрирован службой. Запустили httpd.exe прямо из консоли — сайт открывается, а Конфигуратор веб-сервер не видит: опознаёт он его по установленной службе. Ставим службу командой от администратора и проверяем в services.msc, что Apache2.4 в статусе «Выполняется»:

httpd.exe -k install
httpd.exe -k start

3. Разошлась разрядность. 32-разрядный Конфигуратор ищет 32-разрядный веб-сервер, 64-разрядный — 64-разрядный, и чужую сборку каждый из них просто не замечает. Сверьте, из какого Program Files запущена платформа и какую сборку Apache вы поставили (разбор — в разделе про выбор дистрибутива выше). Тот же перекос позже даёт «Cannot load wsap24.dll into server» при старте службы.

4. IIS установлен, но без ISAPI. Роль веб-сервера есть, а в публикации пусто — почти всегда не отмечены ISAPI Extensions и ISAPI Filters в компонентах разработки приложений. Без них IIS для 1С непригоден, и Конфигуратор его не предлагает. Как доставить одной командой — в разделе про Windows Server 2019 ниже.

5. Конфигуратор запущен не от администратора. Публикация правит конфиг веб-сервера и создаёт каталог, поэтому на системе с включённым UAC Конфигуратор нужно запускать через «Запуск от имени администратора». Симптом бывает и мягче: список веб-серверов есть, но публикация падает на записи файла.

Прошли все пять пунктов, а список по-прежнему пуст — проверьте, какую версию платформы вы вообще запускаете. На машине с несколькими установленными версиями ярлык нередко ведёт на старую, где модули расширения не ставились ни разу.

Несколько баз на одном Apache

Одно из главных преимуществ Apache для 1С — на одном веб-сервере спокойно живёт хоть десяток баз. Каждая база — это просто ещё одна пара Alias + <Directory>:

Alias "/ut11" "D:/www/ut11/"
<Directory "D:/www/ut11/">
    Require all granted
    SetHandler 1c-application
    ManagedApplicationDescriptor "D:/www/ut11/default.vrd"
</Directory>

Alias "/rz23" "D:/www/rz23/"
<Directory "D:/www/rz23/">
    Require all granted
    SetHandler 1c-application
    ManagedApplicationDescriptor "D:/www/rz23/default.vrd"
</Directory>

Управленческая база на /ut11, розница на /rz23, тестовая на /test — и всё это на одном порту, одним LoadModule. У меня на боевом Apache так опубликованы и рабочие базы, и отдельные публикации под интеграции.

Нюанс 1: зашиваем логин прямо в конфиг Apache

Вот приём, которого нет в стандартных инструкциях, а он экономит кучу времени на интеграциях. Когда к базе 1С ходит внешний сервис (вебхук, MCP-сервер, скрипт на Python), ему нужно проходить аутентификацию. Обычно креды передаёт клиент. Но можно зашить их прямо в конфиг Apache, и тогда клиенту вообще не надо ничего знать про пароль:

Alias "/ut11_mcp" "D:/www/ut11/"
<Directory "D:/www/ut11/">
    Require all granted
    # Apache сам подставит заголовок Basic-авторизации в каждый запрос
    RequestHeader set Authorization "Basic bWNwOjE="
    SetHandler 1c-application
    ManagedApplicationDescriptor "D:/www/ut11/default.vrd"
</Directory>

bWNwOjE= — это base64 от строки mcp:1 (логин mcp, пароль 1). Директива RequestHeader set Authorization добавляет заголовок Basic-авторизации в каждый входящий запрос ещё до того, как он попадёт в 1С. В итоге получается отдельная «служебная» публикация той же базы: обычные пользователи ходят на /ut11 и вводят пароль, а интеграция ходит на /ut11_mcp и авторизуется автоматически. Ровно так я публикую базу под MCP-сервер для 1С — клиенту не надо хранить пароль, он просто дёргает URL.

Модуль mod_headers для этого должен быть включён (LoadModule headers_module modules/mod_headers.so).

Нюанс 2: обходим CORS для HTTP-сервисов 1С

Если вы публикуете HTTP-сервисы 1С и дёргаете их из браузера (с фронтенда на другом домене), вы упрётесь в CORS. Браузер сначала шлёт preflight-запрос OPTIONS, и вот тут засада: обработчик 1С на OPTIONS толком не отвечает, и preflight падает. Лечится это так:

Alias "/ordermonitor" "D:/www/ordermonitor/"
<Directory "D:/www/ordermonitor/">
    Require all granted

    Header set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Headers "*"
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"

    # Ключевой трюк: preflight OPTIONS отвечает сам Apache,
    # а всё остальное передаём обработчику 1С.
    <If "%{REQUEST_METHOD} != 'OPTIONS'">
        SetHandler 1c-application
        ManagedApplicationDescriptor "D:/www/ordermonitor/default.vrd"
    </If>
</Directory>

Идея в том, что CORS-заголовки Apache отдаёт всегда (через mod_headers), а обработчик 1С включается только для «настоящих» методов — GET, POST и так далее. На preflight OPTIONS Apache отвечает сам: пустой ответ 200 с нужными заголовками, и браузер спокойно шлёт основной запрос. Без этого <If> любой кросс-доменный вызов HTTP-сервиса из браузера будет отваливаться, и вы потратите вечер, гадая, почему «на бэкенде всё работает, а из фронта нет». Этот же приём выручает, когда 1С отдаёт данные во внешний сервис — например, в микросервис на FastAPI.

Access-Control-Allow-Origin "*" я тут ставлю для наглядности — в проде подставьте конкретный домен фронтенда, а не звёздочку.

Настройка HTTPS (SSL) для 1С в Apache

Как только вы начинаете гонять через веб-сервер что-то серьёзнее теста — обмен с магазином, оплату, персональные данные, — соединение нужно шифровать. Я в своё время наступил на это ровно с интернет-магазином: часть запросов не работала именно потому, что соединение было незащищённым, а после настройки SSL всё поднялось.

Для локальной разработки хватит самоподписанного сертификата. Генерируем ключ и сертификат утилитой OpenSSL (она лежит в bin Apache):

openssl genrsa -out localhost.key 2048
openssl req -new -key localhost.key -out localhost.csr
openssl x509 -req -days 365 -in localhost.csr -signkey localhost.key -out localhost.crt

При генерации в поле Common Name укажите ровно то имя, по которому будете открывать сайт (localhost или ваш домен) — иначе браузер будет ругаться на несоответствие. Дальше подключаем mod_ssl, слушаем 443-й порт и указываем сертификаты:

LoadModule ssl_module modules/mod_ssl.so
Listen 443

<VirtualHost _default_:443>
    DocumentRoot "D:/www"
    ServerName localhost:443
    SSLEngine on
    SSLCertificateFile    "D:/Server/Bin/Apache24/cert/localhost.crt"
    SSLCertificateKeyFile "D:/Server/Bin/Apache24/cert/localhost.key"
</VirtualHost>

Самоподписанному сертификату браузер по умолчанию не доверяет — чтобы убрать предупреждение, добавьте localhost.crt в «Доверенные корневые центры сертификации» локального компьютера. Для боевого сервера самоподписанный не годится: берите бесплатный сертификат Let's Encrypt или платный у регистратора (reg.ru и подобные часто дают год SSL в подарок к домену). Принцип подключения тот же — меняются только файлы сертификата и цепочки.

Нюанс, из-за которого openssl не запускается

Утилита openssl.exe лежит в каталоге bin Apache, но без переменной OPENSSL_CONF она падает с жалобой на конфигурацию. Поэтому команды выполняются так:

cd C:\Server\Bin\Apache24\bin
set OPENSSL_CONF=C:\Server\Bin\Apache24\conf\openssl.cnf

openssl.exe genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out localhost.key
openssl.exe req -new -key localhost.key -out localhost.csr
openssl.exe x509 -req -days 365 -in localhost.csr -signkey localhost.key -out localhost.crt

Командная строка Windows: генерация ключа и запроса на сертификат утилитой openssl.exe для localhost

Сертификат и ключ удобно сложить в отдельную папку certs в корне веб-сервера, а не держать в bin вперемешку с бинарниками.

Папка certs на диске C: с перенесёнными сертификатом и ключом localhost

Почему браузер ругается и как это убрать

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

Chrome: предупреждение «Подключение к сайту не защищено», самоподписанный сертификат недействителен

Лечится добавлением localhost.crt в «Доверенные корневые центры сертификации» локального компьютера (не текущего пользователя — иначе служба и тонкий клиент его не увидят).

Окно «Выбор хранилища сертификата»: пункт «Доверенные корневые центры сертификации»

Действующий сертификат: хостер или Let's Encrypt

Для боевого сервера самоподписанный не годится. Два рабочих пути.

Сертификат от хостера. При покупке домена многие регистраторы дают бесплатный SSL на год — заказывается в личном кабинете, подтверждение владения доменом идёт через TXT-запись в DNS. В ответ приходит письмо с телом сертификата и ключом: их кладут обычными текстовыми файлами рядом с localhost.crt и прописывают в конфиге.

Письмо от REG.RU с TXT-записью _globalsign-domain-verification для подтверждения домена

Пока сайт разрабатывается локально, домен нужно увести на свою машину через файл hosts — иначе запросы уйдут в интернет, а не на локальный Apache:

127.0.0.1    www.web1s.site

Let's Encrypt через certbot — если Apache стоит на Linux, это проще и дешевле. Certbot ставится пакетом, сам находит нужный <VirtualHost> и прописывает в него SSLCertificateFile и SSLCertificateKeyFile. Сертификат живёт 90 дней, но certbot ставит systemd-таймер, который проверяет срок пару раз в сутки и продлевает автоматически — в отличие от годового сертификата от хостера, который придётся продлевать руками.

Логика в обоих случаях одна: получить пару «сертификат + приватный ключ», указать пути в директивах внутри <VirtualHost *:443>, перезапустить Apache. Отличается только выпускающий центр и частота обновления.

Несколько сайтов на 443: виртуальные хосты

Когда на одном Apache живёт больше одного домена, конфигурацию удобнее вынести в conf/extra/httpd-vhosts.conf (подключается раскомментированной строкой Include в конце httpd.conf). У каждого блока — свой ServerName и свои сертификаты.

httpd-vhosts.conf: VirtualHost *:443 с DocumentRoot, ServerName и путями к сертификату web1s.site

Готовый результат выглядит так: замок в адресной строке, цепочка доверия выстроена до корневого центра.

Окно «Сертификат», вкладка «Путь сертификации»: цепочка GlobalSign Root CA — GlobalSign RSA DV SSL CA 2018 — www.web1s.site

Чек-лист: HTTPS не поднимается

Если после настройки соединение не устанавливается, браузер ругается на сертификат или тонкий клиент не достукивается до базы — проверяйте по порядку.

  • mod_ssl не подключён. Строка LoadModule ssl_module modules/mod_ssl.so должна быть раскомментирована. Без неё Apache просто не распознаёт директивы SSLEngine и SSLCertificateFile.
  • Порт 443 занят. На Windows его часто держит уже установленный IIS. Проверка: netstat -aon | findstr :443.
  • Сертификат просрочен или выписан не на тот домен. И браузер, и тонкий клиент сверяют срок действия и совпадение Common Name/SAN с адресом. Сертификат для localhost не подойдёт для внешнего домена.
  • Права на приватный ключ. На Linux файл .key должен быть читаем только пользователем Apache, права 600. Слишком открытые права — типичная причина отказа стартовать при строгих политиках.
  • Неполная цепочка сертификатов. Если сертификат выдан центром с промежуточным звеном, нужен SSLCertificateChainFile (или единый файл с полной цепочкой для Apache 2.4.8+). Без него часть клиентов не построит цепочку доверия.
  • Несколько <VirtualHost> на 443 без ServerName. Apache не сможет по SNI определить, какой сертификат отдавать.
  • Тонкий клиент не доверяет сертификату. Ошибка «удалённый узел не прошёл проверку» — сертификат не добавлен в доверенные на стороне клиента. Для самоподписанного это делается вручную, для Let's Encrypt и сертификата хостера не требуется.
  • Конфиг поправлен, но Apache не перезапущен. Или перезапущен с опечаткой — httpd.exe -t перед каждым рестартом.

Публикация 1С на веб-сервере IIS

Если у вас Windows Server и не хочется ставить сторонний веб-сервер, публикуйте на встроенном IIS. Порядок такой:

  1. Диспетчер серверов → Добавить роли и компоненты → Веб-сервер (IIS). В компонентах разработки приложений обязательно отметьте ISAPI Extensions и ISAPI Filters — без них 1С работать не будет.
  2. Установите платформу 1С с галочкой «Модули расширения веб-сервера».
  3. В Конфигураторе: Администрирование → Публикация на веб-сервере, выбираете IIS, жмёте «Опубликовать».

И вот тут вас ждёт серия типовых ошибок — я специально прошёл по ним, чтобы показать лечение:

  • Нет доступа к папке базы. Первая же публикация упирается в права: пользователю, под которым работает IIS (группа IIS_IUSRS), нужно дать полный доступ к папке файловой базы. Свойства папки → Безопасность → добавить IIS_IUSRS → Полный доступ.
  • Пустая страница или ошибка модуля. Не доустановлены компоненты ISAPI/ASP — вернитесь в мастер ролей и доставьте их (при извлечённом установочном диске укажите альтернативный путь к sources\sxs).
  • HTTP 403.14. Веб-сервер настроен не отдавать листинг каталога. В пуле приложения переключите Managed Pipeline Mode на Classic.
  • 32-разрядная 1С на 64-битном сервере. В дополнительных параметрах пула поставьте «Разрешены 32-разрядные приложения» → True.
  • База не открывается после обновления платформы. Проверьте Сопоставления обработчиков (Handler Mappings): обработчик 1C Web Server Extension должен указывать на wsisapi.dll текущей версии платформы. После обновления 1С путь надо поправить.

После всех настроек перезапустите сайт в диспетчере IIS и откройте http://localhost/имя_базы — должен запуститься веб-клиент.

Публикация 1С на IIS в Windows Server 2019

Порядок выше общий для любой версии IIS. На Windows Server 2019 к нему добавляется несколько деталей, из-за которых публикация обычно не заводится с первого раза, — разберу их по шагам.

Роль веб-сервера с нужными компонентами. Диспетчер серверов → Добавить роли и компоненты → Веб-сервер (IIS). В ветке Разработка приложений обязательно отмечаем ISAPI Extensions и ISAPI Filters: модуль 1С — это ISAPI-расширение, без них публикация работать не будет. Компонент CGI для 1С не нужен, его ставят, если рядом планируется PHP. Быстрее и надёжнее сделать то же самое из PowerShell от администратора:

Install-WindowsFeature Web-Server -IncludeManagementTools
Install-WindowsFeature Web-ISAPI-Ext, Web-ISAPI-Filter
Get-WindowsFeature Web-ISAPI-Ext, Web-ISAPI-Filter | Format-Table Name, InstallState

Последняя команда должна показать Installed у обоих компонентов — это дешевле, чем потом гадать, почему Конфигуратор не видит IIS.

Платформа — с модулями расширения. Устанавливая или обновляя 1С на этом же сервере, отметьте компонент «Модули расширения веб-сервера»: на сервере с одной лишь платформой его почти всегда забывают, а без wsisapi.dll публиковать нечем.

Сопоставление обработчика. После публикации из Конфигуратора у приложения базы в диспетчере IIS появляется обработчик 1C Web Server Extension в разделе «Сопоставления обработчиков» — он указывает на wsisapi.dll конкретной версии платформы. Номер версии зашит в путь, поэтому после каждого обновления 1С обработчик надо править: это ровно тот случай, когда «вчера работало, сегодня 500-я».

Пул приложения: удостоверение и права. По умолчанию пул работает под ApplicationPoolIdentity. Для файловой базы этой учётной записи нужен доступ к каталогу — прав добавляем группе IIS_IUSRS:

icacls "D:\Bases\Buh" /grant "IIS_IUSRS:(OI)(CI)M" /T

Для клиент-серверной базы права на каталог не нужны вовсе: там важно, чтобы учётная запись пула дотягивалась по сети до сервера 1С и порта менеджера кластера.

32-разрядная платформа на 64-битном сервере. Дополнительные параметры пула → «Разрешены 32-разрядные приложения» → True. Без этого пул поднимет 64-битный процесс, который не загрузит 32-битный модуль.

Первое открытие базы часто встречает ошибкой HTTP 403.14 — это про режим конвейера пула, лечение разобрано в вопросах-ответах внизу статьи.

Бонус: Apache в Docker, 1С на хосте — и почему это спорная затея

Соблазнительный сценарий — вынести Apache в Docker-контейнер, а саму 1С оставить на хостовой машине. Веб-сервер изолирован, переносится одной командой и не мусорит в системе. Я довёл эту связку до реально открывающегося веб-клиента УТ и покажу все конфиги: что где лежит и почему. Но сразу честно предупрежу — по итогам граблей: для файловой базы этот подход сомнителен, и ниже объясню, во что он упирается.

Грабля №1: Конфигуратор не видит веб-сервер в контейнере

Первое, обо что спотыкаешься: пытаешься опубликовать базу через диалог «Публикация на веб-сервере», а Конфигуратор пишет «веб-серверы не обнаружены». И это не баг. Диалог ищет локально установленный веб-сервер: Apache — по записям в реестре и службах Windows, IIS — по установке в системе. Apache внутри Docker для Конфигуратора — «другая машина», он его не найдёт в принципе. Да и нашёл бы — сгенерировал бы конфиг с Windows-путями (wsap24.dll, D:\...), а контейнеру нужны Linux-пути.

Вывод: в связке с Docker диалог Конфигуратора не применяется. Публикацию собираем вручную — а это ровно те два артефакта, что генерирует диалог: файл default.vrd в папке публикации и блок в конфиге Apache.

Грабля №2: одного wsap24.so недостаточно

Внутри контейнера Apache работает на Linux, поэтому ему нужен модуль wsap24.so из дистрибутива 1С для Linux, а не wsap24.dll. Но просто скопировать один файл не выйдет — я на этом обжёгся дважды:

  1. При загрузке wsap24.so тянет за собой ядро платформы: core83.so, nuke83.so, библиотеки ICU, libunwind. Без них Apache падает на старте с core83.so: cannot open shared object file.
  2. При работе с базой платформа догружает компоненты в рантайме (xml2.so и десятки других). Отдашь только ядро — получишь Error loading component xml2 уже в браузере.

Практический вывод: в контейнер надо отдавать весь каталог платформы 1С для Linux (~2 GB), а не отдельные файлы. Достать его можно, не устанавливая 1С на машину, — headless-распаковкой дистрибутива во временном контейнере:

# setup-full-*.run — установщик 1С для Linux (ELF, не архив), внутри компонент ws = веб-расширение
docker run --rm \
  -v "/путь/к/дистрибутиву:/dist:ro" \
  -v "/путь/к/проекту/1c-platform:/out" \
  debian:bookworm-slim bash -c '
    cp /dist/setup-full-*.run /tmp/s.run && chmod +x /tmp/s.run
    /tmp/s.run --mode unattended --unattendedmodeui none --enable-components ws
    cp -a /opt/1cv8/x86_64/*/. /out/   # весь каталог платформы на хост
  '

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

Что где лежит: структура и конфиги

docker-apache-1c/
├── docker-compose.yml
├── Dockerfile
├── conf/
│   └── 1c-publications.conf      # блоки <Directory> публикаций (аналог того, что пишет Конфигуратор)
├── www/
│   └── ut/
│       └── default.vrd           # дескриптор публикации базы «ut»
└── 1c-platform/                  # ~2 GB: wsap24.so + все runtime-компоненты платформы 1С для Linux

docker-compose.yml — монтируем папку публикаций, конфиг, файлы базы и каталог платформы:

services:
  apache-1c:
    build: .
    container_name: apache-1c
    ports:
      - "8090:80"
    volumes:
      # Папка публикаций: сюда кладём default.vrd (для файловой базы Apache её и отдаёт)
      - ./www:/usr/local/apache2/htdocs/1c
      # Блоки публикаций (Alias + <Directory> с обработчиком 1c-application)
      - ./conf/1c-publications.conf:/usr/local/apache2/conf/extra/1c-publications.conf
      # Файлы файловой базы с хоста: модуль 1С открывает 1Cv8.1CD напрямую по этому пути
      - "D:/1S/Avito/UT11_4:/var/1c-bases/ut"
      # Каталог платформы 1С для Linux: wsap24.so + все компоненты, что грузятся в рантайме
      - "./1c-platform:/opt/1c:ro"
    extra_hosts:
      # Понадобится для клиент-серверной базы: так контейнер видит сервер 1С на хосте
      - "host.docker.internal:host-gateway"
    restart: unless-stopped

Dockerfile берёт официальный образ Apache, включает нужные модули и подключает модуль 1С из смонтированного каталога платформы. LD_LIBRARY_PATH обязателен — иначе загрузчик не найдёт core83.so рядом с wsap24.so:

FROM httpd:2.4

# Каталог платформы 1С монтируется в /opt/1c (volume в docker-compose.yml).
# LD_LIBRARY_PATH нужен, чтобы загрузчик находил core83.so и прочие библиотеки 1С.
ENV LD_LIBRARY_PATH=/opt/1c

RUN set -eux; \
    sed -i \
      -e 's|^#\(LoadModule rewrite_module\)|\1|' \
      -e 's|^#\(LoadModule headers_module\)|\1|' \
      /usr/local/apache2/conf/httpd.conf; \
    printf '\nLoadModule _1cws_module /opt/1c/wsap24.so\nInclude conf/extra/1c-publications.conf\n' \
      >> /usr/local/apache2/conf/httpd.conf

EXPOSE 80

conf/1c-publications.conf — блок публикации. Это то, что Конфигуратор вписал бы сам, но с Linux-путями внутри контейнера:

Alias "/ut" "/usr/local/apache2/htdocs/1c/ut/"
<Directory "/usr/local/apache2/htdocs/1c/ut/">
    AllowOverride All
    Options None
    Require all granted
    SetHandler 1c-application
    ManagedApplicationDescriptor "/usr/local/apache2/htdocs/1c/ut/default.vrd"
</Directory>

И сам дескриптор www/ut/default.vrd. Для файловой базы в нём строка File= с путём внутри контейнера (тем, что смонтировали в docker-compose.yml):

<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
       base="/ut"
       ib="File=&quot;/var/1c-bases/ut&quot;;">
</point>

После docker compose up -d --build модуль загружается (httpd -M показывает _1cws_module), а по адресу http://localhost:8090/ut/ контейнерный Apache открывает базу и отдаёт стартовую страницу веб-клиента 1С. До этого места я связку довёл вживую.

Грабля №3, из-за которой всё это спорно: лицензия

А вот дальше веб-клиент упирается в стену: «Не найдена лицензия. Не обнаружен ключ защиты программы...». И это принципиальная проблема, а не недонастройка. При файловой базе платформенный код 1С исполняется внутри процесса Apache в контейнере, и лицензия нужна именно ему. А в контейнере (Linux в WSL2) недоступен ни один источник:

  • Аппаратный USB-ключ HASP — прокинуть USB в Docker Desktop на Windows практически нереально.
  • Программная лицензия — привязана к «железу»; активированная на Windows-хосте для контейнера недействительна, а сам контейнер эфемерный (пересоздал — параметры оборудования сменились, лицензия слетела).
  • Сетевой менеджер лицензий — работает, но его надо где-то поднять и прописать контейнеру nethasp.ini с адресом (например host.docker.internal).

Моя честная оценка

Разложить контейнерный Apache и открыть базу — получилось, и как разбор «что у публикации под капотом» это полезно. Но как боевое решение для файловой базы контейнерный Apache сомнителен: ты и так тащишь в контейнер 2 GB платформы, и всё равно упираешься в лицензирование, которое чисто в файловом варианте не решается без плясок.

Если действительно нужен Apache в Docker, разумны два пути:

  1. Клиент-серверная база. Сервер 1С (лицензированный своим ключом) живёт на хосте или в отдельном контейнере, а default.vrd указывает не на файл, а на сервер: ib="Srvr=&quot;host.docker.internal:1541&quot;;Ref=&quot;имя_базы&quot;;". Тогда лицензию сеансу выдаёт сервер, и проблема контейнера снимается. Это правильный production-путь.
  2. Полноценное сетевое лицензирование — поднять менеджер лицензий и настроить nethasp.ini. Оправдано, если такая инфраструктура уже есть.

Файловую базу для веб-доступа в любом случае стоит перевести в клиент-серверную: и по лицензиям, и по производительности (файловый 1Cv8.1CD через bind-mount заметно медленнее нативного, плюс конфликты одновременного доступа с толстым клиентом).

Публикация 1С за реверс-прокси NGinx

Ещё один рабочий сценарий: перед Apache или IIS (либо прямо перед опубликованным HTTP-сервисом 1С) ставят NGinx как реверс-прокси. Он берёт на себя TLS-терминацию, ограничение доступа (allow/deny по IP, Basic Auth), лимиты запросов и балансировку — а сам HTTP-сервис 1С остаётся «прозрачным» и про то, что перед ним стоит прокси, ничего не знает. Весь контроль доступа выносится наружу, из BSL-кода.

Со стороны 1С публикуется обычный HTTP-сервис без встроенной в код аутентификации. Например, отдача номенклатуры в JSON (корень сервиса — nci):

Функция ProductGET(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    ДанныеНоменклатуры = Новый Массив;

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |   Номенклатура.Ссылка КАК Ссылка,
    |   Номенклатура.Наименование КАК Наименование
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура";
    Выборка = Запрос.Выполнить().Выбрать();

    Пока Выборка.Следующий() Цикл
        Данные = Новый Структура;
        Данные.Вставить("uuid", XMLСтрока(Выборка.Ссылка));
        Данные.Вставить("name", Выборка.Наименование);
        ДанныеНоменклатуры.Добавить(Данные);
    КонецЦикла;

    Ответ.УстановитьТелоИзСтроки(СформироватьJSON(ДанныеНоменклатуры),
        КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    Возврат Ответ;
КонецФункции

В коде обработчика нет ни проверки логина, ни разбора заголовков X-Forwarded-For — доступ ограничивается двумя вещами снаружи: отдельной ролью веб-пользователя (минимум прав — чтение одного справочника и вызов одного метода) и настройками самого NGinx. Конфигурация прокси лежит уже вне 1С, в nginx.conf; ключевое здесь — чтобы сегмент пути публикации (nci) совпадал в location и в адресе опубликованного .1cws:

server {
    listen 443 ssl;
    server_name api.example.ru;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    location /nci/ {
        # TLS и контроль доступа — здесь, а не в BSL
        auth_basic           "1C API";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://127.0.0.1:8080/base_nci/hs/nci/;
        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;
    }
}

Такой слой удобно накрутить поверх уже настроенной публикации Apache/IIS из разделов выше: 1С отдаёт голый HTTP-сервис на localhost, а NGinx закрывает его сертификатом и Basic Auth наружу. Разбор REST-сервисов 1С и их интеграции с внешним бэкендом — на курсе интеграции (ссылка в конце статьи).

Итог

Публикация 1С на веб-сервере — навык, который открывает всю интеграционную часть платформы. Разберём кратко, что мы прошли: установили Apache 2.4 нужной разрядности, опубликовали базу и через Конфигуратор, и вручную через httpd.conf, разложили несколько баз на одном сервере, зашили логин прямо в конфиг для интеграций, обошли CORS для HTTP-сервисов, настроили HTTPS и разобрали публикацию на IIS со всеми типовыми ошибками. А в бонусе честно прошли путь с Apache в Docker — до открытой базы в браузере и до понимания, где этот путь упирается в лицензирование и почему для файловой базы он спорный.

Если хотите не просто повторить шаги, а системно разобраться в интеграции 1С с внешним миром — HTTP-сервисы, OData, обмен с сайтами и внешними сервисами, — это ровно то, чему я учу в курсе по интеграции 1С. Публикация на веб-сервере там первый шаг, с которого начинается всё остальное.

А начать можно с занятия по HTTP-сервисам в 1С: опубликовали базу — и сразу отдаёте и принимаете данные по HTTP.

Частые вопросы