security-audit: креды Kafka и PAT Zitadel — из статических Secret'ов вместо Vault Agent
В контуре uralkal роли Vault (security-audit, security-audit-bootstrap) не заведены.
Коллекторы и Job idp-actions-bootstrap монтируют Secret'ы namespace (security-audit-kafka,
kafka-ca) projected volume'ом в /vault/secrets под теми же именами файлов — конфиг
коллекторов (${file:...}, ca_file) не меняется. Из NetworkPolicy убран egress в Vault,
из оверлея uralkal — dependsOn на HelmRelease vault.
This commit is contained in:
parent
f0014c5d00
commit
3162679524
@ -104,16 +104,13 @@ DaemonSet `audit-collector-agent` на узлах `node-role.kubernetes.io/contr
|
||||
|
||||
rm /tmp/admin.properties
|
||||
```
|
||||
3. **Vault** (`secrets/` — KV v2):
|
||||
- секрет `secrets/data/security-audit/kafka` с ключами `username`, `password`, `ca_crt`;
|
||||
`ca_crt` — содержимое `ca.crt` из Secret `kafka/kafka-kafka-contour-tls` (CA генерирует чарт `kafka-contour`,
|
||||
срок 365 дней; при перевыпуске обновить и здесь);
|
||||
- политика `read` на `secrets/data/security-audit/kafka`;
|
||||
- роль `security-audit` в `auth/kubernetes`: bound SA `audit-collector` **и** `access-collector`, namespace
|
||||
`security-audit`, политика выше.
|
||||
|
||||
Заводится в `infra/terraform`, ветка `contour`, модуль `vault-platform-secrets` (роли `vault_kubernetes_auth_backend_role`,
|
||||
KV-секреты).
|
||||
3. **Креды Kafka — статические Secret'ы** в namespace `security-audit` (роли в Vault не заведены, агент-инжектор
|
||||
не используется):
|
||||
- Secret `security-audit-kafka` с ключами `username`, `password` (SCRAM-пользователь `security-audit`);
|
||||
- Secret `kafka-ca` с ключом `ca.crt` — содержимое `ca.crt` из Secret `kafka/kafka-kafka-contour-tls`
|
||||
(CA генерирует чарт `kafka-contour`, срок 365 дней; при перевыпуске обновить и здесь).
|
||||
Оба монтируются projected volume'ом в `/vault/secrets` под именами `kafka-username`, `kafka-password`,
|
||||
`kafka-ca.crt` — конфиг коллекторов (`${file:...}`, `ca_file`) не меняется.
|
||||
4. **Образ** `cr.yandex/crp3ccidau046kdj8g9q/opentelemetry-collector/opentelemetry-collector-contrib:0.121.0-amd64`
|
||||
доступен в registry контура (тот же, что дефолт чарта `opentelemetry-collector-prod` 0.117.1), `regcred` есть в
|
||||
namespace `security-audit`.
|
||||
@ -126,7 +123,7 @@ DaemonSet `audit-collector-agent` на узлах `node-role.kubernetes.io/contr
|
||||
- ../../infrastructure/security-audit/uralkal
|
||||
```
|
||||
|
||||
`dependsOn` в оверлее ждёт HelmRelease `kafka/kafka` и `vault/vault`.
|
||||
`dependsOn` в оверлее ждёт HelmRelease `kafka/kafka`.
|
||||
|
||||
Порядок: сначала должен раскататься провайдер `audit-access` в istiod (`infrastructure/istio-pilot/uralkal/istio-pilot.yaml`,
|
||||
применяется сразу, как только попадёт в master: кластер его уже подключает). Telemetry из `mesh/` ссылается на этот провайдер по имени. Проверка:
|
||||
@ -260,9 +257,8 @@ spec:
|
||||
Метка `istio-injection: disabled` отключила бы инъекцию совсем, даже по метке пода.
|
||||
- `PeerAuthentication` в репозитории нет, поэтому режим PERMISSIVE. Шлюз шлёт в коллектор по auto-mTLS (оба в mesh),
|
||||
коллектор в Kafka — тоже через mTLS (`kafka` в mesh), внутри остаётся `SASL_SSL`.
|
||||
- Vault Agent (`agent-init-first`, pre-populate) + istio-proxy: по паттерну контура (`apps/bi`, `apps/bim`, `apps/cde`…)
|
||||
`traffic.sidecar.istio.io/excludeOutboundPorts: "8200"`. Init-агент ходит в Vault мимо iptables-перехвата,
|
||||
даже если `istio-init` отработал раньше.
|
||||
- Креды Kafka — статические Secret'ы (projected volume в `/vault/secrets`), Vault Agent не используется:
|
||||
роли `security-audit` в Vault контура нет.
|
||||
- `holdApplicationUntilProxyStarts`: kafka exporter подключается к брокерам на старте и без готового proxy падает.
|
||||
- `istio-init` требует `NET_ADMIN`/`NET_RAW`: enforce `privileged` это разрешает, профиль `warn: baseline` даст
|
||||
предупреждения при создании подов — ожидаемо.
|
||||
@ -382,8 +378,8 @@ HTTP-probe на pilot-agent `:15020`, а тот ходит в приложени
|
||||
- **Mesh.** Job в mesh (`sidecar.istio.io/inject=true`, `holdApplicationUntilProxyStarts`). В конце скрипт вызывает
|
||||
`POST 127.0.0.1:15020/quitquitquit`, istio-proxy завершается, под — `Completed`. STRICT mTLS у Zitadel сейчас нет, но
|
||||
Job к нему готов.
|
||||
- **Vault:** роль `security-audit-bootstrap`, `secrets/data/security-audit/zitadel-bootstrap` → `pat` →
|
||||
`/vault/secrets/zitadel-pat`; `excludeOutboundPorts: 8200` — паттерн контура.
|
||||
- **PAT:** статический Secret в namespace `security-audit` (роли в Vault нет), монтируется в
|
||||
`/vault/secrets/zitadel-pat`; имя Secret'а и ключа — в `job.yaml`, сверить с созданным в контуре.
|
||||
- **Скрипт** (`files/idp-actions-bootstrap.sh`, POSIX sh) идемпотентен:
|
||||
1. ждёт `/debug/ready` (10 попыток × 15 с);
|
||||
2. печатает все типы событий инстанса (`known: …`, `POST /admin/v1/events/types/_search`);
|
||||
@ -405,10 +401,8 @@ HTTP-probe на pilot-agent `:15020`, а тот ходит в приложени
|
||||
- Топик `security.idp-events`: 3 партиции, `retention.ms=259200000`, RF по контуру, тем же путём, что остальные
|
||||
топики. Пользователь `security-audit`, ACL не нужны.
|
||||
- Сервисный пользователь Zitadel `security-audit-bootstrap` (machine user) с ролью `IAM_OWNER` на инстансе.
|
||||
Нужны `action.target.read/write/delete`, `action.execution.read/write`, `events.read`. Его PAT — во Vault
|
||||
`secrets/data/security-audit/zitadel-bootstrap`, ключ `pat`.
|
||||
- Роль Vault `security-audit-bootstrap` в `auth/kubernetes`: bound SA `idp-actions-bootstrap`, namespace `security-audit`,
|
||||
политика `read` на `secrets/data/security-audit/zitadel-bootstrap`.
|
||||
Нужны `action.target.read/write/delete`, `action.execution.read/write`, `events.read`. Его PAT — ключ
|
||||
в статическом Secret'е namespace `security-audit` (см. `base/idp-actions-bootstrap/job.yaml`).
|
||||
- Feature flag не нужен: в v4.12.2 `actions` в `/v2/features/instance` удалён (reserved), Actions v2 включены всегда.
|
||||
|
||||
Проверка API изнутри кластера (ожидается `"https://login.sarex.local.uralkali.com"`):
|
||||
|
||||
@ -118,31 +118,24 @@ spec:
|
||||
sidecar.istio.io/inject: "true"
|
||||
# Kafka exporter подключается к брокерам на старте: без готового istio-proxy коллектор упадёт.
|
||||
proxy.istio.io/config: '{"holdApplicationUntilProxyStarts": true}'
|
||||
# Паттерн контура для Vault + sidecar (apps/*/base): трафик агента к Vault мимо istio-proxy.
|
||||
traffic.sidecar.istio.io/excludeOutboundPorts: "8200"
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/agent-init-first: "true"
|
||||
vault.hashicorp.com/agent-pre-populate-only: "true"
|
||||
vault.hashicorp.com/agent-requests-cpu: "25m"
|
||||
vault.hashicorp.com/agent-limits-cpu: "100m"
|
||||
vault.hashicorp.com/auth-path: auth/kubernetes
|
||||
vault.hashicorp.com/role: security-audit
|
||||
# Многострочные шаблоны — см. helmrelease-collector.yaml (toYaml | tpl в чарте).
|
||||
vault.hashicorp.com/agent-inject-secret-kafka-username: secrets/data/security-audit/kafka
|
||||
vault.hashicorp.com/agent-inject-template-kafka-username: |-
|
||||
{{ "{{- with secret \"secrets/data/security-audit/kafka\" -}}" }}
|
||||
{{ "{{ .Data.data.username }}" }}
|
||||
{{ "{{- end -}}" }}
|
||||
vault.hashicorp.com/agent-inject-secret-kafka-password: secrets/data/security-audit/kafka
|
||||
vault.hashicorp.com/agent-inject-template-kafka-password: |-
|
||||
{{ "{{- with secret \"secrets/data/security-audit/kafka\" -}}" }}
|
||||
{{ "{{ .Data.data.password }}" }}
|
||||
{{ "{{- end -}}" }}
|
||||
vault.hashicorp.com/agent-inject-secret-kafka-ca.crt: secrets/data/security-audit/kafka
|
||||
vault.hashicorp.com/agent-inject-template-kafka-ca.crt: |-
|
||||
{{ "{{- with secret \"secrets/data/security-audit/kafka\" -}}" }}
|
||||
{{ "{{ .Data.data.ca_crt }}" }}
|
||||
{{ "{{- end -}}" }}
|
||||
|
||||
# Креды Kafka — статические Secret'ы namespace (роли security-audit в Vault нет).
|
||||
# Те же пути /vault/secrets/..., что читает конфиг: ${file:...} и ca_file.
|
||||
extraVolumes:
|
||||
- name: kafka-secrets
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
name: security-audit-kafka
|
||||
items:
|
||||
- {key: username, path: kafka-username}
|
||||
- {key: password, path: kafka-password}
|
||||
- secret:
|
||||
name: kafka-ca
|
||||
items:
|
||||
- {key: ca.crt, path: kafka-ca.crt}
|
||||
extraVolumeMounts:
|
||||
- {name: kafka-secrets, mountPath: /vault/secrets, readOnly: true}
|
||||
|
||||
# Контур-специфичное (CONTOUR, KAFKA_BROKERS) задаётся в оверлее через extraEnvs.
|
||||
alternateConfig:
|
||||
|
||||
@ -51,7 +51,7 @@ spec:
|
||||
create: false
|
||||
serviceAccount:
|
||||
create: true
|
||||
name: audit-collector # = роль Vault security-audit, bound SA
|
||||
name: audit-collector # bound SA роли Vault security-audit — если вернёмся на Vault Agent
|
||||
presets:
|
||||
logsCollection: {enabled: false}
|
||||
hostMetrics: {enabled: false}
|
||||
@ -96,39 +96,31 @@ spec:
|
||||
hostPath: {path: /var/log/audit, type: DirectoryOrCreate}
|
||||
- name: otelcol-storage
|
||||
hostPath: {path: /var/lib/otelcol-audit, type: DirectoryOrCreate}
|
||||
# Креды Kafka — статические Secret'ы namespace (роли security-audit в Vault нет).
|
||||
# Projected volume складывает оба Secret'а в /vault/secrets под теми же именами файлов,
|
||||
# что читает конфиг: ${file:/vault/secrets/kafka-username|kafka-password}, ca_file=kafka-ca.crt.
|
||||
- name: kafka-secrets
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
name: security-audit-kafka
|
||||
items:
|
||||
- {key: username, path: kafka-username}
|
||||
- {key: password, path: kafka-password}
|
||||
- secret:
|
||||
name: kafka-ca
|
||||
items:
|
||||
- {key: ca.crt, path: kafka-ca.crt}
|
||||
extraVolumeMounts:
|
||||
- {name: audit-log, mountPath: /var/log/audit, readOnly: true}
|
||||
- {name: otelcol-storage, mountPath: /var/lib/otelcol-audit}
|
||||
- {name: kafka-secrets, mountPath: /vault/secrets, readOnly: true}
|
||||
|
||||
# Метка исключает под из webhook'а инъекции Istio ещё до мутации (namespace без istio-injection).
|
||||
podLabels:
|
||||
sidecar.istio.io/inject: "false"
|
||||
podAnnotations:
|
||||
sidecar.istio.io/inject: "false"
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/agent-init-first: "true"
|
||||
vault.hashicorp.com/agent-pre-populate-only: "true"
|
||||
vault.hashicorp.com/agent-requests-cpu: "25m"
|
||||
vault.hashicorp.com/agent-limits-cpu: "100m"
|
||||
vault.hashicorp.com/auth-path: auth/kubernetes
|
||||
vault.hashicorp.com/role: security-audit
|
||||
# Чарт рендерит podAnnotations через toYaml | tpl: однострочный шаблон toYaml переносит,
|
||||
# и литерал {{ "..." }} рвётся. Поэтому по строке на действие (block scalar не переносится).
|
||||
vault.hashicorp.com/agent-inject-secret-kafka-username: secrets/data/security-audit/kafka
|
||||
vault.hashicorp.com/agent-inject-template-kafka-username: |-
|
||||
{{ "{{- with secret \"secrets/data/security-audit/kafka\" -}}" }}
|
||||
{{ "{{ .Data.data.username }}" }}
|
||||
{{ "{{- end -}}" }}
|
||||
vault.hashicorp.com/agent-inject-secret-kafka-password: secrets/data/security-audit/kafka
|
||||
vault.hashicorp.com/agent-inject-template-kafka-password: |-
|
||||
{{ "{{- with secret \"secrets/data/security-audit/kafka\" -}}" }}
|
||||
{{ "{{ .Data.data.password }}" }}
|
||||
{{ "{{- end -}}" }}
|
||||
vault.hashicorp.com/agent-inject-secret-kafka-ca.crt: secrets/data/security-audit/kafka
|
||||
vault.hashicorp.com/agent-inject-template-kafka-ca.crt: |-
|
||||
{{ "{{- with secret \"secrets/data/security-audit/kafka\" -}}" }}
|
||||
{{ "{{ .Data.data.ca_crt }}" }}
|
||||
{{ "{{- end -}}" }}
|
||||
|
||||
# Контур-специфичное (CONTOUR, KAFKA_BROKERS) задаётся в оверлее через extraEnvs.
|
||||
# Полный конфиг вместо мержа с дефолтами чарта.
|
||||
|
||||
@ -19,19 +19,6 @@ spec:
|
||||
annotations:
|
||||
sidecar.istio.io/inject: "true"
|
||||
proxy.istio.io/config: '{"holdApplicationUntilProxyStarts": true}'
|
||||
traffic.sidecar.istio.io/excludeOutboundPorts: "8200" # Vault мимо istio-proxy (паттерн контура)
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/agent-init-first: "true"
|
||||
vault.hashicorp.com/agent-pre-populate-only: "true"
|
||||
vault.hashicorp.com/agent-requests-cpu: "25m"
|
||||
vault.hashicorp.com/agent-limits-cpu: "100m"
|
||||
vault.hashicorp.com/auth-path: auth/kubernetes
|
||||
vault.hashicorp.com/role: security-audit-bootstrap
|
||||
vault.hashicorp.com/agent-inject-secret-zitadel-pat: secrets/data/security-audit/zitadel-bootstrap
|
||||
vault.hashicorp.com/agent-inject-template-zitadel-pat: |-
|
||||
{{- with secret "secrets/data/security-audit/zitadel-bootstrap" -}}
|
||||
{{ .Data.data.pat }}
|
||||
{{- end -}}
|
||||
spec:
|
||||
serviceAccountName: idp-actions-bootstrap
|
||||
restartPolicy: Never
|
||||
@ -82,6 +69,7 @@ spec:
|
||||
- {name: script, mountPath: /scripts, readOnly: true}
|
||||
- {name: events, mountPath: /config, readOnly: true}
|
||||
- {name: tmp, mountPath: /tmp}
|
||||
- {name: zitadel-pat, mountPath: /vault/secrets, readOnly: true}
|
||||
volumes:
|
||||
- {name: tools, emptyDir: {sizeLimit: 16Mi}}
|
||||
- {name: tmp, emptyDir: {medium: Memory, sizeLimit: 16Mi}} # заголовки с PAT — только в памяти
|
||||
@ -89,3 +77,10 @@ spec:
|
||||
configMap: {name: idp-actions-bootstrap-script}
|
||||
- name: events
|
||||
configMap: {name: idp-actions-bootstrap-events}
|
||||
# PAT machine user'а security-audit-bootstrap — статический Secret (роли в Vault нет).
|
||||
# TODO(verify): имя Secret'а и ключа сверить с созданным в контуре; скрипт читает PAT_FILE=/vault/secrets/zitadel-pat.
|
||||
- name: zitadel-pat
|
||||
secret:
|
||||
secretName: security-audit-kafka
|
||||
items:
|
||||
- {key: zitadel_pat, path: zitadel-pat}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
# Коллектору нужны только DNS, Kafka и Vault (агент-инжектор). Входящие — только health-check kubelet'а.
|
||||
# Коллектору нужны только DNS и Kafka. Входящие — только health-check kubelet'а.
|
||||
# (Раньше был egress в Vault для агента-инжектора; креды — статические Secret'ы.)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
@ -25,8 +26,3 @@ spec:
|
||||
ports:
|
||||
# client-листенер SASL_SSL: bootstrap kafka-kafka-contour и advertised-адреса подов controller-headless
|
||||
- {port: 9092, protocol: TCP}
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels: {kubernetes.io/metadata.name: vault}
|
||||
ports:
|
||||
- {port: 8200, protocol: TCP} # vault-vault-contour.vault.svc:8200 (AGENT_INJECT_VAULT_ADDR)
|
||||
|
||||
@ -7,8 +7,6 @@ spec:
|
||||
dependsOn:
|
||||
- name: kafka
|
||||
namespace: kafka
|
||||
- name: vault
|
||||
namespace: vault
|
||||
values:
|
||||
extraEnvs:
|
||||
- name: CONTOUR
|
||||
|
||||
@ -7,8 +7,6 @@ spec:
|
||||
dependsOn:
|
||||
- name: kafka
|
||||
namespace: kafka
|
||||
- name: vault
|
||||
namespace: vault
|
||||
values:
|
||||
extraEnvs:
|
||||
- name: CONTOUR
|
||||
|
||||
Loading…
Reference in New Issue
Block a user