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-подключений, не смогут обновлять данные"
  • Кнопка "Удалить"
  • Кнопка "Отмена"

 

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

 

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

Администратор впервые вкладку "Драйверы", но в системе не загружен ни один драйвер

 

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

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

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

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