- README.md: перепиcан как компактный обзор (98 строк) с навигацией по docs/ - docs/: 13 файлов — getting-started, architecture, configuration, addons, storage, security, cicd, observability, networking, operations, make-reference, molecule-testing, troubleshooting - addons/*/README.md: 31 новый файл — описание, параметры, примеры кода для каждого из 34 аддонов (vault и external-secrets уже существовали)
7.1 KiB
7.1 KiB
Безопасность
Стек безопасности: HashiCorp Vault, External Secrets Operator, CrowdSec, Vaultwarden.
HashiCorp Vault
Централизованное управление секретами, PKI, динамические credentials. Подробный README: addons/vault/README.md.
Быстрый старт
# group_vars/all/addons.yml
addon_vault: true
vault_mode: "standalone" # standalone | ha
vault_auto_unseal_type: "none" # none | k8s | aws | gcp | azure | transit
vault_injector_enabled: true # Vault Agent Injector
vault_ingress_host: "vault-hc.example.com"
vault_ingress_tls: true
make addon-vault
Режимы auto-unseal
| Тип | Описание | Где хранятся ключи |
|---|---|---|
none |
Ручной unseal при каждом рестарте | Нигде — только у оператора |
k8s |
Ключи в Kubernetes Secret + unsealer Pod | Secret vault-unseal-keys |
aws |
AWS KMS | AWS KMS ключ |
gcp |
Google Cloud KMS | GCP KMS ключ |
azure |
Azure Key Vault | Azure Key Vault |
transit |
Другой Vault (transit engine) | Другой Vault |
Для homelab рекомендуется k8s:
vault_auto_unseal_type: "k8s"
vault_auto_unseal_k8s_shares: 5
vault_auto_unseal_k8s_threshold: 3
HA режим (3 ноды, Raft)
vault_mode: "ha"
vault_ha_replicas: 3
vault_auto_unseal_type: "k8s" # обязателен для HA
Инициализация (первый запуск)
После установки Ansible автоматически:
- Инициализирует Vault (
vault operator init) - Сохраняет ключи unseal в Secret (при
vault_auto_unseal_type: k8s) - Unseals Vault
- Выводит root token
Vault Agent Injector — инжекция секретов в поды
# Аннотации на Pod/Deployment:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "my-app"
vault.hashicorp.com/agent-inject-secret-config.env: "secret/myapp/config"
vault.hashicorp.com/agent-inject-template-config.env: |
{{- with secret "secret/myapp/config" -}}
DB_PASSWORD={{ .Data.data.db_password }}
API_KEY={{ .Data.data.api_key }}
{{- end }}
Секрет будет доступен в поде как /vault/secrets/config.env.
Kubernetes Auth Method
# Включить Kubernetes auth в Vault:
vault auth enable kubernetes
vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# Создать роль:
vault write auth/kubernetes/role/my-app \
bound_service_account_names=my-app \
bound_service_account_namespaces=my-app \
policies=my-app-policy \
ttl=24h
Helm чарты с Vault секретами
# Chart values через External Secrets (рекомендуется)
# или через Vault Agent annotations на Pod
# Прямой pull из Vault (в init container):
initContainers:
- name: vault-auth
image: vault:latest
command:
- sh
- -c
- |
vault login -method=kubernetes role=my-app
vault kv get -field=password secret/myapp/db > /vault/secrets/db-password
env:
- name: VAULT_ADDR
value: "http://vault.vault.svc.cluster.local:8200"
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
External Secrets Operator
Синхронизирует секреты из Vault в Kubernetes Secrets автоматически. Подробный README: addons/external-secrets/README.md.
Быстрый старт
addon_external_secrets: true
addon_vault: true # рекомендуется — ESO настраивается на Vault автоматически
external_secrets_vault_url: "http://vault.vault.svc.cluster.local:8200"
external_secrets_vault_role_id: "xxx" # после создания AppRole в Vault
Секрет в vault.yml:
vault_eso_approle_secret_id: "xxx"
Создать AppRole в Vault
vault auth enable approle
vault policy write eso-policy - <<EOF
path "secret/data/*" {
capabilities = ["read"]
}
EOF
vault write auth/approle/role/eso-role \
token_policies="eso-policy" \
token_ttl=1h \
token_max_ttl=4h
vault read auth/approle/role/eso-role/role-id
vault write -f auth/approle/role/eso-role/secret-id
ExternalSecret — синхронизировать секрет
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-app-secrets
namespace: my-app
spec:
refreshInterval: 1m
secretStoreRef:
name: vault-backend # ClusterSecretStore
kind: ClusterSecretStore
target:
name: my-app-secret # имя Kubernetes Secret
creationPolicy: Owner
data:
- secretKey: db-password
remoteRef:
key: secret/myapp
property: db_password
- secretKey: api-key
remoteRef:
key: secret/myapp
property: api_key
Использование в Deployment:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-app-secret
key: db-password
CrowdSec
IDS/IPS система обнаружения вторжений. Анализирует логи ingress-nginx. Подробнее: addons/crowdsec/README.md.
addon_crowdsec: true
crowdsec_nginx_bouncer_enabled: true # блокировать IP через nginx
Vaultwarden
Self-hosted менеджер паролей (Bitwarden-совместимый). Подробнее: addons/vaultwarden/README.md.
addon_vaultwarden: true
vaultwarden_domain: "https://vault.example.com"
vaultwarden_signups_allowed: false
Общие рекомендации
Network Policies (Calico/Cilium)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-nginx
namespace: my-app
spec:
podSelector:
matchLabels:
app: my-app
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- port: 8080
Pod Security Standards
# Namespace с restricted policy:
apiVersion: v1
kind: Namespace
metadata:
name: secure-app
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
Non-root контейнеры
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]