При обновлении платформы 1С:Предприятие, особенно при переходе на релизы ветки 8.3.5 и выше, системные администраторы и разработчики часто сталкиваются с неприятной ситуацией: веб-сервисы перестают работать у внешних пользователей. Сама публикация кажется доступной, WSDL-описание открывается в браузере, но при попытке вызова методов мобильные приложения или внешние системы выдают ошибку: Couldn't resolve host name или Не могу определить адрес хоста.
Давайте проанализируем ситуацию: если мы заглянем внутрь WSDL-файла (который представляет собой XML), то в самом конце увидим секцию soapbind:address location. Там вместо ожидаемого внешнего адреса https://company.ru/... прописано внутреннее имя сервера в локальной сети, например, http://Server/.... Естественно, внешние клиенты ничего не знают о сервере с именем Server. В рамках этой статьи мы разберем, почему 1С так себя ведет и как заставить платформу отдавать корректные ссылки.
Первое, что мы должны проверить после любого обновления платформы — это пути к библиотекам в настройках вашего веб-сервера (Apache или IIS). Рассмотрим ситуацию: вы установили новую платформу, но веб-сервер продолжает использовать старый файл wsisapi.dll (для IIS) или mod_ws_ap24.so (для Apache) из каталога bin предыдущей версии.
Проанализируем последствия: старый модуль может некорректно взаимодействовать с новым ядром системы, что приводит к ошибкам формирования динамического контента, в том числе и WSDL-описаний. Рассмотрим шаги для исправления на примере IIS:
1C Web-service Extension).bin новой платформы.Аналогично для Apache в файле httpd.conf необходимо проверить путь в директиве LoadModule. Если путь ведет в папку старого релиза, его нужно обновить и перезапустить службу веб-сервера.
Выясним причину, по которой 1С вообще решает вставить локальное имя сервера в описание сервиса. Платформа формирует location динамически. Она смотрит на HTTP-заголовок Host, который пришел в запросе. Если между клиентом и сервером 1С стоит прокси-сервер (например, Nginx, Apache в режиме реверса или Kerio), он может подменять оригинальный заголовок на внутренний IP-адрес или локальное имя машины.
Если в 1С приходит запрос с заголовком Host: Server, она честно пишет в WSDL: "Я нахожусь на Server". Наша задача — заставить прокси-сервер передавать оригинальное имя хоста, которое ввел пользователь в браузере.
Для Apache (в роли прокси):
В конфигурационном файле проксирующего сервера необходимо включить передачу оригинального имени хоста с помощью директивы ProxyPreserveHost. Рассмотрим пример настройки:
<VirtualHost *:80>
ServerName company.ru
ProxyPreserveHost On
ProxyPass /base http://192.168.1.10/base
ProxyPassReverse /base http://192.168.1.10/base
</VirtualHost>
Для Nginx:
В блоке location нужно явно указать передачу заголовка. Посмотрим на пример конфигурации:
location /base/ {
proxy_pass http://internal_server/base/;
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_set_header Host $host; является критически важным. После применения этих настроек 1С получит в запросе company.ru и подставит его в описание веб-сервиса.
Если манипуляции с заголовками не помогают или у вас нет доступа к настройкам прокси-сервера, мы можем прибегнуть к "тяжелой артиллерии" — ручной правке файла публикации default.vrd. Этот файл находится в каталоге, куда вы опубликовали базу из конфигуратора.
В современных версиях платформы (начиная с 8.3) в теге point можно использовать атрибут base, который жестко задает базовый URL для всех относительных ссылок в публикации. Рассмотрим пример структуры файла:
<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/BaseName"
ib="Srvr="Server";Ref="BaseName";">
<ws>
<point name="MyWebService" alias="ws1.1cws"/>
</ws>
</point>
Попробуем изменить атрибут base так, чтобы он содержал полный URL. Важный момент: техподдержка 1С часто советует менять параметр ib (строку соединения с базой), прописывая там внешний адрес вместо имени сервера. Однако, как показывает практика, это часто приводит к тому, что база просто перестает открываться, так как сервер 1С:Предприятия не может найти себя по внешнему адресу. Поэтому ib лучше оставить в покое, используя внутренние имена или IP-адреса.
Если вы используете IIS без сторонних прокси-серверов, но проблема сохраняется, проанализируем настройки привязок (Bindings) сайта. Если в настройках привязки в поле "Имя узла" (Host name) пусто, IIS может передавать в 1С имя компьютера.
company.ru.Это заставит веб-сервер более корректно идентифицировать входящие запросы и передавать правильный контекст в расширение 1С.
Иногда возникают проблемы с разрешением имен внутри самой ОС, на которой стоит 1С. Рассмотрим вариант "чистой" публикации. При публикации базы через конфигуратор, в строке соединения (если используется клиент-серверный вариант), попробуйте указать IP-адрес сервера вместо его имени. Например: Srvr="192.168.1.10";Ref="base";. После этого обязательно обновите публикацию. В некоторых случаях это помогает платформе перестать использовать NetBIOS-имя сервера в генерируемых XML-документах.
После внесения любых изменений в настройки веб-сервера или файл default.vrd, выполните следующие действия:
C:\Windows\System32\drivers\etc\hosts (или /etc/hosts для Linux) добавьте строку, сопоставляющую ваш внешний домен с локальным IP-адресом сервера. Например: 127.0.0.1 company.ru. Это поможет системе правильно определять себя при локальных запросах.Подведем итог: проблема с неправильным адресом в веб-сервисах 1С почти всегда кроется в том, как веб-сервер транслирует заголовок Host в сторону платформы. Правильная настройка проксирования (в частности, использование ProxyPreserveHost On) или жесткое указание базового адреса в default.vrd позволяют решить этот вопрос раз и навсегда.