docs: полная документация проекта — docs/ и README.md для каждого аддона
- 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 уже существовали)
This commit is contained in:
284
docs/security.md
Normal file
284
docs/security.md
Normal file
@@ -0,0 +1,284 @@
|
||||
# Безопасность
|
||||
|
||||
Стек безопасности: HashiCorp Vault, External Secrets Operator, CrowdSec, Vaultwarden.
|
||||
|
||||
## HashiCorp Vault
|
||||
|
||||
Централизованное управление секретами, PKI, динамические credentials. Подробный README: [addons/vault/README.md](../addons/vault/README.md).
|
||||
|
||||
### Быстрый старт
|
||||
|
||||
```yaml
|
||||
# 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
|
||||
```
|
||||
|
||||
```bash
|
||||
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`:
|
||||
```yaml
|
||||
vault_auto_unseal_type: "k8s"
|
||||
vault_auto_unseal_k8s_shares: 5
|
||||
vault_auto_unseal_k8s_threshold: 3
|
||||
```
|
||||
|
||||
### HA режим (3 ноды, Raft)
|
||||
|
||||
```yaml
|
||||
vault_mode: "ha"
|
||||
vault_ha_replicas: 3
|
||||
vault_auto_unseal_type: "k8s" # обязателен для HA
|
||||
```
|
||||
|
||||
### Инициализация (первый запуск)
|
||||
|
||||
После установки Ansible автоматически:
|
||||
1. Инициализирует Vault (`vault operator init`)
|
||||
2. Сохраняет ключи unseal в Secret (при `vault_auto_unseal_type: k8s`)
|
||||
3. Unseals Vault
|
||||
4. Выводит root token
|
||||
|
||||
### Vault Agent Injector — инжекция секретов в поды
|
||||
|
||||
```yaml
|
||||
# Аннотации на 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
|
||||
|
||||
```bash
|
||||
# Включить 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 секретами
|
||||
|
||||
```yaml
|
||||
# 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](../addons/external-secrets/README.md).
|
||||
|
||||
### Быстрый старт
|
||||
|
||||
```yaml
|
||||
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`:
|
||||
```yaml
|
||||
vault_eso_approle_secret_id: "xxx"
|
||||
```
|
||||
|
||||
### Создать AppRole в Vault
|
||||
|
||||
```bash
|
||||
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 — синхронизировать секрет
|
||||
|
||||
```yaml
|
||||
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:
|
||||
```yaml
|
||||
env:
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: my-app-secret
|
||||
key: db-password
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CrowdSec
|
||||
|
||||
IDS/IPS система обнаружения вторжений. Анализирует логи ingress-nginx. Подробнее: [addons/crowdsec/README.md](../addons/crowdsec/README.md).
|
||||
|
||||
```yaml
|
||||
addon_crowdsec: true
|
||||
crowdsec_nginx_bouncer_enabled: true # блокировать IP через nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vaultwarden
|
||||
|
||||
Self-hosted менеджер паролей (Bitwarden-совместимый). Подробнее: [addons/vaultwarden/README.md](../addons/vaultwarden/README.md).
|
||||
|
||||
```yaml
|
||||
addon_vaultwarden: true
|
||||
vaultwarden_domain: "https://vault.example.com"
|
||||
vaultwarden_signups_allowed: false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Общие рекомендации
|
||||
|
||||
### Network Policies (Calico/Cilium)
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
# 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 контейнеры
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
containers:
|
||||
- securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: [ALL]
|
||||
```
|
||||
Reference in New Issue
Block a user