(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет! Меня зовут Денис, можно просто Дэн. Я пришёл в разработку 20 лет назад, когда ещё был жив Delphi, где-то через 3 года перешёл на Java. За это время успел покодить, побыть тимлидом, начальником отдела, ИТ-директором, техлидом и даже на пару лет отойти от Java. Каюсь) За это время накопилось немного опыта, мыслей, вопросов, идей, которыми хочется поделиться. Поэтому и решил завести канал про Java разработку и сопутствующие ей темы. Что здесь будет - да много чего :) В частности: сравнение технологий, может даже с холиваром, а ля Java vs Kotlin, Maven vs Gradle, Lombok или не Lombok. Еще: типичные проблемы при разработке и что с ними можно сделать, мысли про новые фреймворки, библиотеки, языки, и т.д. DevOps в части CI. Совсем базовых вещей здесь не будет, для этого есть Baeldung, куча бесплатных курсов и хороших книг
Послушал доклад на JPoint про уже подзабытую уязвимость log4j и удивился 3 вещам.
Напомню: оказывается некоторые версии log4j2 позволяли вставлять в выводимое в лог сообщение выражение, позволяющее сделать удалённый вызов через механизм JNDI lookup. Причём есть возможность не только слить какие-то критичные данные, но и что-то запустить на сервере, пишущем логи, через встроенный в JDK JS движок и его функцию eval.

Первое, что удивило: уязвимость появилась в 2014 году, найдена и обсуждена на конференции по ИБ в 2016 году. Примерно тогда же появился первый фикс, который ничего не фиксил) Выстрелила в конце 2021. Как можно было про нее забыть??? Неразвитость ИБ? Информационная перегрузка? Кому-то было выгодно?

Второе: на первый взгляд эксплуатировать уязвимость сложно - нужно чтобы совпали 3 фактора: использование log4j определённого диапазона версий, отсутствие валидации пользовательского ввода и либо возможность вызвать внешний сервер для передачи конфиденциальных данных или загрузки remote code из внутренней сети, либо сервер атакующего уже должен быть во внутренней сети. Ну и детали об атакуемой системе неплохо бы знать: куда передавать сообщение с exploit-ом, что можно слить, что можно запустить на сервере. Но если подумать, несколько широко распространён log4j, как много пользовательских данных, http заголовков к нам приходит, и что-то из этого точно логируется, а главное как много ИТ систем в мире и 100% не у всех хватает денег на выделенного ИБ спеца - уязвимость совсем не кажется абстрактной, скорее наоборот.

И наконец третье. Разные я видел способы пропатчить библиотеку, сам патчил, но чтобы взять и вырезать файл - это что новое. Но способ эффективный - учитывая редкость использования функционала, в котором была найдена уязвимость, появившийся на сервере ClassNotFoundException в 99,9% случаев будет указывать на атаку. Ну и напоследок - как можно было такое редкий и опасный функционал включать по умолчанию...

Вывод: следование практикам ИБ и feature toggling рулят

#security #vulnerability
(java || kotlin) && devOps pinned «Всем привет! Меня зовут Денис, можно просто Дэн. Я пришёл в разработку 20 лет назад, когда ещё был жив Delphi, где-то через 3 года перешёл на Java. За это время успел покодить, побыть тимлидом, начальником отдела, ИТ-директором, техлидом и даже на пару лет…»
Чем kubernetes, он же k8s лучше контейнера сервлетов или сервера приложений.
Во-первых под капотом k8s лежит Docker, а значит мы получаем все его плюшки. Не зря k8s называют оркестратором контейнеров. Чем занимается оркестратор?
1) планированиеи ресурсов. Разработчик декларативно задает как он хочет задеплоить своё приложение в Deployment. А именно: сколько нужно экземпляров - replicas, сколько CPU и памяти - requests и limits, про соседству с какими приложениями его нужно размещать, по соседству с какими не нужно - labels и (anti) affinity. k8s исходя из имеющихся у него серверов, они же nodes, и их загрузки размещает экземпляры приложения - pods. Или процесс раскатки падает, если подходящих серверов нет( У серверов приложений такого механизма нет. Важно добавить - процесс поддержания требуемой конфигурации приложения непрерывный, при любых отклонениях k8s будет убивать и добавлять поды.
2) стратегия раскатки. k8s позволяет в том же Deployment в параметре strategy задать два базовых варианта: при появлении новой версии гасить все поды сразу и поднимать новые или раскатывать плавно, учитывая значения максимально допустимого превышения и нехватки числа экземпляров MaxSurge и MaxUnaveilable. Для серверов приложений такое поведение можно реализовать с помощью DevOps джобы.
3) автоматическое восстановление. Нода или под могут упасть. Падение определяется по healthcheck, заданному в том же Deployment, причём очень гибко, см livenessProbe, readinessProbe и startupProbe. k8s при наступлении такого события рестартует pod. Для серверов приложений это либо делается руками, либо автоматизируется извне.
4) горизонтальное масштабирование. С помощью HorizontalPodAutoscaller можно задать диапазон числа реплик и предельную загрузку CPU, при которой k8s добавляет или убирает реплики. Для серверов приложений - опять же ручное управление.
Отдельно хочу отменить внутреннюю DNS в k8s. Если у вас несколько приложений в одном облаке, он же cluster, то можно делать запросы по имени из Service. Вся внутренняя маршрутизация в облаке работает именно так. Для серверов приложений снова ничего такого нет.
Ну и load balancing, url/port mapping и SSL termination. В старом мире этим занимался отдельно стоящий nginx, в k8s его включили в периметр системы. #cloud
Всем привет! Решил написать пост про архитектурную проблему, с которой столкнулся недавно. Где делать сортировку данных? Обычно проблема звучит так: на клиенте, т.е в коде приложения, или на сервере, т.е. в БД? У нас все чуть сложнее. Дано:
1) БД
2) бэк-система
3) миддл-система, обслуживает веб-клиентов
4) веб-клиент.
Для начала я бы отбросил бэк-систему и веб-клиента. Веб-клиента - потому что в презентационном слое логики должно быть как можно меньше. При этом надо отметить, что исключения из этого правила могут быть, т.к клиенты сейчас мощные - 4+ ядра, 8+ Гб памяти. А бэк-систему исключаем потому, что с одной стороны рядом есть БД, а с другой - сортировка нужна для отображения пользователю, поэтому логичнее ее переместить поближе к месту использования. Т.е. сводим проблему к исходной - клиент (миддл) или сервер (БД). Исходя из каких аргументов можно сделать окончательный выбор:
1) является ли сортировка частью контракта, т.е API? Нужна ли она другим потребителям? Если является - то в БД
2) нужна ли пагинация? Если да - то сортируем в БД, т.к. только там есть полный набор данных
3) сложность условия сортировки. Можно ли его реализовать в SQL?
4) наличие индекса в БД и возможность его добавить. С индексом по полю сортировки в БД она в большинстве случае будет быстрее, чем на клиенте
5) число клиентов, обращающихся к БД. Если БД перегружена, а масштабирование невозможно, то имеет смысл вынести сортировку выше по цепочке. Еще важен тип БД, RDBMS можно масштабировать только горизонтально, 64 ядерные сервера дороги, а 128 ядерных не бывает)
6) может ли клиент менять способ сортировки при работе с данными? Если да, то стоит рассмотреть реализацию всех сортировок на клиенте
7) трудоемкость кодирования. В большинстве случаев тут "выигрывает" БД, т.к. ORDER BY декларативен и проще любых алгоритмов на Java. #arch