/ Каталог продукции / Охрана периметра / Интегрированная система охраны ИСО Тополь / Программное обеспечение / API трансляции данных

ИСО Тополь API мониторинга

Предварительная редакция от 29 Июля 2022г.

1. Введение

1.1 Назначение

API мониторинга является расширением ИСО Тополь API интеграции и предназначено для трансляции данных во внешние сервисы.
В отличии от API интеграции, которое нацелено на запросы клиента к серверу, API мониторинга позволяет серверу самостоятельно передавать данные без инициации обмена внешним сервисом

1.2 Совместимость

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

1.3 Протокол передачи данных без шифрования

Для обмена информацией (без использования шифрования) с внешним сервисом используется протокол HTTP/1.1 в соответствии с RFC 2616 “Hypertext Transfer Protocol -- HTTP/1.1” https://tools.ietf.org/html/rfc2616

1.4 Протокол передачи данных с шифрованием

Для обмена информацией с внешним сервисом с использованием шифрования канала передачи данных используется протокол HTTPS в соответствии с RFC 2818 “HTTP Over TLS” https://datatracker.ietf.org/doc/html/rfc2818

1.5 Формат передачи данных

Данные между сервером ИСО Тополь и внешним сервисом передаются в одностороннем порядке по инициативе сервера с помощью POST запроса.
Набор передаваемых данных представляет из себя JSON в соответствии с rfc 8259 «The JavaScript Object Notation (JSON) Data Interchange Format» https://tools.ietf.org/html/rfc8259

1.5.1 Формат передачи данных о дате и времени

Данные поля типа дата (например дата события) передаются в формате POSIX time (Unix epoch) + три регистра для миллисекунд т.е. например дата 1519220475466 = 1519220475 POSIX (21 Февраля 2018 13:41:15 GMT) + 466 миллисекунд = 21.02.2018 13:41:15:466 GMT

1.5.2 Формат передачи идентификаторов

Данные типа UUID представляют из себя уникальный идентификатор, сформированный в соответствии с RFC 4122 «A Universally Unique IDentifier (UUID) URN Namespace» https://tools.ietf.org/html/rfc4122
Передаются UUID в строковом виде в формате, описанном в пункте 3.Namespace Registration Template, «The formal definition of the UUID string representation»

2 Авторизация и идентификаторы

Для авторизации сервера на стороннем сервиса и передачи идентификатора сервера, используются заголовки: - bosid - идентификатор сервера, указанный в переменной SET_SSOI_ID файла конфигурации - password - пароль сервера, указанный в переменной SET_SSOI_PASSWORD файла конфигурации

SET_SSOI_ID может содержать любое текстовое значение в зависимости от требований стороннего сервиса. Рекомендуется использовать текстовое представление UUID в соответствии с пунктом 1.5.2 Формат передачи идентификаторов для обеспечения совместимости между сторонними сервисами и облачной инфраструктурой ИСО

SET_SSOI_PASSWORD может содержать как сам пароль так и его хэш в зависимости от требований внешнего сервиса.

ВАЖНО! Пароль или хэш пароля хранятся в файле конфигурации в открытом виде, в случае установки сервера ИСО Тополь на оборудование заказчика необходимо предпринять меры по защите файла от несанкционированного доступа

2.1 Авторизация с динамическим ключом

Для повышения уровня безопасности авторизации на внешнем сервисе, возможно использование динамического ключа в поле password. Для этого необходимо установить значение переменной SET_SSOI_PASSWORD_SALT в значение true в файле конфигурации.
При этом в поле password будет передаваться не значение переменной SET_SSOI_PASSWORD а SHA-512 хэш с солью, в качестве которой выступает текущее значение системного времени сервера в формате POSIX time (Unix epoch) с нулевым значением текущих секунд. При использование динамического ключа значение SET_SSOI_PASSWORD передаётся в кодировке Base64

Таким образом ключ изменяется изменяется раз в минуту вместе с солью.
При расшифровке данных внешний сервис должен сравнить известный ему пароль (или хэш пароля, если в переменной SET_SSOI_PASSWORD указан хэш) с полученным хэшем используя в качестве соли своё системное время, аналогично представленное в формате POSIX time (Unix epoch) с нулевым значением текущих секунд

Пример реализации функции хэширования на языке Java:

    private static String getHashSHA(String password, Long timestamp) throws NoSuchAlgorithmException {
        if (timestamp == null) {  // Метка времени которая используется в качестве соли для пароля сервера Тополь.
            // Сторонний сервис должен обеспечивать возможность проверки данных с несколькими метками для корректной
            // работы в случае рассинхронизации часов между сервером Тополь и сервером стороннего сервиса
            timestamp = Instant.now().getEpochSecond(); // Метка времени обрезается до секунд
        }
        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); // Подготовка массива байт соли
        buffer.putLong(timestamp);
        byte[] salt = buffer.array(); // Соль
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-512"); // Дайджест для SHA-512
        messageDigest.update(salt); // Заполнение динамическими (солью) данными
        byte[] hash = messageDigest.digest(password.getBytes(StandardCharsets.UTF_8)); // Заполнение статическими (паролем) данными
        return Base64.getEncoder().encodeToString(hash); // Кодирование в Base64
    }

ВАЖНО! Для обеспечения возможности работы динамического ключа, необходимо чтобы внешний сервис позволял рассинхронизацию своего времени со временем сервера как минимум на 1 минуту т.к. посылка данных может быть сформирована в конце минуты и с учётом сетевых задержек быть принятой внешним сервисом в следующую минуту.

3 Адресация

Адреса запросов формируются из адреса стороннего сервиса и адреса точки доступа приёмника данных для конкретного типа данных

3.1 Адрес стороннего сервиса

Сервер позволяет указать адреса трёх разных сторонних сервисов, на которые будет вестись трансляция данных в переменных файла конфигурации SET_SSOI_URL1, SET_SSOI_URL2 и SET_SSOI_URL3.
В переменной указывается полный путь с указанием протокола (http или https), ip адреса или доменного имени сервиса и порта для приёма данных, например:

SET_SSOI_URL1=https://cloud.ssoi.ru:30000
SET_SSOI_URL2=https://cloud.npfpol.ru:40000
SET_SSOI_URL3=http://10.42.0.3:33000

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

ВАЖНО! Сервер ИСО Тополь не контролирует когерентность данных на серверах SET_SSOI_URL1, SET_SSOI_URL2 и SET_SSOI_URL3 внешнего сервиса, синхронизация данных между ними должна осуществляться на стороне внешнего сервиса

4 Адреса точек доступа и передача данных

4.1 Передача состояния сервера

При запуске сервера, ИСО тополь передаёт своё полное состояние отправляя пакет данных в формате идентичном ответу на запрос списка приборов (см. пункт 4. Получение списка приборов в ИСО Тополь API интеграции) в точку доступа JSON_SET_STATE

JSON_SET_STATE = "/json/setstate";

Например, если SET_SSOI_URL1=https://cloud.ssoi.ru:30000 то итоговый POST запрос будет нацелен на https://cloud.ssoi.ru:30000/json/setstate

Аналогично с командой “Получение списка приборов” в “ИСО Тополь API интеграции” передаваемый при статус является актуальной опорной точкой для дальнейшего мониторинга с помощью новых событий, однако существует возможность принудительной синхронизации в двух вариантах, которые могут работать одновременно: - при помощи регулярной отправки пакета статуса - если в файле конфигурации значение переменной SET_SSOI_SEND_STATE_INTERVAL выставлено больше 0, то полное состояние сервера будет транслироваться с указанным интервалом (в секундах) - при помощи отправки пакета статуса при каждом изменении состоянии системы если переменная SET_SSOI_SEND_STATE_ON_CHANGE выставлена в значение true в файле конфигурации

ВАЖНО! Стоит учитывать что частая передача пакета статуса приведёт к значительному потреблению трафика. Обратите внимание на пункт 4.2 где описан альтернативный вариант принудительной синхронизации с более легковесным пакетом данных

4.2 Передача зон

При запуске сервера, ИСО тополь передаёт полное состояние охраняемых зон в формате идентичном ответу на запрос списка зон (см. пункт 8.1 Получение списка зон в ИСО Тополь API интеграции) в точку доступа JSON_SET_ZONES

JSON_SET_ZONES = "/json/setzones";

Аналогично передаче полного статуса, существует возможность принудительной синхронизации состояния зон в двух вариантах, которые могут работать одновременно: - при помощи регулярной отправки пакета статуса зон - если в файле конфигурации значение переменной SET_SSOI_SEND_ZONES_INTERVAL выставлено больше 0, то полный статус зон будет транслироваться с указанным интервалом (в секундах) - при помощи отправки пакета статуса зон при каждом изменении их состоянии если переменная SET_SSOI_SEND_ZONES_ON_CHANGE выставлена в значение true в файле конфигурации

4.3 Передача событий

При формировании нового события в системе, оно оценивается по уровню важности (поле level) и если его уровень выше чем указанный в переменной SET_SSOI_LEVEL то оно попадает в буфер событий для отправки внешнему сервису.
Это позволяет указывать начиная с каких событий вести трансляцию данных и не отсылать события низкой важности. Список уровней приведён в “ИСО Тополь API интеграции”

Размер локального буфера может быть отрегулирован в переменной SET_SSOI_MAX_CACHE. При удачной передаче события внешнему сервису оно удаляется из буфера. При переполнении буфера формируется событие отсутствия связи с внешним сервисом и новые события перестают приниматься буфером до его частичной очистки при успешном сеансе связи со сторонним сервисом.

Раз в секунду сервер оценивает наличие событий в буфере, и при их наличии инициирует передачу внешнему сервису, обращается к точке

JSON_ADD_EVENT = "/json/addevent";

События передаются в формате JSON аналогично ответу на запрос “4. Получение оперативного списка событий” но сервер самостоятельно следит за индексом последнего переданного события.
Если в конфигурационном файле значение переменной SET_SSOI_EVENTS_ACCEPTS_ARRAY выставлено в false, то сервер будет передавать по одному событию (от старых к новым) за сеанс, если значение выставлено в true то будут переданы все доступные события в виде массива объектов

5 Полное шифрование данных

Настройка SET_SSOI_SALT в файле конфигурации позволяет включить шифрование всех передаваемых данных в теле запроса независимо от применяемого протокола передачи данных.
Для шифрования данных используется AES в режиме CBC с дополнением PKCS#5
Пример реализации функции расшифровки данных на языке Java:

    public static String decrypt(String data, Long timestamp, String password) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        if (timestamp == null) {  // Метка времени которая используется в качестве соли для пароля сервера Тополь.
            // Сторонний сервис должен обеспечивать возможность проверки данных с несколькими метками для корректной
            // работы в случае рассинхронизации часов между сервером Тополь и сервером стороннего сервиса
            timestamp = Instant.now().getEpochSecond(); // Метка времени обрезается до секунд
        }
        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); // Подготовка массива байт соли
        buffer.putLong(timestamp);
        byte[] salt = buffer.array();  // Соль
        byte[] vectorBuffer = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Буфер вектора инициализации
        IvParameterSpec vector = new IvParameterSpec(vectorBuffer); // Вектор инициализации
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); // PBKDF2-HMAC-SHA256
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256); // Длина ключа 256
        SecretKey key = keyFactory.generateSecret(keySpec);
        SecretKeySpec secretKey = new SecretKeySpec(key.getEncoded(), "AES"); // Ключ
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // Шифр AES в режиме CBC с дополнением PKCS#5
        cipher.init(Cipher.DECRYPT_MODE, secretKey, vector);
        return new String(cipher.doFinal(Base64.getDecoder().decode(data))); // Преобразование из Base64 и расшифровка
    }

Все предложения в этой категории:


Приборы Фото
Руководство пользователя
Открытое API
API трансляции данных