Введение
Образы контейнеров — это фундаментальные элементы развертывания современных приложений, но при неправильной настройке и защите они могут создавать значительные риски для безопасности. В этом руководстве мы рассмотрим 10 распространенных уязвимостей, возникающих при создании и развертывании образов контейнеров, а также предложим практические решения и примеры.
1. Запуск контейнеров от имени пользователя root
Уязвимость
Запуск контейнеров с правами пользователя root дает избыточные разрешения, которые могут быть использованы в случае взлома контейнера.
Пример
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Решение
Создайте пользователя без прав root и переключитесь на него:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y nginx
# Create non-root user
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
RUN chown -R appuser:appgroup /var/www/html /var/log/nginx
USER appuser
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2. Использование последних версий тегов
Уязвимость
Использование тега :latest может привести к непредвиденным последствиям и проблемам с безопасностью, поскольку базовый образ может измениться без предупреждения.
Пример
FROM node:latest
COPY . /app
Решение
Используйте теги с указанием конкретной версии:
FROM node:16.14.2-slim
COPY . /app
3. Конфиденциальные данные в контексте сборки
Уязвимость
Включение конфиденциальных файлов в контекст сборки может привести к их отображению в слоях образа.
Пример
COPY . /app
RUN npm install
Решение
Используйте .dockerignore для исключения конфиденциальных файлов:
.env
*.key
*.pem
node_modules
.git
4. Устаревшие базовые образы
Уязвимость
Использование устаревших базовых образов с известными уязвимостями.
Пример
FROM debian:stretch
RUN apt-get update && apt-get install -y python
Решение
Используйте актуальные базовые образы и регулярно проводите сканирование:
FROM debian:bullseye-slim
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y python3
5. Ненужные пакеты
Уязвимость
Использование ненужных пакетов увеличивает поверхность атаки.
Пример
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
build-essential \
python3 \
vim \
curl \
wget
Решение
Используйте минимальные базовые образы и устанавливайте только необходимые пакеты:
FROM python:3.9-slim
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
6. Ненадежные источники пакетов
Уязвимость
Использование ненадежных или небезопасных источников пакетов может привести к внедрению вредоносного кода.
Пример
RUN curl -k https://untrusted-source.com/package.sh | bash
Решение
Проверяйте подписи пакетов и используйте безопасные источники:
# Add GPG key and verify package
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
RUN echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable" > /etc/apt/sources.list.d/docker.list
7. Раскрытие секретов в переменных среды
Уязвимость
Жесткое кодирование секретов в инструкциях ENV в Dockerfile приводит к их отображению в истории образов.
Пример
ENV AWS_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
ENV AWS_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Решение
Используйте аргументы сборки или переменные среды выполнения:
ARG AWS_ACCESS_KEY
ARG AWS_SECRET_KEY
RUN aws configure set aws_access_key_id $AWS_ACCESS_KEY && \
aws configure set aws_secret_access_key $AWS_SECRET_KEY
8. Ненадежные права доступа к файлам
Уязвимость
Неправильные права доступа к файлам могут привести к несанкционированному доступу к конфиденциальным данным.
Пример
COPY app.config /etc/app/
RUN chmod 777 /etc/app/app.config
Решение
Установите соответствующие разрешения:
COPY app.config /etc/app/
RUN chown appuser:appgroup /etc/app/app.config && \
chmod 600 /etc/app/app.config
9. Отсутствие проверок работоспособности
Уязвимость
Без проверок работоспособности контейнеры с ошибками могут продолжать работать.
Пример
FROM nginx:alpine
EXPOSE 80
Решение
Внедрите проверку работоспособности:
FROM nginx:alpine
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
10. Незашифрованные сообщения
Уязвимость
Использование незашифрованных протоколов для передачи конфиденциальных сообщений.
Пример
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Решение
Настройте SSL/TLS:
COPY ssl/cert.pem /etc/nginx/ssl/
COPY ssl/key.pem /etc/nginx/ssl/
COPY nginx-ssl.conf /etc/nginx/conf.d/default.conf
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
Рекомендации по развертыванию
- Всегда проверяйте изображения перед развертыванием:
# Using Trivy scanner
trivy image your-image:tag
- Внедряйте политики безопасности во время выполнения:
# Example SecurityContext in Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: your-secure-image:tag
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
- Используйте многоэтапные сборки, чтобы уменьшить размер итогового изображения:
# Build stage
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production stage
FROM node:16-slim
COPY --from=builder /app/dist /app
USER node
CMD ["node", "app/server.js"]
Заключение
Защита образов контейнеров требует внимания к деталям и соблюдения передовых методов обеспечения безопасности на всех этапах сборки и развертывания. Для поддержания высокого уровня безопасности необходимы регулярное сканирование, обновление и аудит.
Не забудьте:
- Регулярно обновляйте базовые образы и зависимости
- Внедряйте принцип наименьших привилегий
- Используйте многоэтапные сборки
- Проверяйте образы на наличие уязвимостей
- Внедряйте средства контроля безопасности во время выполнения
- Отслеживайте работу контейнеров в производственной среде