Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
В продолжение к предыдущей статье Передовые технологии на службе СЭД рассмотрим современные подходы к обеспечению корпоративной безопасности и ожидаемые риски у корпораций в России.
Аннотация
Что такое безопасность уровня Enterprise? Встречается огромное разнообразие схем конфигурации безопасности инфраструктуры. Например: валидация и кэширование токена только в сервисе Gateway с прямой отправкой логина и списка ролей сервисам или ретрансляция токена с Gateway в сервисы для активации функций Spring Security через распаковку токена в логин и роли с проверкой только подписи токена открытым ключом.
На самом деле, любую существующую схему безопасности можно отнести к Enterprise. Базовая конфигурация Spring Security, предоставляемая по умолчанию, не выдерживает высоких нагрузок. Данный фактор стал одним из главных причин разнообразия подходов к безопасности, возникших в поиске оптимального способа поддержки высоких нагрузок в рамках существующей инфраструктуры и технологий.
В статье рассматриваются основные аспекты конфигурирования корпоративной безопасности с поддержкой высоких нагрузок в реактивном стеке технологий. Подробно описана модель безопасности attribute-based access control (ABAC), которая применяет совокупность абстрактных правил к определённому типу действий с учётом роли при необходимости.
Перечисляются видимые риски более высокого уровня с обзором их снижения или обхода. А также, некоторый поучительный исторический экскурс с акцентом на до сих пор актуальные риски по безопасности.
Введение
Начнём с рассмотрения основополагающей на данный момент модели безопасности ABAC в сравнении с классической моделью role-based access control (RBAC).
Классическая модель безопасности RBAC предлагает грубый подход, не позволяющий описать политику безопасности многоуровневой филиальной системы.
RBAC оперирует ролями и группами ролей. Каждая роль напрямую привязана к действию, что приводит к созданию большого количества ролей (роль менеджера головной организации, роль менеджера филиала, роль менеджера подразделения филиала – разные сущности в силу функциональных различий).
Сплошной список ролей не позволяют эффективно выстроить политики безопасности, группирующие типичные действия из-за неочевидности их разграничения. Модель RBAC стала архаичной не смотря на сегодняшнее присутствие в большинстве информационных систем.
Основное преимущество модели безопасности ABAC в возможности описания политики безопасности через совокупность правил, основанных на атрибутах участвующих в действиях пользователя. Такой подход позволяет детализировать политики безопасности до необходимого уровня.
Целевое направление применения ABAC – описание политик безопасности филиальной системы с полным контролем доступа до любого уровня вложенности и сложности описания. Все правила ABAC описываются в виде SpEL-выражений и в отличии от RBAC хранятся в базе данных, где соответственно легко поддаются анализу и модификации.
Можно отметить интересный факт связанный с переходом информационной безопасности от модели RBAC к ABAC – на первом этапе каждая политика содержит одно правило.
Предлагаемые в статье технологии и подходы в полной мере реализуют концепцию ABAC с поддержкой высоких нагрузок за счёт применения каскадного кэширования с гарантией консистентности.
В итоге, реализована библиотека Reactive Spring ABAC Security с открытым исходным кодом на GutHub, обладающая рядом свойств: как гибкость в настройках, мощь в широких возможностях и скорость в работе. Библиотека опубликована в Maven Central:
<dependency>
<groupId>io.github.sevenparadigms</groupId>
<artifactId>reactive-spring-abac-security</artifactId>
<version>1.0.0</version>
</dependency>
Через настройки библиотеки можно выбрать любую гомоморфную исходной схему конфигурации безопасности из коробки, а также генерировать или валидировать токен – в совокупности такая гибкость становится особенно удобно при разработке макета проекта на начальной стадии с целью точной оценки итоговых сроков реализации или участия в тендере, продемонстрировав готовый макет с основным функционалом, в то время, как у конкурентов ничего нет.
Совсем не обязательно поднимать дополнительный корпоративный SSO-сервер аутентификации типа Keycloak для задач такого рода, когда скорость реализации и простота развёртывания выходят на передний план – ведь такие задачи выполняют фрилансеры без отрыва внутренних ресурсов.
Предлагаемая библиотека на клиентской стороне активирует Spring Security с моделью безопасности ABAC, при этом, кэшируя данные по токену, обратившись к сервису авторизации только один раз. Пометка отозванности токена в кэше происходит через событие Spring Event, инициацию которого оставляем за логикой инфраструктуры при завершении сессии пользователя.
Основные аспекты реализации
Рассмотрим основные моменты при настройке конфигурации безопасности Spring Security:
@Bean
fun securityWebFilterChain(
http: ServerHttpSecurity,
authenticationWebFilter: AuthenticationWebFilter,
abacRulePermissionService: AbacRulePermissionService,
expressionHandler: DefaultMethodSecurityExpressionHandler
): SecurityWebFilterChain {
expressionHandler.setPermissionEvaluator(abacRulePermissionService)
http.csrf().disable()
.headers().frameOptions().disable()
.cache().disable()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint())
.and()
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS)
.permitAll()
.and()
.requestCache().requestCache(NoOpServerRequestCache.getInstance())
.and()
.authorizeExchange()
.matchers(EndpointRequest.toAnyEndpoint())
.hasAuthority(Constants.ROLE_ADMIN)
.and()
.authorizeExchange()
.pathMatchers(*Constants.whitelist).permitAll()
.anyExchange().authenticated()
.and()
.securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
.addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHORIZATION)
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
if (super.tokenIntrospector() != null) {
http.oauth2ResourceServer()
.opaqueToken().introspector(super.tokenIntrospector())
}
return http.build()
}
Строка expressionHandler.setPermissionEvaluator(abacRulePermissionService) включает функционал ABAC. Все правила ABAC представляют собой компилируемые и кэшируемые SpEL-выражения, предоставляя полную свободу в предикатах. Описание подключения ABAC будет в разделе настройки безопасности на стороне клиентского сервиса через файл конфигурации application.yml
По умолчанию, при первом запросе клиента, Spring создаёт web-сессию для кэширования сессионных переменных, результата запросов и сбора различных данных при взаимодействии с клиентом в рамках одной сессии. Данный подход устарел, даже при кэшировании сессий в Redis или Hazelcast – сессии занимают значительный объем памяти и вся логика вокруг сессий не имеет перспектив, не говоря уже о проблемах утечки в реактивном стеке.
На много проще и увереннее поддерживать жизнь сессии в рамках одной реактивной цепочки инструкций запрос-ответа, после чего, сессия благополучно закроется вместе с сессионным потоком. Кто-то возразит и скажет, что кэширование сессий экономит до тысячи инструкций на её создание, но тут дело в совокупности факторов: неоднозначность данной оптимизации пришедшей в наследство из синхронного стека, высокой эффективности современных процессоров, когда тысяча инструкций выполняются менее чем за 1 мс и высоком риске утечки памяти реактивного стека.
Следующей строкой отключаем поддержку сессий: securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
В Webflux была проблема #7157 связанная с кэшированием в сессиях, поэтому также отключаем сессионное кэширование строкой: requestCache().requestCache(NoOpServerRequestCache.getInstance()), чтобы Webflux оперировал только кэшем уровня бизнес-логики и только в контексте потока исполняемого запроса.
По умолчанию, Spring Security не кэширует токен по хэшу из-за постоянной необходимости проверки токена на отозванность в сервисе авторизации. Но допустим, если взять с десяток сервисов с разной степенью нагруженностью в зависимости от решаемых бизнес-задач и разнесёнными в десятки подов, то сервису авторизации понадобится больше сотни подов из-за чрезмерной нагрузки, т.к. один внешний запрос может каскадно индуцировать подзапросы на все сервисы и создавая таким образом подобие DDoS-атаки на сервис авторизации.
Возможность кэширования токенов предусмотрена в библиотеке Spring OAuth2 через расширение OpaqueToken и кэширующий интроспектор NimbusOpaqueToken, который единожды валидирует токен в сервисе авторизации. Заменим интроспектор на свою реализацию, т.к. в нашей библиотеке не используются автоконфиги Spring OAuth2 не смотря на заимствование функционала и включим в конфигурацию строкой: http.oauth2ResourceServer().opaqueToken().introspector(super.tokenIntrospector())
Настройка безопасности клиента
Рассмотрим файл конфигурации application.yml из демонстрационного проекта webflux-dsl-abac-example:
spring:
r2dbc:
url: r2dbc:postgresql://postgres:postgres@localhost/dsl_abac?schema=public
pool:
maxSize: 20
main:
allow-bean-definition-overriding: true
security:
abac.url: r2dbc:postgresql://postgres:postgres@localhost/abac_rules?schema=public
iteration: 512
length: 720
secret: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwiYXV0aCI6IlJPTEVfVVNFUiIsImV4cCI6MTYzMDYxMDI5NX0.m0XU2NvGaAtzptgLfmptj3Fk7S1e1NrBTYTqBAjHoPI8lbRB7z3J52FiLRw-PUZPjQusDt19RszrUQDsZoVXeQ
expiration: 1800
X-User-Id: true
skip-token-validation: true
cache-token: true
Как видим, есть основное соединение с базой данных, а есть отдельная база данных abac_rules, в которой аккумулируются правила со всех сервисов, что удобно в управлении безопасностью и появляется возможность переиспользования правил. А если включить репликацию таблиц abac_rules в базы данных филиалов, то появится централизованное управление безопасностью.
Переменные iteration и length используются для генерации секретного ключа и соли системного пароля пользователя. Переменная secret используется как часть секрета для генерации пароля пользователя и токена. Переменная expiration имеет значение времени жизни токена в секундах.
X-User-Id при значении true активирует Spring Security, когда ожидается в заголовках в ключе X-User-Id приходит значение id пользователя, а в X-Roles массив ролей. Имя пользователя в Spring Security указывается как пустая строка, если заголовок X-Login отсутствует.
Переменная skip-token-validation при значении true активирует Spring Security, извлекая из токена имя пользователя и роли. Стоит единственная проверка на время жизни токена.
Переменная cache-token при значении true активирует Spring Security с полной валидацией токена и кэшированием данных токена. В случае, если в конфигурации не прописан путь до сервиса авторизации spring.security.introspection.uri, тогда ожидается, что токен каким-то образом уже лежит в текущем CacheManager – это удобно при кустомном способе авторизации пользователя, а иначе CacheManager используется для кластерного кэширования токена.
Практическое применение ABAC
Скрипт создания таблицы:
CREATE TABLE abac_rule
(
id uuid DEFAULT uuid_generate_v1mc() NOT NULL PRIMARY KEY,
name text,
domain_type text,
target text,
condition text
);
insert into abac_rule(name, domain_type, target, condition)
values('Test Rule', 'Dsl', 'action == ''findAll'' and subject.roles.contains(''ROLE_ADMIN'')', 'domainObject.sort == ''id:desc'''),
('IP Rule', 'Dsl', 'action == ''findAll'' and environment.ip == ''192.168.2.207''', 'domainObject.sort == ''id:desc'''),
('Query jtree not null Rule', 'Dsl', 'action == ''findAll'' and subject.roles.contains(''ROLE_ADMIN'')', 'domainObject.query == ''!@jtree'' and domainObject.fields ==''id'' and domainObject.sort == ''id:desc'''),
('Query equals jsonb field Rule', 'Dsl', 'action == ''findAll'' and subject.roles.contains(''ROLE_ADMIN'')', 'domainObject.query == ''jtree.name==Acme doc'' and domainObject.sort == ''id:desc'''),
('Query equals jsonb field in Rule', 'Dsl', 'action == ''findAll'' and subject.roles.contains(''ROLE_ADMIN'')', 'domainObject.query == ''jtree.name^^Acme doc'' and domainObject.sort == ''id:desc''');
Применение правила в аннотации над методом:
@PreAuthorize("hasPermission(#dsl, 'findAll')")
fun findAll(@PathVariable jfolderId: UUID, dsl: Dsl)
= objectService.findAll(jfolderId, dsl)
Для более подробного изучения применения ABAC следует изучить исходный код тестов демонстрационного проекта webflux-dsl-abac-example
Системные риски безопасности
Microsoft официально до 2013 года, в соответствии с законами на тот момент, была обязана встраивать в свои ОС дыры и сообщать о выявленных спецслужбам США. Сейчас эти пункты из законов исключены, но оставили возможность взаимодействия на коммерческой основе для формирования баланса между коммерческим имиджем и уровнем технологичности ведения разведки.
В 2013 году спецслужбами США было взломано большинство правительственных серверов Китая через маршрутизаторы Cisco и ОС Windows Server. В дальнейшем выяснилось, маршрутизаторы подменили во время таможенного досмотра в США. По прибытию в Китай маршрутизаторы были успешно перепрошиты, но изменений в печатной плате не выявлены.
В результате данного инцидента, с текущего 2022 года все правительственные учреждения, подрядчиковые организации и финансовые институты Китая обязаны работать только с маршрутизаторами, серверами и операционными системами отечественного производства.
Есть у этой истории и обратная сторона – сразу после инцидента, с 2013 по 2015 года в Китае было произведено десятки тысяч серверов Supermicro с дополнительным чипом 2х3 мм, которые в массовом порядке поставлены сотням компаний по всей планете. Из них 7000 серверов были установлены в Apple. Также сервера доставили подрядчику Министерства обороны США Elemental, который устанавливал их в бортовые сети боевых кораблей ВМФ, центры управления беспилотников ЦРУ, центры обработки данных Министерства обороны, NASA, обе палаты Конгреса, подразделение внутренней безопасности Госдепа, а также в Amazon.
В результате этой атаки, все представляющие интерес сервера Supermicro с выходом в Интернет были взломаны и на десятки анонимных серверов в Интернете выгружено петабайты информации. Микрокод встроенного чипа регулярно пытался установить соединение с рядом действующих DNS-серверов в Интернете, имитируя dns-запрос и как только соединение устанавливалось, сразу загружалась подпрограмма сканирования и идентификации.
В 2015 году новое подразделение Amazon Web Services (AWS), созданное для нужд ЦРУ, наняла стороннюю компанию для проверки безопасности серверов, поставляемые Elemental, где обнаружили чип вне оригинальной конструкции плат Supermicro. Apple в том же году демонтировал 7000 серверов Supermicro и разорвал контракт на поставку еще 30 тыс. серверов Supermicro.
Эта история приблизилась к развязке в конце сентября 2015 года, когда председатель КНР Си Цзиньпин и президент США Барак Обама сделали совместное заявление о правовой поддержке защиты интеллектуальной собственности и увеличении поставок сетевого оборудования из США в Китай.
В России же налажен выпуск отечественных маршрутизаторов на процессоре «Байкал-Т1», но по ним еще нет эксплуатационной экспертизы и соответственно компании не готовы к переходу. Также нет серверной ОС и все крупнейшие системообразующие институты России на свой постоянный страх и критически высокий риск используют Windows Server и AWS от Amazon.
В случае начала театра военных действий и в силу «чуждости» повсеместно используемых технологий, вполне логично ожидать прямой атаки и уничтожения под корень, в первую очередь, баз данных финансовых институтов страны.
И обратно, если прилегающая страна, нарушая принципы добрососедства стала размещать у себя системы ПРО-ПВО и авиационные системы противника, то во время боевых действий вероятность «утечки» данных к противнику будет близка к 100%, сколько не из-за желания соседей их передавать, а из-за возможного наличия дополнительного чипа.
Поэтому, в силу стратегии национальной безопасности, с первых же секунд боевых действий начнётся операция по принуждению к миру обведенной вокруг пальца противником соседствующей страны, когда уничтожаются всё вооружение и военная инфраструктура.
К слову, Россия производит модульную военную технику, отчасти чтобы исключить возможность использования дополнительного чипа, чтобы заказчики вставляли свои модули в самые чувствительные места самолёта, корабля, танка или средств ПВО.
Резюме
Усиление информационной безопасности Китая привело к значительному ускорению развития отечественных технологий и беспрецедентной поддержке IT-стартапов государством. России было бы естественно рассмотреть существующие стандарты безопасности Китая по оборудованию в госсекторе, что сэкономило бы немало времени.
Самый быстрый способ соответствовать общемировым трендам в информационной безопасности – перенести часть производственных мощностей процессоров и системных плат из Китая в Россию для целенаправленного импортозамещения оборудования в госсекторе.
Необходимо строить совместные кластера с Китаем и Индией как c ближайшими союзниками, с которыми связаны десятилетия совместных работ по исследованию и производству высокотехнологичной продукции. А финансовым институтам выстраивать партнёрские отношения с IT-гигантами Alibaba и Xiaomi для обоюдного обогащения компетенциями. Настоящая мощь всех исторических империй была в разнообразии способа выражения силы.