440 lines
23 KiB
Markdown
440 lines
23 KiB
Markdown
[Документация](../../README-ru.md#документация) → Безопасность
|
||
|
||
-----
|
||
|
||
[Read in English](security.en.md)
|
||
|
||
# Оглавление
|
||
|
||
⚠️ Предупреждение: детальное описание настроек безопасности достаточно длинное.
|
||
|
||
Если не боитесь - читайте [Подробное описание](#подробное-описание).
|
||
|
||
Если хотите просто быстро настроить Vitastor с шифрованием - читайте начало статьи.
|
||
|
||
- [Быстрая настройка](#быстрая-настройка)
|
||
-
|
||
|
||
# Быстрая настройка
|
||
|
||
|
||
|
||
# Пользовательские сценарии
|
||
|
||
Зачем всё это нужно вам?
|
||
|
||
|
||
|
||
# Подробное описание
|
||
|
||
Начиная с версии 3.1.0, в Vitastor есть следующие функции:
|
||
1. Шифрование соединений с etcd (TLS)
|
||
2. Шифрование соединений с OSD (AES-GCM) - по выбору либо только заголовков, либо и заголовков, и данных
|
||
3. Сквозное шифрование данных образов (AES-XTS)
|
||
4. Хранения ключей шифрования AES-XTS во внешнем Vault
|
||
5. Контрольных сумм данных на транспортном уровне с секретной "солью"
|
||
6. Аутентификация с помощью TLS (X.509) сертификатов и закрытых ключей
|
||
7. Разграничение прав доступа клиентов к данным etcd
|
||
8. Разграничение прав доступа клиентов к данным самих образов (на стороне OSD)
|
||
|
||
По умолчанию шифрование, аутентификация и авторизация отключены, но, начиная с 3.1.0,
|
||
используются контрольные суммы данных на транспортном уровне (`proto_checksums=payload`).
|
||
|
||
## Шифрование соединений с etcd (TLS)
|
||
|
||
Варианты настройки:
|
||
- Без шифрования (http)
|
||
- С шифрованием (https)
|
||
- С клиентским сертификатом, но при выключенной авторизации (`use_auth=false`) - используется
|
||
отдельный сертификат и ключ: `etcd_client_cert`, `etcd_client_key`
|
||
- С клиентским сертификатом, при включённой аутентификации на уровне OSD - используется общий
|
||
сертификат и ключ: для OSD - `osd_cert` и `osd_pkey`, для клиентов - `cert` и `pkey`
|
||
|
||
## Шифрование соединений с OSD (AES-GCM)
|
||
|
||
Варианты настройки:
|
||
- Без шифрования и без контрольных сумм: `proto_checksums=none`.
|
||
- Без шифрования, с контрольными суммами данных: `proto_checksums=payload` (можно не указывать,
|
||
т.к. это значение по умолчанию). При этом контрольные суммы можно отключить на стороне
|
||
клиента либо использовать более старые версии клиента, не поддерживающие контрольные суммы.
|
||
Если нужно запретить подключение клиентов без контрольных сумм, можно использовать опцию
|
||
`force_proto_checksums=payload`.
|
||
- С шифрованием заголовков и контрольными суммами данных: активируется при установленных опциях
|
||
`cert`, `pkey`, `osd_ca` на стороне клиента и `osd_cert`, `osd_pkey`, `osd_ca`, `client_ca`
|
||
на стороне OSD, при `proto_checksums=payload`. При этом по умолчанию запрещается
|
||
отключение контрольных сумм на уровне клиента, то есть используется `force_proto_checksums=payload`.
|
||
- С полным шифрованием всего трафика: аналогично прошлому варианту, но с `proto_checksums=gcm`.
|
||
Клиенту при этом по умолчанию разрешается понизить уровень защиты до контрольных сумм, но
|
||
это тоже можно запретить через `force_proto_checksums=gcm`. Данный вариант не является рекомендуемым,
|
||
так как добавлен в первую очередь для возможной поддержки небезопасных (публичных) сетей и
|
||
больше всего снижает производительность. В частности, если одновременно использовать полное
|
||
шифрование трафика и сквозное шифрование образов AES-XTS, то данные будут шифроваться дважды.
|
||
|
||
Для шифрования используется алгоритм AES-256-GCM и собственный упрощённый протокол согласования
|
||
ключей, полностью аналогичный TLS 1.3 ECDHE.
|
||
|
||
## Сквозное шифрование данных образов (AES-XTS)
|
||
|
||
Клиент Vitastor поддерживает шифрование данных каждого образа своим ключом. В этом случае на OSD
|
||
уходят уже зашифрованные данные и сами OSD не видят настоящее содержимое образов. Разные ключи
|
||
в том числе могут иметь разные снимки или клоны одного и того же образа. Например, можно сделать
|
||
базовый образ ВМ (условный Debian Linux) нешифрованным, но наследовать от него шифрованные образы
|
||
клиентских ВМ.
|
||
|
||
Ключи шифрования образов могут храниться либо в etcd, либо во внешнем Vault. Во втором случае
|
||
в etcd хранятся только ID ключей, а Vitastor вообще не имеет доступа к данным образов. Для
|
||
использования Vault нужно создать образ с опцией `--enc_key vault:ID`, а в конфигурации указать
|
||
опции:
|
||
- vault_url
|
||
- vault_ca
|
||
- vault_client_cert
|
||
- vault_client_key
|
||
|
||
Ещё раз повторимся, что если AES-XTS используется с полным шифрованием трафика (`proto_checksums=gcm`),
|
||
то данные образов шифруются дважды - сначала AES-XTS, а потом AES-GCM. Можете использовать,
|
||
только если вы совсем параноик :-).
|
||
|
||
## Производительность шифрования
|
||
|
||
У вас может возникнуть вопрос - а как быстро всё это прекрасное шифрование работает?
|
||
|
||
Ответ - скорость сильно зависит от процессора. Складывается она из нескольких вещей:
|
||
|
||
-
|
||
|
||
TODO: vitastor-cli bench.
|
||
|
||
## Аутентификация по сертификатам
|
||
|
||
При включённом шифровании клиенты, OSD и мониторы Vitastor аутентифицируются по сертификатам
|
||
как при соединениях с etcd (Antietcd), так и с OSD.
|
||
|
||
Для OSD и мониторов должны использоваться отдельные сертификаты - либо самоподписанные, либо
|
||
подписанные отдельными CA (`osd_ca` и `mon_ca`). При этом все OSD могут использовать один и
|
||
тот же сертификат и все мониторы тоже могут использовать один и тот же сертификат, так как
|
||
привилегии разных OSD или разных мониторов ничем не отличаются (теоретически можно было бы
|
||
сделать разграничение сертификатов OSD по пулам, но пока что такой необходимости не было).
|
||
|
||
Также сертификат монитора может быть вообще не нужен, если Antietcd встраивается в сам монитор.
|
||
В этом случае монитор и так имеет доступ ко всем данным etcd прямо в памяти.
|
||
|
||
Каждый клиент должен иметь свой сертификат, подписанный общим корневым сертификатом
|
||
для клиентов (`client_ca`). Common Name сертификата должно равняться имени пользователя.
|
||
|
||
## Модель прав доступа
|
||
|
||
Привилегии пользователей хранятся в данных etcd в ключах `/vitastor/config/user/<имя>`.
|
||
|
||
У пользователя есть 2 свойства:
|
||
- Тип:
|
||
- Клиент (`type=client` или не указано) - может читать и модифицировать только явным образом
|
||
разрешённые образы.
|
||
- Администратор (`type=admin`) - может читать и модифицировать все образы, а также администрировать
|
||
кластер: смотреть общую статистику и состояние, создавать и удалять OSD и так далее.
|
||
- Список имён групп, членом которых пользователь является.
|
||
|
||
У образов есть 3 свойства:
|
||
- Владелец (owner) - имя пользователя, которому разрешено и читать, и менять образ
|
||
- Группа владельцев (owner_group) - имя группы владельцев
|
||
- Группа читатетей (reader_group) - имя группы пользователей, которым разрешено читать образ
|
||
|
||
У пулов есть 1 свойство:
|
||
- Группа создателей (creator_group) - имя группы пользователей, которым разрешено создавать образы в пуле
|
||
|
||
## Права доступа к данным etcd
|
||
|
||
Привилегии реализуются через Antietcd во всех режимах работы. Если используется etcd, то
|
||
Antietcd выступает в роли фильтрующего прокси, при этом он может быть встроен в монитор
|
||
Vitastor или запущен отдельно. В этом случае etcd должен разрешать входящие подключения
|
||
только от Antietcd, а все остальные компоненты должны соединяться с Antietcd.
|
||
|
||
Если же используется Antietcd, то привилегии реализуются в нём самом.
|
||
|
||
Если используется встроенный в монитор Antietcd, то привилегии включаются либо параметром
|
||
`use_auth: true`, либо, если этот параметр не указан - включается автоматически, если задан
|
||
любой из параметров `client_ca`, `osd_ca`, `mon_ca`. При этом монитор требует указания
|
||
параметров `client_ca` и `osd_ca`, а если не используется режим проксирования в etcd -
|
||
также `antietcd_server_ca`, чтобы Antietcd мог отличать кластерные соединения от клиентских.
|
||
|
||
Если используется отдельно стоящий Antietcd, привилегии нужно включать явным образом.
|
||
|
||
Встроенные привилегии etcd не поддерживаются по причине их многочисленных недоработок:
|
||
- Аутентификация по сертификатам не работает в REST интерфейсе etcd,
|
||
- Привилегии хранятся отдельно от k/v и не могут участвовать в транзакциях,
|
||
- Менять привилегии может только администратор (root)
|
||
- Нет поддержки фильтрации ответов чтения по привилегиям.
|
||
|
||
Подробный список привилегий на ключи в etcd [смотрите ниже](#привилегии-etcd).
|
||
|
||
## Права доступа к данным OSD
|
||
|
||
Регулируется опцией `use_auth`, либо, если она не указана, включается автоматически,
|
||
если используется шифрование, то есть, если заданы опции `osd_ca` и `client_ca`.
|
||
|
||
OSD аутентифицирует клиентов по сертификатам и разрешает каждому клиенту только
|
||
то, что ему разрешено согласно модели прав доступа.
|
||
|
||
Подробный список разрешаемых OSD операций [смотрите ниже](#привилегии-osd).
|
||
|
||
## Права доступа к API
|
||
|
||
[vitastor-cli serve](../usage/cli.ru.md#serve) также поддерживает клиентскую
|
||
аутентификацию по сертификатам. Принимаются только сертификаты, подписанные
|
||
`client_ca`. В качестве серверного сертификата используется отдельный сертификат
|
||
`server_cert` с ключом `server_key`.
|
||
|
||
При этом для корректной работы `vitastor-cli serve` он сам должен использовать
|
||
для доступа в Vitastor сертификат (`cert`+`pkey`) пользователя с правами
|
||
администратора (`type=admin`).
|
||
|
||
Обычным клиентам при доступе к API разрешаются только API-операции с образами,
|
||
доступными им либо на чтение (для чтения), либо на запись (для модификации).
|
||
Все остальные API-вызовы разрешаются только для администраторов.
|
||
|
||
Подробный список разрешаемых API операций [смотрите ниже](#привилегии-api).
|
||
|
||
## Привилегии etcd
|
||
|
||
Ниже все названия ключей приведены без общего префикса `/vitastor`.
|
||
|
||
Разрешённые операции с ключами в Antietcd для клиентов (`type=client`):
|
||
- Только чтение:
|
||
- Разрешено всегда:
|
||
- `/config/global`
|
||
- `/config/node_placement`
|
||
- `/config/pools`
|
||
- `/pg/config`
|
||
- `/osd/state/*`
|
||
- `/pg/state/*`
|
||
- `/index/maxid/*`
|
||
- Для образов, которые [может читать пользователь](#модель-прав-доступа):
|
||
- `/config/inode/*`
|
||
- `/index/image/*`
|
||
- `/inode/stats/*`
|
||
- Чтение и запись:
|
||
- Для пулов, в которых может создавать образы пользователь:
|
||
- `/index/maxid/*`
|
||
- Для образов, которыми владеет пользователь:
|
||
- `/config/inode/*`
|
||
- `/index/image/*`
|
||
|
||
Разрешённые операции с ключами в Antietcd для администраторов (`type=admin`):
|
||
- Чтение:
|
||
- `/stats`
|
||
- `/mon/*`
|
||
- `/pg/*`
|
||
- `/pgstats/*`
|
||
- `/inode/stats/*`
|
||
- `/pool/stats/*`
|
||
- Чтение и запись:
|
||
- `/config/*`
|
||
- `/osd/*`
|
||
- `/index/*`
|
||
- `/pg/history/*`
|
||
|
||
Разрешённые операции с ключами в etcd для OSD:
|
||
- Чтение:
|
||
- `/pg/config`
|
||
- `/config/*`
|
||
- Чтение и запись:
|
||
- `/osd/*`
|
||
- `/pg/state/*`
|
||
- `/pg/history/*`
|
||
- `/pgstats/*`
|
||
|
||
Разрешённые операции с ключами в etcd для мониторов:
|
||
- Чтение:
|
||
- `/config/*`
|
||
- `/osd/*`
|
||
- `/pgstats/*`
|
||
- Чтение и запись:
|
||
- `/pg/config`
|
||
- `/stats`
|
||
- `/history/last_clean_pgs`
|
||
- `/mon/*`
|
||
- `/pg/history/*`
|
||
- `/inode/stats/*`
|
||
- `/pool/stats/*`
|
||
|
||
## Привилегии OSD
|
||
|
||
Клиентские операции:
|
||
- READ - разрешено для образов, доступных пользователю на чтение.
|
||
- WRITE, DELETE, SCRUB - разрешены для образов, доступных пользователю на запись.
|
||
- SYNC - операция не связана с образом и разрешена всегда.
|
||
- DESCRIBE - операция разрешена только для администраторов (используются командами
|
||
`vitastor-cli describe` и `fix`).
|
||
- PING - операция разрешена всегда.
|
||
- SHOW_CONFIG - операция разрешена всегда, однако если в ней клиент представляется
|
||
как OSD, то проверяется, что он использует сертификат, подписанный `osd_ca`.
|
||
- SEC_LIST (листинг) - разрешена другим OSD и администраторам с любыми параметрами,
|
||
а обычным клиентам разрешена только для запросов, ограниченных образом, доступным
|
||
пользователю на чтение.
|
||
|
||
Кластерные операции - разрешаются только другим OSD:
|
||
- SEC_READ
|
||
- SEC_WRITE
|
||
- SEC_WRITE_STABLE
|
||
- SEC_SYNC
|
||
- SEC_STABILIZE
|
||
- SEC_ROLLBACK
|
||
- SEC_DELETE
|
||
- SEC_READ_BMP
|
||
- SEC_LOCK
|
||
|
||
## Привилегии API
|
||
|
||
Клиентам (пользователям с `type=client`) разрешаются операции:
|
||
- image/list - для образов, которые пользователь может читать.
|
||
- image/create - для пулов, в которых пользователю разрешено создавать образы, либо
|
||
для создания снимков образов, которыми пользователь владеет.
|
||
- image/delete, image/flatten, image/modify - для образов, которыми пользователь владеет.
|
||
|
||
Все остальные операции разрешаются только администраторам (`type=admin`).
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
Таким образом, доступны следующие варианты настройки:
|
||
|
||
### Mon в роли Etcd proxy
|
||
|
||
Mon
|
||
- use_antietcd: true
|
||
- etcd_proxy = {
|
||
urls: [],
|
||
cert = <antietcd.pem>,
|
||
key,
|
||
ca = <etcd.pem>,
|
||
}
|
||
- antietcd_cert = antietcd.pem
|
||
- antietcd_key
|
||
|
||
etcd
|
||
--client-cert-auth --cert-file=etcd.pem --key-file=etcd.key --trusted-ca-file=antietcd.pem \
|
||
--peer-client-cert-auth --peer-cert-file=etcd.pem --peer-key-file=etcd.key --peer-trusted-ca-file=etcd.pem
|
||
|
||
### Mon с отдельным Antietcd Proxy
|
||
|
||
Mon
|
||
- use_antietcd: false
|
||
- etcd_ca = antietcd.pem
|
||
|
||
Antietcd
|
||
--client_cert_auth 1 --auth_filter vitastor_auth_filter.js --etcd_proxy url1,url2,... \
|
||
--cert antietcd.pem --key antietcd.key --ca client_ca.pem --osd_ca osd_ca.pem \
|
||
--etcd_cert antietcd.pem --etcd_key antietcd.key --etcd_ca etcd.pem
|
||
|
||
etcd
|
||
--client-cert-auth --cert-file=etcd.pem --key-file=etcd.key --trusted-ca-file=antietcd.pem \
|
||
--peer-client-cert-auth --peer-cert-file=etcd.pem --peer-key-file=etcd.key --peer-trusted-ca-file=etcd.pem
|
||
|
||
### Mon со встроенным Antietcd
|
||
|
||
Mon
|
||
- use_antietcd: true
|
||
- use_auth: true
|
||
- antietcd_cert = antietcd.pem
|
||
- antietcd_key
|
||
|
||
### Отдельный Antietcd
|
||
|
||
Mon
|
||
- use_antietcd: false
|
||
- etcd_ca = antietcd.pem
|
||
|
||
Antietcd
|
||
--client_cert_auth 1 --auth_filter vitastor_auth_filter.js
|
||
|
||
## Варианты настройки
|
||
|
||
### Настройка по умолчанию
|
||
|
||
Используются только контрольные суммы данных на транспортном уровне. Соединения с etcd не шифруются.
|
||
Аутентификация и авторизация не используется, любой клиент имеет доступ ко всем данным кластера.
|
||
|
||
Аналог настройки:
|
||
- proto_checksums: payload
|
||
|
||
### Полная защита
|
||
|
||
Везде
|
||
- osd_ca
|
||
- client_ca
|
||
- etcd_ca = antietcd.pem
|
||
|
||
OSD
|
||
- osd_cert
|
||
- osd_pkey
|
||
|
||
Клиент
|
||
- cert
|
||
- pkey
|
||
|
||
### Только защита etcd
|
||
|
||
- etcd_ca
|
||
- etcd_cert
|
||
- etcd_key
|
||
|
||
### antietcd и только защита antietcd
|
||
|
||
- etcd_ca
|
||
- etcd_cert
|
||
- etcd_key
|
||
- use_antietcd: true
|
||
- antietcd_cert = etcd_ca
|
||
- antietcd_key
|
||
- antietcd_ca = etcd_cert
|
||
|
||
### Полное шифрование протокола, включая данные
|
||
|
||
Внимание: если включить этот вариант защиты и при этом
|
||
|
||
### Только контрольные суммы на транспортном уровне, без шифрования
|
||
|
||
## Настройка Vault/OpenBao
|
||
|
||
openssl req -days 3650 -x509 -addext basicConstraints=critical,CA:TRUE,pathlen:1 --addext subjectAltName=DNS:vault \
|
||
-new -newkey rsa:4096 -nodes -keyout vault.key -out vault.crt
|
||
|
||
bao status -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200
|
||
|
||
bao operator init -n 1 -t 1 -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200
|
||
|
||
bao operator unseal -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200
|
||
|
||
bao auth enable -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200 cert
|
||
|
||
bao secrets enable -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200 -path=secret kv-v1
|
||
|
||
bao kv put -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200 secret/vitastor/testimg3 key=$(openssl rand -hex 64)
|
||
|
||
cat >testimg3.policy <<EOF
|
||
path "/secret/vitastor/testimg3" {
|
||
capabilities = ["read"]
|
||
}
|
||
EOF
|
||
|
||
bao policy write -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200 testimg3 testimg3.policy
|
||
|
||
bao write -ca-cert /etc/openbao/tls/vault.crt -address=https://vault:8200 auth/cert/certs/testimg3 certificate=@testimg3.crt display_name=testimg3 token_ttl=24h token_policies=testimg3
|
||
|
||
curl --cacert /etc/vitastor/vault.crt --cert testimg3.crt --key testimg3.key --json '{}' https://vault:8200/v1/auth/cert/login
|
||
|
||
curl --cacert /etc/vitastor/vault.crt --cert testimg3.crt --key testimg3.key -H 'X-Vault-Token: s.Qkrm78BeK7Rqdz5MA3eJZNbu' https://vault:8200/v1/secret/vitastor/testimg3
|