Часто возникает ситуация: кто-то изменил важный документ, и в журнале регистрации 1С мы видим только общую информацию — имя пользователя, тип соединения WS-соединение, номер сеанса и идентификатор транзакции. При этом множество устройств, например терминалы сбора данных (ТСД), могут работать под одним общим пользователем 1С. Возникает закономерный вопрос: можно ли по номеру сеанса узнать конкретное устройство (IP-адрес, MAC-адрес, пользователя операционной системы)? Проанализируем ситуацию и разберем все доступные способы решения этой задачи.
Если мы посмотрим в стандартный Журнал регистрации 1С, то заметим, что для веб-сервисов и WS-соединений платформа не фиксирует IP-адреса конечных устройств. Обычно в логах отображается только служебный пользователь (например, IIS_USR) или внутренний IP самого веб-сервера. Это связано со спецификой работы протокола SOAP в архитектуре платформы 1С.
Рассмотрим, как можно найти концы, если документ уже был изменен, и у нас есть только номер сеанса и время транзакции.
Если на вашем веб-сервере было заранее включено полное логирование (access logs), мы можем сопоставить данные. Для этого берем точное время транзакции из журнала регистрации 1С (с точностью до секунды) и ищем соответствующий запрос в логах Apache (файл access.log) или логах IIS. Там будет зафиксирован IP-адрес, с которого физически пришел HTTP-запрос к опубликованному веб-сервису.
Если на сервере 1С был заранее настроен сбор Технологического журнала с детализацией событий CONN, CALL или HTTP, мы сможем вытащить оттуда реальный IP-адрес. В потоке ТЖ по номеру сеанса можно найти свойство ClientIP. Важно понимать: без заранее включенного ТЖ этот метод бесполезен.
Проанализируем ситуацию, когда ТСД или ПК находятся за роутером (в другом сегменте сети). Веб-сервер IIS или Apache увидит только IP-адрес шлюза (например, 192.168.1.1). Чтобы узнать внутренний "серый" IP-адрес конечного устройства, нам придется дополнительно анализировать логи маршрутизатора за то же самое время.
Разберем способы определения параметров для активных сессий.
Откроем консоль кластера 1С, перейдем в раздел "Сеансы". Там присутствуют колонки "IP-адрес клиента" и "Имя компьютера". Однако для WS-соединений там часто будет фигурировать хост самого сервера, а не удаленного устройства.
Посмотрим на пример использования встроенного языка 1С. Можно использовать метод ПолучитьСоединенияИнформационнойБазы(). Он возвращает массив текущих соединений. Мы можем перебрать их в цикле и проверить свойства ИмяКомпьютера и НомерСеанса.
Выясним причину сложностей: платформа 1С для классических SOAP-сервисов не предоставляет удобного метода для чтения HTTP-заголовков. Разберем по шагам, как изменить архитектуру обмена, чтобы всегда знать, кто изменяет данные.
Лучшим решением будет модификация клиентского приложения (например, ПО на ТСД). Клиент при формировании запроса к 1С должен сам определять свой локальный IP-адрес или MAC-адрес и вставлять его в тело запроса (в параметры XML).
Далее, на стороне сервера 1С, при обработке этого запроса, мы принудительно пишем эти данные в журнал регистрации:
// В модуле веб-сервиса
// Параметр ВходящийIP передается с клиента
ЗаписьЖурналаРегистрации("ОбменДанными.ВебСервис",
УровеньЖурналаРегистрации.Информация,
Метаданные.Документы.ЗаказКлиента,
ДокументСсылка,
"Изменение документа с устройства. IP: " + ВходящийIP);
Рассмотрим современный вариант. Если вместо WS-соединений использовать HTTP-сервисы, мы получаем полный доступ к HTTP-заголовкам запроса. Если клиент прошел через прокси, мы можем вытащить его оригинальный IP из стандартных заголовков. Посмотрим на пример кода:
Функция МойСервисОбработатьЗапрос(Запрос)
// Получаем IP адрес из заголовков прокси-сервера
РеальныйIP = Запрос.Заголовки.Получить("X-Forwarded-For");
Если РеальныйIP = Неопределено Тогда
РеальныйIP = Запрос.Заголовки.Получить("X-Real-IP");
КонецЕсли;
// Логируем полученный IP-адрес
ЗаписьЖурналаРегистрации("HTTPСервис.Запрос",,,, "IP клиента: " + РеальныйIP);
// Дальнейшая логика обработки...
КонецФункции
Этот подход делает систему полностью прозрачной и безопасной, позволяя легко идентифицировать любое устройство в сети.