📚 docs(security): Add comprehensive Security chapter
## New Security Documentation Structure
/security/
├── README.md # Security overview & contacts
├── forensics-checklist.md # Incident investigation guide
├── persistence-scan.sh # Quick persistence detector
├── runtime-detector.sh # Mining/suspicious process detector
└── hardening/
├── docker.md # Docker security baseline
├── kubernetes.md # K8s policies (future reference)
└── cloud.md # Hetzner-specific hardening
## Key Components
### Forensics Checklist
- Process analysis commands
- Persistence mechanism detection
- Network connection analysis
- File system inspection
- Authentication audit
- Decision matrix for threat response
### Scripts
- persistence-scan.sh: Cron, systemd, executables, SSH keys
- runtime-detector.sh: Mining process detection with --kill option
### Hardening Guides
- Docker: Secure compose template, Dockerfile best practices
- Kubernetes: NetworkPolicy, PodSecurityStandard, Falco rules
- Cloud: Egress firewall, SSH hardening, fail2ban, monitoring
## Post-Incident Documentation
Based on lessons learned from Incidents #1 and #2 (Jan 2026)
Co-authored-by: Cursor Agent <agent@cursor.sh>
This commit is contained in:
316
security/hardening/kubernetes.md
Normal file
316
security/hardening/kubernetes.md
Normal file
@@ -0,0 +1,316 @@
|
||||
# ☸️ Kubernetes Security Hardening — DAARION
|
||||
|
||||
**Версія:** 1.0.0
|
||||
**Статус:** Reference (для майбутньої K8s міграції)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Критичні налаштування
|
||||
|
||||
### 1. NetworkPolicy (Egress deny-by-default)
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: default-deny-egress
|
||||
namespace: daarion
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress: [] # Deny all outbound by default
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-dns-only
|
||||
namespace: daarion
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
name: kube-system
|
||||
ports:
|
||||
- protocol: UDP
|
||||
port: 53
|
||||
```
|
||||
|
||||
### 2. PodSecurityStandard: Restricted
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: daarion
|
||||
labels:
|
||||
pod-security.kubernetes.io/enforce: restricted
|
||||
pod-security.kubernetes.io/audit: restricted
|
||||
pod-security.kubernetes.io/warn: restricted
|
||||
```
|
||||
|
||||
### 3. Secure Pod Template
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: secure-pod
|
||||
namespace: daarion
|
||||
spec:
|
||||
# Security Context (Pod level)
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
fsGroup: 1001
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
# Service Account
|
||||
serviceAccountName: minimal-sa
|
||||
automountServiceAccountToken: false
|
||||
|
||||
containers:
|
||||
- name: app
|
||||
image: your-image:tag
|
||||
|
||||
# Security Context (Container level)
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
# Resource limits (CRITICAL for anti-mining)
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
limits:
|
||||
cpu: "1000m" # Max 1 CPU
|
||||
memory: "512Mi"
|
||||
|
||||
# Liveness/Readiness probes
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
|
||||
# Volume mounts (if needed)
|
||||
volumeMounts:
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
- name: cache
|
||||
mountPath: /app/cache
|
||||
|
||||
# Temporary volumes
|
||||
volumes:
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
sizeLimit: 64Mi
|
||||
- name: cache
|
||||
emptyDir:
|
||||
sizeLimit: 128Mi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Security Policies
|
||||
|
||||
### ResourceQuota (Namespace limits)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: daarion-quota
|
||||
namespace: daarion
|
||||
spec:
|
||||
hard:
|
||||
requests.cpu: "10"
|
||||
requests.memory: 20Gi
|
||||
limits.cpu: "20"
|
||||
limits.memory: 40Gi
|
||||
pods: "50"
|
||||
```
|
||||
|
||||
### LimitRange (Default limits)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: LimitRange
|
||||
metadata:
|
||||
name: daarion-limits
|
||||
namespace: daarion
|
||||
spec:
|
||||
limits:
|
||||
- type: Container
|
||||
default:
|
||||
cpu: "500m"
|
||||
memory: "256Mi"
|
||||
defaultRequest:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
max:
|
||||
cpu: "2"
|
||||
memory: "1Gi"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Runtime Detection (Falco)
|
||||
|
||||
### Falco Rule: Crypto Mining Detection
|
||||
|
||||
```yaml
|
||||
# falco-rules.yaml
|
||||
- rule: Detect Crypto Mining Process
|
||||
desc: Detect processes commonly used for cryptocurrency mining
|
||||
condition: >
|
||||
spawned_process and
|
||||
(proc.name in (xmrig, minerd, cpuminer, cgminer, bfgminer, ethminer,
|
||||
catcal, softirq, vrarhpb, G4NQXBp) or
|
||||
proc.cmdline contains "stratum+" or
|
||||
proc.cmdline contains "pool" or
|
||||
proc.cmdline contains "cryptonight")
|
||||
output: >
|
||||
Crypto mining process detected
|
||||
(user=%user.name command=%proc.cmdline container=%container.name
|
||||
image=%container.image.repository)
|
||||
priority: CRITICAL
|
||||
tags: [cryptomining, mitre_execution]
|
||||
|
||||
- rule: Detect Connection to Mining Pool
|
||||
desc: Detect outbound connections to known mining pool ports
|
||||
condition: >
|
||||
outbound and
|
||||
(fd.sport in (3333, 5555, 7777, 14433, 45700, 45560, 14444, 9999))
|
||||
output: >
|
||||
Connection to potential mining pool
|
||||
(user=%user.name command=%proc.cmdline connection=%fd.name
|
||||
container=%container.name)
|
||||
priority: CRITICAL
|
||||
tags: [cryptomining, network]
|
||||
|
||||
- rule: High CPU in Container
|
||||
desc: Detect containers with sustained high CPU usage
|
||||
condition: >
|
||||
container and
|
||||
container.cpu.usage > 80
|
||||
output: >
|
||||
High CPU usage in container
|
||||
(container=%container.name cpu=%container.cpu.usage%)
|
||||
priority: WARNING
|
||||
tags: [performance, cryptomining]
|
||||
```
|
||||
|
||||
### Falco Deployment
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: falco
|
||||
namespace: falco
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: falco
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: falco
|
||||
spec:
|
||||
serviceAccountName: falco
|
||||
containers:
|
||||
- name: falco
|
||||
image: falcosecurity/falco:latest
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- name: proc
|
||||
mountPath: /host/proc
|
||||
readOnly: true
|
||||
- name: rules
|
||||
mountPath: /etc/falco/rules.d
|
||||
volumes:
|
||||
- name: proc
|
||||
hostPath:
|
||||
path: /proc
|
||||
- name: rules
|
||||
configMap:
|
||||
name: falco-rules
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring & Alerting
|
||||
|
||||
### Prometheus Rules
|
||||
|
||||
```yaml
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PrometheusRule
|
||||
metadata:
|
||||
name: daarion-security-rules
|
||||
namespace: monitoring
|
||||
spec:
|
||||
groups:
|
||||
- name: security
|
||||
rules:
|
||||
- alert: HighCPUUsage
|
||||
expr: >
|
||||
sum(rate(container_cpu_usage_seconds_total{namespace="daarion"}[5m]))
|
||||
by (pod) > 0.8
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "High CPU usage in pod {{ $labels.pod }}"
|
||||
|
||||
- alert: UnauthorizedNetworkConnection
|
||||
expr: >
|
||||
increase(falco_events_total{rule=~".*mining.*"}[5m]) > 0
|
||||
for: 1m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Potential crypto mining detected"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ K8s Security Checklist
|
||||
|
||||
Before deploying to Kubernetes:
|
||||
|
||||
- [ ] Namespace has PodSecurityStandard: restricted
|
||||
- [ ] NetworkPolicy: deny egress by default
|
||||
- [ ] All pods have resource limits
|
||||
- [ ] All pods run as non-root
|
||||
- [ ] All pods have readOnlyRootFilesystem
|
||||
- [ ] All pods drop ALL capabilities
|
||||
- [ ] seccompProfile: RuntimeDefault
|
||||
- [ ] No privileged containers
|
||||
- [ ] ServiceAccount tokens not auto-mounted
|
||||
- [ ] Falco or similar runtime detection deployed
|
||||
- [ ] Resource quotas set on namespace
|
||||
Reference in New Issue
Block a user