Skip to main content

JDBC-коннектор

Бизнес-требования

Основные требования к фиче:

  • Добавить подключение диспетчере данных – JDBC-коннектор
  • Возможность добавлять новые коннекторы к любой СУБД прямо из интерфейса системы
  • Возможность управлять параметрами подключения через конфигурацию источника
  • Обеспечить безопасность соединения
  • Сохранить логику взаимодействия с микросервисами бэкенда, просмотр статуса подключения
  • Настроить логирование всех операций с JDBC-коннекторами
  • Коннектор и нагрузка на него никак не должны влиять на производительность системы, при падении драйвера не должен падать основной поток FB
  • В документации требуется добавить новый раздел, посвященный добавлению JDBC-драйвером и подключению по JDBC к внешним СУБД

Вопросы:

  • Нужны ли типы защиты SSL/SSH? +
  • Нужен ли валидатор драйверов? + Какие поддерживаем результаты валидации (принято/отклонено или принято/предупреждение/отклонено)
  • Формирование JDBC URL: строка подключения в формате jdbc:<subdb>://<host>:<port>/<database>?  +

План работ

  • Управление драйверами (бэкенд)
    • Подготовить каталог для хранения jar-файлов драйверов с правами доступа только для сервисов платформы; обеспечить резервное копирование этого каталога
    • Настроить валидатор драйверов: проверить наличие обязательных мета-методов (getTables, getColumns, getImportedKeys, getColumnName, getColumnType, getScale, getColumnCount); обеспечить логирование результатов валидации
    • Обеспечить регистрацию драйвера в реестре: записать тип, версию, хэш-сумму (?), дату загрузки, статус
    • Настроить хранение лицензионных ключей драйверов БД; обеспечить проверку наличия лицензии при регистрации драйвера
  • Управление драйверами (фронтенд)
    • Реализовать интерфейс загрузки драйвера: выбор файла, ввод типа СУБД, версии, описания; обеспечить проверку файла
    • Реализовать вывод списка доступных драйверов в интерфейсе настройки источников
  • Конфигурация подключений (бэкенд)
    • Настроить хранение учётных данных в хранилище с обратимым шифрованием; обеспечить передачу секретов микросервисам только в момент выполнения подключения
    • Реализовать модуль тестирования подключения: при нажатии «Проверить» микросервисы пытаются установить соединение с внешней БД и выполнить пробный запрос; обеспечить возврат понятного сообщения об успехе или ошибке
    • Реализовать поддержку параметров SSL: загрузка сертификата сервера, настройка взаимной аутентификации при необходимости; обеспечить проверку валидности сертификата при тестировании подключения
    • Реализовать поддержку SSH-туннеля: ввод хоста, порта, логина, пароля или ключа; обеспечить создание туннеля перед установкой JDBC-соединения и его закрытие после завершения
  • Конфигурация подключений (фронтенд)
    • Реализовать форму создания источника данных: выбор драйвера из реестра, ввод JDBC URL, логина, пароля, настроек SSL/SSH; обеспечить маскировку пароля в интерфейсе
  • Загрузка данных (бэкенд)
    • Реализовать логику Cron: запуск загрузок по расписанию или событию; обеспечить передачу контекста выполнения в Blocker и обработку ошибок запуска
    • Реализовать логику Blocker: проверка активной загрузки для того же источника; обеспечить установку и снятие блокировки, предотвращение параллельного импорта одной таблицы
    • Реализовать логику Loader: чтение данных из внешней БД через JDBC-драйвер с учётом параметров подключения
    • Настроить запись данных в ClickHouse
  • Логирование и мониторинг (бэкенд)
    • Настроить сбор логов при добавлении и валидации драйверов, создании JDBC-подключений
    • Настроить алертинг: при ошибке загрузки, таймауте подключения или превышении лимита попыток отправлять уведомление
  • Ролевая модель (бэкенд)
    • Доступ к добавлению и валидации драйверов имеют только пользователи с ролью "Администратор системы"
    • Доступ к созданию подключений имеют только пользователи с ролью "Разработчик" и выше

АрхиИнтектуграционная схема

JDBC.png

Сценарии использования

Use case Зачем нужен
Администратор взаимодействует с веб-интерфейсом
Точка входа для всех операций с драйверами
Интерфейс читает/записывает данные в реестр драйверов
Чтобы показать список доступных драйверов и сохранить новый
Интерфейс передаёт файл драйвера на валидацию
Проверка корректности .jar-файла перед сохранением
Валидатор сохраняет проверенный файл в хранилище
Физическое хранение драйверов на диске
Реестр передаёт список доступных типов драйверов во Слой 2
Чтобы дата-инженер видел только проверенные драйверы при создании источника
BI-разработчик запускает тест подключения
Проверка работоспособности настроек перед сохранением
BI-разработчик создаёт/редактирует конфигурацию подключения
Сохранение параметров: URL, порт, имя БД
BI-разработчик настраивает маппинг таблиц и полей
Определение, какие данные и как загружать из источника
Конфигурация ссылается на хранилище учётных данных
Пароли хранятся отдельно от конфигурации (безопасность)
Конфигурация ссылается на настройки SSL/SSH
Параметры защищённого соединения вынесены отдельно
Модуль тестирования вызывает микросервисы для проверки
Реальное подключение к БД выполняется через ETL-сервисы
Микросервисы читают параметры подключения
Чтобы знать, к какой БД подключаться
Микросервисы читают правила маппинга
Чтобы знать, какие таблицы и поля загружать
Хранилище передаёт учётные данные микросервисам
Логин/пароль для подключения к внешней БД
Настройки SSL/SSH передаются микросервисам
Для защищённого соединения с источником
Микросервисы читают данные из внешних БД через JDBC
Основной процесс ETL-загрузки
Микросервисы записывают данные в ClickHouse
Загрузка данных в БД проекта для аналитики
Микросервисы пишут логи загрузки
Отладка ETL-процессов, мониторинг ошибок
Валидатор пишет логи проверки драйверов
Аудит операций с драйверами, отладка проблем

Критерии приёмки

Решение

Управление драйверами

Системная логика (бэкенд)

План работ:

  • Подготовить каталог для хранения jar-файлов драйверов с правами доступа только для сервисов платформы; обеспечить резервное копирование этого каталога
  • Настроить валидатор драйверов: проверить наличие обязательных мета-методов; обеспечить логирование результатов валидации
  • Обеспечить регистрацию драйвера в реестре: записать тип, версию, путь к файлу, хэш-сумму (?), дату загрузки, статус
  • Настроить хранение лицензионных ключей драйверов в БД; обеспечить проверку наличия лицензии при регистрации драйвера

Реестр драйверов:

  • Требуется обеспечить хранение jar-файлов в системном хранилище (например, в серверном хранилище)
  • Требуется обеспечить хранение параметров драйверов в системном хранилище (например, в PG):
    • id записи
    • Путь к файлу драйвера в хранилище
    • Тип СУБД – текст
    • Версия СУБД – текст
    • Описание – текст
    • Статус – текст
  • Требуются методы для:
    • Передачи jar-файлов с фронтенда
      • POST-запрос
      • Передает в себе:
        • Файл драйвера
        • Тип СУБД – текст
        • Версия СУБД – текст
        • Описание – текст
      • Должна быть выполнена проверка валидации файла (см. далее)
      • Должна быть проверка на роль пользователя – только администратор системы
    • Получения списка jar-файлов из хранилища
      • GET-запрос
      • Ничего не передает в себе
      • Ожидает в ответ список параметров файлов:
        • id записи из хранилища параметров
        • Тип СУБД – текст
        • Версия СУБД – текст
        • Описание – текст
        • Статус – текст
      • Должна быть проверка на роль пользователя – только администратор системы
    • Обновления jar-файлов в хранилище:
      • PATCH-запрос (ну или PUT, просто стараюсь соблюсти REST)
      • Передает в себе:
        • id записи из хранилища параметров
      • Может передавать в себе:
        • Файл драйвера
        • Тип СУБД – текст
        • Версия СУБД – текст
        • Описание – текст
      • При перезаписи файла должна быть выполнена проверка валидации как при добавлении файла
        • Если валидация пройдена, старый файл удаляется, вместо него добавляется переданный
      • Должна быть проверка на роль пользователя – только администратор системы
    • Удаления jar-файлов в хранилище:
      • DELETE-запрос
      • Передает в себе:
        • id записи из хранилища параметров
      • Удаляется и запись в хранилище параметров, и jar-файл в реестре драйверов согласно пути к файлу в хранилище параметров
      • Должна быть проверка на роль пользователя – только администратор системы

Валидатор драйверов:

Валидатор проверяет загружаемый .jar-файл JDBC-драйвера перед регистрацией в реестре. Его цель – не допустить в систему некорректные, повреждённые или небезопасные файлы.

  • Требуется метод для вызова валидации файла:
    • POST-запрос
    • Передаёт в себе jar-файл
    • Должна быть проверка на роль пользователя – только администратор системы
  • Метод обязательно вызывается при создании/редактировании драйвера
  • Обязательно выполняются следующие проверки:
    • Расширение файла = .jar
    • MIME-тип = application/java-archive или application/zip
    • Неповрежденная структура файла
    • Размер файла < 100 MB
    • Наличие манифеста META-INF/MANIFEST.MF
    • Отсутствуют подозрительные классы
    • Цифровая подпись файла валидна (при наличии)
    • Хэш не в списке уязвимых
    • Файл уникален в реестре драйверов
  • Обязательно выполняются проверки на наличие следующих мета-методов:
    • getTables,
    • getColumns,
    • getImportedKeys,
    • getColumnName,
    • getColumnType,
    • getScale,
    • getColumnCount
  • Требуется защита от Java-инъекций (не должно быть ппропущено):
    • Вредоносный класс в .jar-файле (класс с static {} блоком, выполняющим код)
    • JNDI-инъекция через логи
    • Выполнение команд на основе ввода
    • SpEL, OGNL, JavaScript в конфиге
  • Запрещенные параметры в JDBC URL:
    • allowLoadLocalInfile=true
    • allowMultiQueries=true
    • autoDeserialize=true
    • statementInterceptors
    • connectionInitSql
  • Дополнительно могут выполняться другие проверки для защиты при загрузке файлов
  • В случае ошибки необходимо возвращать на фронтенд текст "Валидация файла не пройдена. Ошибка:" + текст системной ошибки

Чек-лист проверок файла:

Проверка
Критичность
Расширение файла = .jar
Критическая
MIME-тип = application/java-archive или application/zip
Критическая
Неповрежденная структура файла
Критическая
Размер файла < 100 MB
Критическая
Наличие манифеста META-INF/MANIFEST.MF
Критическая
Отсутствуют подозрительные классы
Подозрительная
Цифровая подпись файла валидна (при наличии)
Критическая
Хэш не в списке уязвимых
Критическая
Файл уникален в реестре драйверов
Критическая
Наличие мета-метода getTables
Критическая
Наличие мета-метода getColumns
Критическая
Наличие мета-метода getImportedKeys
Критическая
Наличие мета-метода getColumnName
Критическая
Наличие мета-метода getColumnType
Критическая
Наличие мета-метода getScale
Критическая
Наличие мета-метода getColumnCount
Критическая
Отсутствие вредоносных классов (static {} блок с кодом)
Критическая
Отсутствие JNDI-инъекций через логи
Критическая
Отсутствие выполнения команд на основе ввода
Критическая
Отсутствие SpEL, OGNL, JavaScript в конфиге
Критическая
Отсутствие параметра allowLoadLocalInfile=true в JDBC URL
Критическая
Отсутствие параметра allowMultiQueries=true в JDBC URL
Критическая
Отсутствие параметра autoDeserialize=true в JDBC URL
Критическая
Отсутствие параметра statementInterceptors в JDBC URL
Критическая
Отсутствие параметра connectionInitSql в JDBC URL
Критическая
Драйвер не содержит нативных библиотек (.so, .dll, .dylib)
Подозрительная
Отсутствует доступ к System.getenv() и System.getProperties()
Подозрительная
Отсутствуют исходящие сетевые вызовы (кроме БД)
Подозрительная
Отсутствует использование Reflection API для доступа к внутренним классам JVM
Подозрительная
Отсутствуют классы с обфусцированными именами (a, b, c, ...)
Подозрительная
Отсутствуют потоки/таймеры, которые остаются активными после закрытия соединения
Подозрительная
Отсутствует сериализация объектов через Serializable
Подозрительная
Отсутствуют вызовы ClassLoader.getSystemClassLoader()
Подозрительная
Отсутствует доступ к файловой системе за пределами /tmp
Подозрительная
Размер файла соответствует типичному для драйверов этой СУБД (не аномально большой)
Подозрительная
В архиве присутствуют файлы документации (LICENSE, README)
Подозрительная
Версия драйвера не является устаревшей (> 3 лет с момента выпуска)
Подозрительная
Отсутствуют deprecated JDBC-методы в использовании
Подозрительная
Отсутствует использование finalizer-методов
Подозрительная
Отсутствуют классы с именами, содержащими Hack, Exploit, Inject, Bypass
Подозрительная
  • Если валидация пройдена (нет ни одной ошибки со статусом "Критическая"), то:
    • В таблице параметров драйверов появляется новая запись с параметрами
    • Записи присваивается статус в зависимости от результатов проверки:
      • Если нет ни одной ошибки со статусом "Подозрительная" – статус "Активен"
      • Если есть хотя бы одна ошибка со статусом "Подозрительная" – статус "Требует проверки"
    • В реестр драйверов помещается файл драйвера

 

Пользовательский интерфейс

Расположение: Панель администратора → Настройки → Новая вкладка "JDBC-драйверы"

Вкладка доступна только пользователям с ролью "Администратор системы". Для всех остальных ролей вкладка отсутствует.

На вкладке:

  • Кнопка "Добавить драйвер"
  • Прокручиваемый список драйверов (по аналогии со списком шрифтов на соседней вкладке):
    • Каждый элемент списка представляет собой поле с типом драйвера
    • Каждый элемент списка раскрывается
    • При раскрытии видны следующие данные:
      • Статус ("Принято" зеленого цвета, или "Требует проверки" желтого цвета)
      • Версия СУБД
      • Описание
    • При наведении на элемент списка появляются 2 кнопки: удалить ("корзина") и редактировать ("карандаш")
    • Если в списке нет элементов, то нет и списка. В области остается только кнопка "Добавить"

При добавлении/редактировании драйвера открывается модальное окно:

  • Название окна – "Добавление/редактирование драйвера"
  • Поле ввода "Тип", по умолчанию пустое, обязательно для заполнения
  • Поле ввода "Версия СУБД", по умолчанию пустое
  • Область выбора файла с кнопкой "Выбрать файл"
  • Кнопка "Добавить"
  • Кнопка "Отмена"

image.png

При удалении драйвера появляется модальное окно с ошибкой:

  • Название – "Удаление драйвера"
  • Текст: "Вы уверены, что хотите удалить данный драйвер? Все существующие подключения, использующие драйвер для JDBC-подключений, не смогут обновлять данные"
  • Кнопка "Удалить"
  • Кнопка "Отмена"

 

Если драйвер не прошел валидацию, то появляется всплывающая ошибка при открытом окне создания/редактирования: "Валидация драйвера не пройдена: обнаружены критические нарушения безопасности или целостности файла"

 

Сценарии использования

АдминистрПользоваторель впервыеходит на вкладку "ДJDBC-драйверы",. В интерфейсе о втображается спистеме не загружен ни одинк драйверов в виде раскрывающихся строк.

Пользователь нажимает на драйвер в списке. Раскрывается список параметров этого драйвера.

Пользователь нажимает на кнопку "Добавить драйвер". Открывается модальное окно добавления драйвера.

Пользователь нажимает в окне кнопку "Выбрать файл". Открывается filepicker для выбора файла с устройства. После выбора файл добавляется в окно в виде иконки файла с подписью в вдие названия файла. Кнопка "Выбрать файл" остается под файлом.

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

Пользователь наводит курсор на драйвер в списке. Появляются кнопки удаления и редактирования. 

Пользователь нажимает на кнопку удаления. Открывается модальное окно для удаления драйвера.

Пользователь нажимает в окне на кнопку "Удалить". Драйвер удаляется из списка.

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

 

Системная логика (фронтенд)

При переходе на вкладку "JDBC-драйверы" выполняется GET-запрос на получение списка драйверов с бэкенда. В ответ приходит массив параметров:

  • id записи из хранилища параметров
  • Тип – текст, подставляется в качестве названий элементов списка
  • Версия СУБД – текст, подставляется в список параметров при раскрытии элемента списка
  • Описание – текст, подставляется в список параметров при раскрытии элемента списка
  • Статус – текст, подставляется в список параметров при раскрытии элемента списка

При выборе файла в окне добавления/редактирования открывается filepicker. Доступны для выбора только файлы с расширением .jar. Можно выбрать ровно один файл. При повторном выборе файла в том же окне заменять старый файл на новый.

При добавлении драйвера выполняется:

  • POST-запрос на валидацию драйвера. Передает в себе только файл драйвера. Если в ответ получает ошибку валидации, то выводить всплывающее сообщение с ошибкой с бэкенда.
  • Если валидация пройдена, то выполняется POST-запрос на отправку параметров драйвера. Передаются введенные пользователем данные:
    • Файл драйвера
    • Тип – текст
    • Версия СУБД – текст
    • Описание – текст

При редактировании драйвера выполняется:

  • POST-запрос на валидацию драйвера. Передает в себе только файл драйвера. Если в ответ получает ошибку валидации, то выводить всплывающее сообщение с ошибкой с бэкенда.
  • Если валидация пройдена, то выполняется PATCH-запрос, который передает в себе все измененные параметры.

При удалении драйвера выполняется DELETE-запрос, который передает в себе id удаляемого драйвера.

Конфигурация подключений

Системная логика (бэкенд)
План работ:

  • Настроить хранилище учётных данных с обратимым шифрованием;обеспечить передачу секретов микросервисам только в момент выполнения подключения
  • Реализовать модуль тестирования подключения: при вызове метода микросервисы пытаются установить соединение с внешней БД и выполнить пробный запрос; обеспечить возврат понятного сообщения об успехе или ошибке
  • Реализовать поддержку параметров SSL: прием сертификатов, настройка взаимной аутентификации; обеспечить проверку валидности сертификата при тестировании подключения
  • Реализовать поддержку SSH-туннеля: прием параметров хоста, порта, логина, пароля или ключа; обеспечить создание туннеля перед установкой JDBC-соединения и его закрытие после завершения
  • Обеспечить регистрацию подключения в реестре: записать имя, тип драйвера, URL, зашифрованные учетные данные, настройки SSL/SSH, статус
Хранилище подключений:

Требуется обеспечить хранение параметров подключений в системном хранилище (например, в PG):
  • id записи Имя подключения – текст
  • ID драйвера – ссылка на реестр драйверов JDBC
  • URL – текст
  • Логин – текст
  • Пароль – текст (зашифрованный)
  • Настройки SSL (флаги и сертификаты) – текст/JSON (зашифрованный)
  • Настройки SSH (хост, порт, логин, пароль/ключ) – текст/JSON (зашифрованный)
  • Статус – текст
  • Дата последней проверки – дата/время
  • Результат последней проверки – текст
Требуются методы для:
  • Создания подключения:
    • POST-запрос
    • Передает в себе:
      • Имя подключения
      • ID драйвера JDBC
      • URL
      • Логин
      • Пароль
      • Настройки SSL (опционально)
      • Настройки SSH (опционально)
    • Должна быть выполнена проверка существования драйвера по ID
    • Должна быть выполнена проверка валидации JDBC URL (отсутствие запрещенных параметров)
    • Должно быть выполнено шифрование пароля и чувствительных настроек перед сохранением
    • Должна быть проверка на роль пользователя – администратор системы, администратор тенанта или разработчик
  • Тестирования подключения:
    • POST-запрос
    • Передает в себе:
      • Параметры подключения (аналогично созданию, но без сохранения) ИЛИ
      • id существующего подключения
    • Должна быть выполнена попытка установки соединения через микросервисы
    • Должна быть выполнена попытка выполнения пробного запроса
    • В случае использования SSH должно быть создано и закрыто туннельное соединение
    • Должен быть возвращен статус успеха или детализированная ошибка
    • Должна быть проверка на роль пользователя – администратор системы, администратор тенанта или разработчик
  • Получения списка подключений:
    • GET-запрос
      • Ничего не передает в себе
      • Ожидает в ответ список параметров подключений:
        • id записи
        • Имя подключения
        • Тип драйвера (получается из связанной записи драйвера) JDBC
        • URL
        • Статус
        • Дата последней проверки
        • Результат последней проверки
        • Пароли и ключи в ответе не возвращаются
        • Должна быть проверка на роль пользователя – администратор системы, администратор тенанта или разработчик
  • Обновления подключения:
    • PATCH-запрос
    • Передает в себе:
      • id записи
    • Может передавать в себе любые поля для обновления (частичное обновление)
    • При передаче нового пароля или ключей должна выполняться их повторная шифровка
    • Должна быть проверка на роль пользователя – администратор системы, администратор тенанта или разработчик
  • Удаления подключения:
    • DELETE-запрос
    • Передает в себе id записи
    • Удаляется запись из хранилища параметров
    • Должна быть проверка на отсутствие активных задач ETL, использующих данное подключение
    • Должна быть проверка на роль пользователя – администратор системы, администратор тенанта или разработчик

 

Загрузка данных

Логирование и мониторинг

Ролевая модель