Перейти к основному содержимому
Вернуться в категорию

Безопасность Docker: Усиление защиты контейнерной среды

Лучшие практики безопасности Docker: пользователь без root, файловая система только для чтения, профили seccomp, сканирование образов, безопасность Docker socket, сетевая изоляция и управление секретами.

Время чтения: 17 dk Контейнеры и оркестрация
dockerбезопасностьконтейнерseccompapparmorсканирование образовсекретыусиление

Содержание

Безопасность Docker: Усиление защиты контейнерной среды

Docker-контейнеры в конфигурации по умолчанию могут содержать множество уязвимостей. Контейнеры, работающие от root, чрезмерно привилегированные контейнеры и небезопасные образы представляют серьёзные риски. В этом руководстве мы рассмотрим безопасность Docker послойно.

1. Запуск от имени пользователя без root

Самая фундаментальная мера безопасности: запуск контейнеров от имени пользователя без root.

Определение пользователя в Dockerfile

hljs dockerfile
# Плохая практика — запуск от root
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

# Хорошая практика — пользователь без root
FROM node:20

# Создать пользователя и группу
RUN groupadd -r appgroup && useradd -r -g appgroup appuser

WORKDIR /app
COPY --chown=appuser:appgroup . .
RUN npm ci --only=production

# Переключиться на пользователя без root
USER appuser

CMD ["node", "server.js"]

Указание пользователя во время выполнения

hljs bash
# Запустить с конкретным пользователем
docker run -d --user 1000:1000 myapp:latest

# Запустить с текущим пользователем
docker run -d --user $(id -u):$(id -g) myapp:latest

2. Файловая система только для чтения

hljs bash
# Запустить с корневой файловой системой только для чтения
docker run -d \
  --name myapp \
  --read-only \
  --tmpfs /tmp \
  --tmpfs /var/run \
  myapp:latest
hljs yaml
# docker-compose.yml
services:
  app:
    image: myapp:latest
    read_only: true
    tmpfs:
      - /tmp
      - /var/run
    volumes:
      - app-logs:/app/logs

3. Управление capabilities

hljs bash
# Удалить все capabilities, добавить только необходимые
docker run -d \
  --name myapp \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  myapp:latest

# НИКОГДА не использовать привилегированный режим
# docker run --privileged myapp  # ПЛОХАЯ ПРАКТИКА
hljs yaml
services:
  app:
    image: myapp:latest
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
      - CHOWN

4. Профили Seccomp

hljs bash
# Запустить с профилем seccomp по умолчанию (рекомендуется)
docker run -d --security-opt seccomp=default myapp:latest

# Пользовательский профиль seccomp
docker run -d \
  --security-opt seccomp=/path/to/seccomp-profile.json \
  myapp:latest

5. Безопасность Docker-образов

Безопасные практики Dockerfile

hljs dockerfile
# Минимальный образ с многоэтапной сборкой
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# Production-образ — минимальный
FROM node:20-alpine

# Применить обновления безопасности
RUN apk update && apk upgrade && apk add --no-cache dumb-init

# Пользователь без root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules

USER appuser

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1

ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]

Сканирование образов

hljs bash
# Сканирование с Trivy (рекомендуется)
docker run --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy:latest image myapp:latest

# Только критические и высокие уязвимости
docker run --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy:latest image \
  --severity CRITICAL,HIGH \
  myapp:latest

6. Безопасность Docker Socket

hljs bash
# Монтировать Docker socket только для чтения (для мониторинга)
docker run -d \
  --name monitoring \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  monitoring-app:latest

# НИКОГДА не монтировать Docker socket в production-контейнерах!

7. Управление секретами

hljs bash
# Использовать Docker secrets (режим Swarm)
echo "StrongPass123!" | docker secret create db_password -

docker service create \
  --name myapp \
  --secret db_password \
  myapp:latest
# Секрет доступен по пути /run/secrets/db_password

8. Сетевая безопасность

hljs bash
# Открывать только необходимые порты
docker run -d \
  --name myapp \
  -p 127.0.0.1:8080:8080 \
  myapp:latest

9. Лимиты ресурсов

hljs bash
# Лимиты CPU и памяти
docker run -d \
  --name myapp \
  --memory 512m \
  --memory-swap 512m \
  --cpus 1.0 \
  --pids-limit 100 \
  myapp:latest

10. Безопасность Docker Daemon

hljs json
// /etc/docker/daemon.json
{
  "icc": false,
  "no-new-privileges": true,
  "userns-remap": "default",
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Заключение

Безопасность Docker требует многоуровневого подхода. Начните с пользователя без root, файловой системы только для чтения, минимальных capabilities и сканирования образов. Никогда не передавайте секреты как переменные окружения, не монтируйте Docker socket без необходимости и защищайтесь от DoS-атак с помощью лимитов ресурсов. С этими мерами безопасности на серверах REXE вы можете обеспечить безопасность контейнерной инфраструктуры.