Контейнерные технологии кардинально изменили подход к разработке и развертыванию приложений, но одновременно с этим создали новый спектр угроз безопасности. В 2024 году исследователи зафиксировали критическое увеличение атак на контейнерную инфраструктуру, при этом каждый третий инцидент связан именно с компрометацией образов контейнеров. Современные хакеры научились маскировать вредоносный код под легитимные обновления популярных образов, что делает эти атаки особенно опасными.
Масштабы угрозы: статистика 2024 года
Согласно исследованиям компании GitGuardian, проведенным в ноябре 2024 года, анализ 200,000 публично доступных образов Docker выявил 30,000 уникальных секретов, скрытых в 19,000 образах - это составляет 10% от всего исследованного датасета. Еще более тревожным является факт, что 1,200 секретов (4%) оказались активными и проверяемыми, некоторые из которых оставались действительными более года.
Исследование Sysdig Threat Research Team показало еще более масштабную картину: анализ свыше 250,000 Linux-образов на Docker Hub выявил 1,652 образа, содержащих вредоносный контент. Наибольшую категорию составили криптомайнеры (608 образов), за которыми следуют образы с встроенными секретами (281 случай).
Компания JFrog обнаружила еще более шокирующие данные: приблизительно 20% всех публичных репозиториев (почти три миллиона репозиториев!) фактически размещали вредоносный контент. Контент варьировался от простого спама, продвигающего пиратский контент, до крайне вредоносных сущностей, таких как вредоносное ПО и фишинговые сайты.
Критические уязвимости: анализ "Leaky Vessels"
CVE-2024-21626: Уязвимость побега из контейнера
Самой критической угрозой 2024 года стала группа уязвимостей "Leaky Vessels", включающая четыре CVE с наивысшими оценками CVSS. CVE-2024-21626 с оценкой 8.6 CVSS позволяет злоумышленникам полностью покинуть изолированную среду контейнера и получить доступ к файловой системе хоста.
Уязвимость возникает из-за утечки файловых дескрипторов в runc версии ≤1.1.11. Злоумышленники могут манипулировать рабочим каталогом (process.cwd) только что созданного процесса контейнера, что позволяет процессу получить доступ к файловой системе хоста.
Техническая механика эксплуатации:
# Вредоносный Dockerfile
WORKDIR /proc/self/fd/8
RUN echo "Container escape achieved" > /host/proof.txt
Эта простая команда может привести к полному компрометированию хоста, поскольку файловый дескриптор /proc/self/fd/8 обычно указывает на каталог /sys/fs/cgroup в файловой системе хоста.
CVE-2024-23651, CVE-2024-23652, CVE-2024-23653: Уязвимости BuildKit
Три дополнительные уязвимости затрагивают BuildKit ≤0.12.4:
- CVE-2024-23651: Состояние гонки между двумя вредоносными шагами сборки может привести к доступу к файлам хост-системы
- CVE-2024-23652: Позволяет потенциально удалять произвольные файлы на хосте во время создания образа
- CVE-2024-23653: Неправильная проверка прав в Interactive Containers API может привести к побегу из контейнера
Современные инструменты безопасности контейнеров
Trivy: Универсальный сканер безопасности
Trivy от Aqua Security стал стандартом индустрии для сканирования уязвимостей контейнеров. Инструмент поддерживает:
Базовое использование:
# Сканирование образа
trivy image nginx:1.24-alpine
# Сканирование файловой системы
trivy fs /path/to/project
# Сканирование репозитория Git
trivy repo https://github.com/example/repo
# Сканирование с выводом в JSON
trivy image --format json --output results.json nginx:1.24-alpine
Расширенные возможности 2024:
- Kubernetes-манифесты: Проверка конфигураций на соответствие лучшим практикам безопасности
- Infrastructure as Code: Сканирование Terraform, CloudFormation, ARM templates
- SBOM-поддержка: Генерация Software Bill of Materials в форматах SPDX и CycloneDX
- Лицензионная совместимость: Выявление потенциальных лицензионных нарушений
Настройка с игнорированием ложных срабатываний:
# .trivyignore
CVE-2023-12345 # Ложное срабатывание - исправлено в патче
CVE-2023-54321 # Принято как приемлемый риск для dev-среды
Grype: Специализированный сканер от Anchore
Grype предлагает высокую точность с минимальным количеством ложных срабатываний:
Основные команды:
# Сканирование локального образа
grype docker:nginx:1.24-alpine
# Сканирование с использованием Docker socket
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
anchore/grype:latest docker:nginx:1.24-alpine
# Сканирование SBOM
grype sbom:path/to/sbom.json
# Сканирование с фильтрацией по серьезности
grype nginx:1.24-alpine --fail-on critical
Интеграция с CI/CD:
# GitHub Actions
name: Container Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Grype vulnerability scanner
uses: anchore/scan-action@v3
with:
image: "myapp:${{ github.sha }}"
fail-build-on: critical
severity-cutoff: high
Harbor: Корпоративный реестр с интегрированной безопасностью
Harbor как корпоративное решение для управления образами предоставляет:
Ключевые функции безопасности:
- Интегрированное сканирование: Автоматическое сканирование с помощью Trivy по умолчанию
- Подпись образов: Использование Cosign для гарантии подлинности
- Политики развертывания: Предотвращение загрузки образов с критическими уязвимостями
- RBAC: Детализированное управление доступом на основе ролей
Конфигурация политики безопасности:
# harbor-security-policy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: harbor-security-policy
namespace: harbor-system
data:
policy.yaml: |
policies:
- name: "Block Critical CVEs"
enabled: true
action: "deny"
rule:
vulnerability:
severity: "critical"
- name: "Require Image Signature"
enabled: true
action: "deny"
rule:
signature:
required: true
Rootless-контейнеры: новый стандарт безопасности
Docker Rootless Mode
Docker Rootless Mode, полностью поддерживаемый с версии 20.10, кардинально улучшает безопасность:
Установка и настройка:
# Установка rootless Docker
curl -fsSL https://get.docker.com/rootless | sh
# Настройка переменных окружения
export PATH=/home/$USER/bin:$PATH
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
# Запуск daemon
systemctl --user enable docker
systemctl --user start docker
# Проверка статуса
systemctl --user status docker
docker context ls
Ограничения rootless режима:
- Невозможность привязки к привилегированным портам (<1024) без дополнительной настройки
- Ограниченные возможности сетевых драйверов (отсутствие overlay networks)
- Отсутствие поддержки некоторых storage drivers
- Производительность может быть ниже на 5-10% по сравнению с privileged режимом
Обход ограничения портов:
# Использование sysctl для unprivileged ports
echo 'net.ipv4.ip_unprivileged_port_start = 80' | sudo tee -a /etc/sysctl.conf
sudo sysctl --system
Podman: Безопасность по умолчанию
Podman предлагает rootless-контейнеры по умолчанию с дополнительными преимуществами безопасности:
Ключевые особенности:
- Daemonless-архитектура: Отсутствие центрального демона снижает поверхность атаки
- User namespaces: Изоляция пользователей контейнера от пользователей хоста
- SELinux-интеграция: Принудительное управление доступом
- Pod-поддержка: Совместимость с концепциями Kubernetes
Практическое использование:
# Создание rootless контейнера
podman run --rm -it alpine:3.18
# Создание пода (аналог Kubernetes)
podman pod create --name mypod -p 8080:80
podman run -d --pod mypod nginx:1.24-alpine
podman run -d --pod mypod redis:7-alpine
# Генерация Kubernetes YAML
podman generate kube mypod > mypod.yaml
# Управление системными сервисами
podman generate systemd --new --name mypod > mypod.service
Миграция с Docker на Podman:
# Создание alias для совместимости
echo 'alias docker=podman' >> ~/.bashrc
# Импорт образов из Docker
podman load -i $(docker save nginx:1.24-alpine)
# Работа с docker-compose через podman-compose
pip3 install podman-compose
podman-compose up -d
Безопасность Kubernetes: многоуровневая защита
Pod Security Standards
Kubernetes 1.25+ заменил Pod Security Policies на более простые Pod Security Standards:
Профили безопасности:
# namespace-security.yaml
apiVersion: v1
kind: Namespace
metadata:
name: secure-namespace
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
spec: {}
---
# Применение на уровне кластера
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-policy
namespace: kube-system
data:
policy: |
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
Три уровня безопасности:
- Privileged: Без ограничений (только для системных подов)
- Baseline: Минимальные ограничения, предотвращающие известные эскалации привилегий
- Restricted: Строго ограниченные политики, следующие лучшим практикам Pod hardening
Network Policies: сетевая сегментация
Детализированное управление сетевым трафиком:
# network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress: [] # Запрет всего входящего трафика по умолчанию
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
role: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
RBAC: Role-Based Access Control
Принцип минимальных привилегий:
# rbac-configuration.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: developer-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods/log", "pods/exec"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: development
subjects:
- kind: User
name: developer@company.com
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-role
apiGroup: rbac.authorization.k8s.io
---
# ClusterRole для чтения метрик
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: metrics-reader
rules:
- apiGroups: ["metrics.k8s.io"]
resources: ["nodes", "pods"]
verbs: ["get", "list"]
Лучшие практики безопасности контейнеров
Создание безопасных образов
Production-ready Dockerfile с security hardening:
# Используем конкретные теги и multi-stage build
FROM golang:1.21.5-alpine3.18 AS builder
# Установка security updates
RUN apk update && apk upgrade && apk add --no-cache git ca-certificates tzdata
# Создание non-root пользователя
RUN adduser -D -g '' appuser
WORKDIR /app
# Копирование dependency files сначала (для кэширования)
COPY go.mod go.sum ./
RUN go mod download
RUN go mod verify
# Копирование исходного кода
COPY . .
# Статическая компиляция с security flags
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -a -installsuffix cgo -ldflags='-w -s -extldflags "-static"' \
-o app .
# Финальный образ на основе distroless
FROM gcr.io/distroless/static:nonroot
# Копирование пользователя и сертификатов
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
# Копирование приложения
COPY --from=builder /app/app /app
# Использование non-root пользователя
USER nonroot:nonroot
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD ["/app", "healthcheck"]
# Metadata
LABEL maintainer="security-team@company.com" \
version="1.0.0" \
description="Secure microservice"
ENTRYPOINT ["/app"]
Управление секретами в production:
text# secure-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
namespace: production
annotations:
# Ротация секретов каждые 90 дней
secret-rotation.io/next-rotation: "2024-04-30"
type: Opaque
stringData:
database-url: "postgresql://user:pass@db:5432/app"
api-key: "super-secret-key"
jwt-secret: "jwt-signing-key"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
namespace: production
labels:
app: secure-app
version: v1.0.0
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: secure-app
template:
metadata:
labels:
app: secure-app
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65534 # nobody user
runAsGroup: 65534
fsGroup: 65534
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:1.0.0
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
- name: API_KEY
valueFrom:
secretKeyRef:
name: app-secrets
key: api-key
resources:
limits:
cpu: 500m
memory: 512Mi
ephemeral-storage: 1Gi
requests:
cpu: 250m
memory: 256Mi
ephemeral-storage: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: tmp
emptyDir:
sizeLimit: 100Mi
- name: cache
emptyDir:
sizeLimit: 200Mi
- name: secret-volume
secret:
secretName: app-secrets
defaultMode: 0400
nodeSelector:
kubernetes.io/arch: amd64
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- secure-app
topologyKey: kubernetes.io/hostname
tolerations:
- key: "app-tier"
operator: "Equal"
value: "production"
effect: "NoSchedule"
Runtime-безопасность с дополнительными политиками
Pod Disruption Budget для высокой доступности:
# pdb-configuration.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: secure-app-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: secure-app
---
# Resource Quota для namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
persistentvolumeclaims: "10"
pods: "50"
secrets: "20"
Мониторинг и обнаружение угроз
Falco: Runtime-безопасность с расширенными правилами
Настройка правил для обнаружения современных угроз:
# falco-security-rules.yaml
- rule: CVE-2024-21626 Container Escape Detection
desc: >
Detect CVE-2024-21626 exploitation attempts through
suspicious /proc/self/fd usage indicating container escape
condition: >
container and
((evt.type = execve and proc.cwd startswith "/proc/self/fd") or
(evt.type in (open, openat, openat2) and fd.name glob "/proc/*/cwd/*") or
(evt.type in (symlink, symlinkat) and fs.path.target startswith "/proc/self/fd/") or
(evt.type = chdir and evt.arg.path startswith "/proc/self/fd/"))
output: >
CRITICAL: CVE-2024-21626 container escape detected
(container=%container.name process=%proc.name pid=%proc.pid
command=%proc.cmdline cwd=%proc.cwd user=%user.name)
priority: CRITICAL
tags: [container_escape, cve-2024-21626, security]
- rule: Suspicious Container Network Activity
desc: Detect unusual network connections from containers
condition: >
container and evt.type = connect and
(fd.sip.name in (suspicious_domains) or
fd.dip in (crypto_mining_pools) or
(fd.sport in (reverse_shell_ports) or fd.dport in (reverse_shell_ports)))
output: >
WARNING: Suspicious network activity detected
(container=%container.name process=%proc.name
connection=%fd.sip:%fd.sport->%fd.dip:%fd.dport)
priority: WARNING
tags: [network, malware, cryptocurrency]
- rule: Crypto Mining Activity Detection
desc: Detect cryptocurrency mining processes in containers
condition: >
container and spawned_process and
(proc.name in (crypto_miners) or
proc.cmdline contains "stratum" or
proc.cmdline contains "xmrig" or
proc.cmdline contains "mining")
output: >
ALERT: Cryptocurrency mining detected
(container=%container.name process=%proc.name command=%proc.cmdline)
priority: HIGH
tags: [cryptocurrency, malware, mining]
- rule: Container Privileged Escalation
desc: Detect attempts to escalate privileges in containers
condition: >
container and evt.type in (setuid, setgid, setresuid, setresgid) and
evt.arg.uid = 0
output: >
CRITICAL: Privilege escalation attempt detected
(container=%container.name process=%proc.name user=%user.name->root)
priority: CRITICAL
tags: [privilege_escalation, security]
Интеграция Falco с системами оповещений:
# falco-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: falco-config
namespace: falco
data:
falco.yaml: |
json_output: true
json_include_output_property: true
http_output:
enabled: true
url: "http://falcosidekick:2801"
grpc:
enabled: true
bind_address: "0.0.0.0:5060"
grpc_output:
enabled: true
program_output:
enabled: true
keep_alive: false
program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
Интеграция с CI/CD: Comprehensive Security Pipeline
GitLab CI/CD с multi-stage security scanning:
# .gitlab-ci.yml
stages:
- build
- security-scan
- compliance-check
- deploy
variables:
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_DRIVER: overlay2
SECURE_REGISTRY: "$CI_REGISTRY/security"
before_script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
build:
stage: build
services:
- docker:24.4-dind
script:
- docker build --no-cache -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
artifacts:
reports:
dotenv: build.env
variables:
DOCKER_BUILDKIT: 1
trivy-vulnerability-scan:
stage: security-scan
image: aquasec/trivy:0.48.3
services:
- docker:24.4-dind
script:
- trivy image --exit-code 0 --format template --template "@contrib/sarif.tpl"
-o trivy-results.sarif $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- trivy image --exit-code 1 --severity HIGH,CRITICAL
$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
artifacts:
reports:
sast: trivy-results.sarif
expire_in: 1 week
allow_failure: false
grype-vulnerability-scan:
stage: security-scan
image: anchore/grype:v0.74.1
services:
- docker:24.4-dind
script:
- grype $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -o sarif > grype-results.sarif
- grype $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --fail-on critical
artifacts:
reports:
sast: grype-results.sarif
expire_in: 1 week
allow_failure: false
container-structure-test:
stage: security-scan
image: gcr.io/gcp-runtimes/container-structure-test:v1.16.0
script:
- container-structure-test test --image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--config container-structure-test.yaml
artifacts:
reports:
junit: test-results.xml
secret-scanning:
stage: security-scan
image: trufflesecurity/trufflehog:3.63.2
script:
- trufflehog docker --image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--json > secret-scan-results.json
- |
if [ -s secret-scan-results.json ]; then
echo "Secrets found in container image!"
cat secret-scan-results.json
exit 1
fi
artifacts:
reports:
sast: secret-scan-results.json
expire_in: 1 week
compliance-check:
stage: compliance-check
image: aquasec/kube-bench:v0.6.15
script:
- kube-bench run --config-dir /opt/kube-bench/cfg
--outputfile compliance-results.json --json
artifacts:
reports:
compliance: compliance-results.json
expire_in: 1 week
only:
- main
deploy-staging:
stage: deploy
needs:
- trivy-vulnerability-scan
- grype-vulnerability-scan
- container-structure-test
- secret-scanning
environment:
name: staging
url: https://staging.example.com
script:
- kubectl config use-context staging
- kubectl set image deployment/app container=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- kubectl rollout status deployment/app --timeout=300s
only:
- develop
deploy-production:
stage: deploy
needs:
- trivy-vulnerability-scan
- grype-vulnerability-scan
- container-structure-test
- secret-scanning
- compliance-check
environment:
name: production
url: https://app.example.com
script:
- kubectl config use-context production
- kubectl set image deployment/app container=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- kubectl rollout status deployment/app --timeout=600s
when: manual
only:
- main
Container Structure Test configuration:
# container-structure-test.yaml
schemaVersion: "2.0.0"
commandTests:
- name: "Check non-root user"
command: "whoami"
expectedOutput: ["nonroot"]
- name: "Verify application binary"
command: "ls"
args: ["-la", "/app"]
expectedOutput: ["-rwxr-xr-x.*app"]
fileExistenceTests:
- name: "Application binary exists"
path: "/app"
shouldExist: true
- name: "No package managers"
path: "/usr/bin/apt"
shouldExist: false
- name: "No shell access"
path: "/bin/sh"
shouldExist: false
metadataTest:
user: "nonroot"
workdir: "/"
exposedPorts: []
volumes: []
entrypoint: ["/app"]
Современные решения и тренды 2024-2025
Supply Chain Security с SLSA Framework
GitHub Actions с SLSA Level 3 attestation:
# .github/workflows/secure-build.yml
name: Secure Build with SLSA Attestation
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
build:
permissions:
id-token: write
contents: read
attestations: write
packages: write
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix=commit-
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate SLSA provenance
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
with:
image: ghcr.io/${{ github.repository }}
digest: ${{ steps.build.outputs.digest }}
registry-username: ${{ github.actor }}
registry-password: ${{ secrets.GITHUB_TOKEN }}
- name: Attest build provenance
uses: actions/attest-build-provenance@v1
with:
subject-name: ghcr.io/${{ github.repository }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
Zero Trust Container Security
Istio Service Mesh с comprehensive security policies:
# istio-zero-trust.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all-default
namespace: production
spec:
rules: [] # Deny all by default
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
selector:
matchLabels:
app: backend
rules:
- from:
- source:
principals: ["cluster.local/ns/production/sa/frontend-service"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/v1/*"]
when:
- key: request.headers[x-api-version]
values: ["v1"]
---
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: jwt-auth
namespace: production
spec:
selector:
matchLabels:
app: backend
jwtRules:
- issuer: "https://auth.company.com"
jwksUri: "https://auth.company.com/.well-known/jwks.json"
audiences:
- "backend-api"
forwardOriginalToken: true
---
# Workload Identity для подов
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-service
namespace: production
annotations:
iam.gke.io/gcp-service-account: backend-sa@project.iam.gserviceaccount.com
Advanced Threat Detection
OPA Gatekeeper policies для предотвращения атак:
# opa-security-policies.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredsecuritycontext
spec:
crd:
spec:
names:
kind: K8sRequiredSecurityContext
validation:
type: object
properties:
runAsNonRoot:
type: boolean
requiredDropCapabilities:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredsecuritycontext
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := "Container must run as non-root user"
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
required := input.parameters.requiredDropCapabilities
provided := container.securityContext.capabilities.drop
missing := required[_]
not missing in provided
msg := sprintf("Container must drop capability %v", [missing])
}
---
apiVersion: config.gatekeeper.sh/v1alpha1
kind: K8sRequiredSecurityContext
metadata:
name: must-have-security-context
spec:
match:
- apiGroups: ["apps"]
kinds: ["Deployment"]
namespaces: ["production", "staging"]
parameters:
runAsNonRoot: true
requiredDropCapabilities: ["ALL"]
Incident Response и Recovery
Автоматизированное реагирование на инциденты
Falco + Kubernetes Event Response:
# incident-response.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: incident-response-playbook
namespace: security
data:
response.sh: |
#!/bin/bash
INCIDENT_TYPE=$1
CONTAINER_NAME=$2
NAMESPACE=$3
case $INCIDENT_TYPE in
"container_escape")
echo "CRITICAL: Container escape detected in $CONTAINER_NAME"
# Немедленная изоляция пода
kubectl patch deployment $CONTAINER_NAME -n $NAMESPACE -p '{"spec":{"replicas":0}}'
# Создание network policy для блокировки трафика
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-$CONTAINER_NAME
namespace: $NAMESPACE
spec:
podSelector:
matchLabels:
app: $CONTAINER_NAME
policyTypes:
- Ingress
- Egress
EOF
;;
"crypto_mining")
echo "WARNING: Crypto mining detected in $CONTAINER_NAME"
# Ограничение CPU и уведомление
kubectl patch deployment $CONTAINER_NAME -n $NAMESPACE -p '{"spec":{"template":{"spec":{"containers":[{"name":"'$CONTAINER_NAME'","resources":{"limits":{"cpu":"100m"}}}]}}}}'
;;
esac
---
apiVersion: batch/v1
kind: Job
metadata:
name: security-incident-handler
namespace: security
spec:
template:
spec:
serviceAccountName: incident-responder
containers:
- name: handler
image: alpine/k8s:1.28.4
command: ["/bin/sh", "/scripts/response.sh"]
volumeMounts:
- name: scripts
mountPath: /scripts
volumes:
- name: scripts
configMap:
name: incident-response-playbook
defaultMode: 0755
restartPolicy: OnFailure
Заключение и практические рекомендации
Безопасность контейнерной инфраструктуры требует многоуровневого подхода и постоянного мониторинга. Основываясь на анализе современных угроз и лучших практик индустрии, рекомендуется следующий набор мер:
🛡️ Основные принципы защиты:
Defense in Depth (Глубокая защита):
- Image Security: Использование проверенных базовых образов, regular scanning
- Runtime Security: Непрерывный мониторинг поведения контейнеров
- Network Security: Микросегментация с Network Policies
- Identity Security: Строгое управление доступом через RBAC и Service Accounts
Zero Trust Architecture:
- Каждый запрос требует аутентификации и авторизации
- Минимальные привилегии для всех компонентов
- Continuous verification всех операций
- Encryption in transit и at rest для всех данных
⚡ Критически важные действия:
- Немедленно обновите runc до версии >1.1.12 для защиты от CVE-2024-21626
- Внедрите автоматизированное сканирование всех образов в CI/CD pipeline
- Используйте rootless контейнеры везде, где это технически возможно
- Настройте Pod Security Standards на уровне кластера с профилем "restricted"
- Реализуйте Network Policies с принципом "deny by default"
📊 Метрики для мониторинга безопасности:
- MTTR (Mean Time To Response): Время реакции на security инциденты <15 минут
- Vulnerability Coverage: 100% образов должны проходить сканирование
- Compliance Score: Соответствие security policies >95%
- False Positive Rate: <5% ложных срабатываний в системах обнаружения угроз
🎯 Roadmap развития безопасности:
Q1 2025:
- Полный переход на SLSA Level 3 для всех критических приложений
- Внедрение eBPF-based security мониторинга
- Integration с SIEM системами для централизованного анализа
Q2-Q3 2025:
- Adoption WebAssembly для изоляции критических workloads
- Machine Learning для обнаружения аномалий в поведении контейнеров
- Автоматизированный incident response с самовосстановлением
Контейнерная безопасность - это не одноразовая настройка, а непрерывный процесс адаптации к новым угрозам. Регулярный audit, обновление инструментов и обучение команды остаются ключевыми факторами успешной защиты современной инфраструктуры 🚀
Присоединяйтесь к нашему сообществу на канале Т.Е.Х.Н.О Windows & Linux! 💪 Ваша активность и обратная связь помогают нам создавать еще более качественный и актуальный контент по безопасности и системному администрированию.
#контейнеры #docker #kubernetes #безопасность #devops #cybersecurity #podman #trivy #grype #harbor #rootless #cve2024 #leakyvessels #devsecops #containerregistry #networksecurity #rbac #istio #zerotrust #supplychainsecurity #runtimesecurity #vulnerabilityscanning #containerescape #slsa #opa #gatekeeper #falco