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-подключений
- Настроить алертинг: при ошибке загрузки, таймауте подключения или превышении лимита попыток отправлять уведомление
- Ролевая модель (бэкенд)
- Доступ к добавлению и валидации драйверов имеют только пользователи с ролью "Администратор системы"
- Доступ к созданию подключений имеют только пользователи с ролью "Разработчик" и выше
Архитектурная схема
Сценарии использования
| 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 записи из хранилища параметров
- Тип СУБД – текст
- Версия СУБД – текст
- Описание – текст
- Статус – текст
- Должна быть проверка на роль пользователя – только администратор системы
- GET-запрос
- Обновления jar-файлов в хранилище:
- PATCH-запрос (ну или PUT, просто стараюсь соблюсти REST)
- Передает в себе:
- id записи из хранилища параметров
- Может передавать в себе:
- Файл драйвера
- Тип СУБД – текст
- Версия СУБД – текст
- Описание – текст
- При перезаписи файла должна быть выполнена проверка валидации как при добавлении файла
- Если валидация пройдена, старый файл удаляется, вместо него добавляется переданный
- Должна быть проверка на роль пользователя – только администратор системы
- Удаления jar-файлов в хранилище:
- DELETE-запрос
- Передает в себе:
- id записи из хранилища параметров
- Удаляется и запись в хранилище параметров, и jar-файл в реестре драйверов согласно пути к файлу в хранилище параметров
- Должна быть проверка на роль пользователя – только администратор системы
- Передачи 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 кнопки: удалить ("корзина") и редактировать ("карандаш")
- Если в списке нет элементов, то нет и списка. В области остается только кнопка "Добавить"
При добавлении/редактировании драйвера открывается модальное окно:
- Название окна – "Добавление/редактирование драйвера"
- Поле ввода "Тип", по умолчанию пустое, обязательно для заполнения
- Поле ввода "Версия СУБД", по умолчанию пустое
- Область выбора файла с кнопкой "Выбрать файл"
- Кнопка "Добавить"
- Кнопка "Отмена"
При удалении драйвера появляется модальное окно с ошибкой:
- Название – "Удаление драйвера"
- Текст: "Вы уверены, что хотите удалить данный драйвер? Все существующие подключения, использующие драйвер для JDBC-подключений, не смогут обновлять данные"
- Кнопка "Удалить"
- Кнопка "Отмена"
Если драйвер не прошел валидацию, то появляется всплывающая ошибка при открытом окне создания/редактирования: "Валидация драйвера не пройдена: обнаружены критические нарушения безопасности или целостности файла"
Сценарии использования
Администратор впервые вкладку "Драйверы", но в системе не загружен ни один драйвер

