June 11, 2025

Модуль 11: DevSecOps — Безопасность в DevOps

Курс DevOps для новичков 2025


🔒 Что такое DevSecOps?

DevSecOps — это эволюция DevOps, которая интегрирует безопасность на каждом этапе разработки и эксплуатации. Вместо того чтобы думать о безопасности в конце, DevSecOps делает её частью повседневного процесса разработки.

По данным исследований 2025 года, более 85% инцидентов безопасности связаны с неправильной конфигурацией компонентов и недостаточной защитой в CI/CD пайплайнах. DevSecOps решает эти проблемы через автоматизацию проверок безопасности.


🎯 Принцип "Shift Left Security"

Shift Left означает перенос проверок безопасности как можно раньше в цикле разработки:

  • Анализ кода на этапе написания
  • Автоматические проверки при commit
  • Сканирование зависимостей при сборке
  • Тестирование безопасности в CI/CD
  • Мониторинг безопасности в продакшне

Преимущества Shift Left

Снижение затрат — исправление уязвимостей на раннем этапе в 100 раз дешевле
Быстрая обратная связь — разработчики получают уведомления о проблемах сразу
Повышение качества — безопасность становится частью культуры разработки


⚠️ Основные угрозы безопасности

OWASP Top 10 — критичные уязвимости 2025

  1. Broken Access Control — нарушения контроля доступа
  2. Cryptographic Failures — криптографические сбои
  3. Injection — SQL, NoSQL, OS injection атаки
  4. Insecure Design — небезопасный дизайн приложения
  5. Security Misconfiguration — неправильная конфигурация
  6. Vulnerable Components — уязвимые компоненты
  7. Authentication Failures — сбои аутентификации
  8. Software Integrity Failures — нарушения целостности ПО
  9. Logging Failures — недостаточное логирование
  10. Server-Side Request Forgery — SSRF атаки

🔐 Безопасность в CI/CD пайплайне

Многоуровневая защита пайплайна

# .github/workflows/security.yml
name: Security Checks

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    # 1. Сканирование секретов в коде
    - name: Scan for secrets
      uses: trufflesecurity/trufflehog@main
      with:
        path: ./
        base: ${{ github.event.repository.default_branch }}
        head: HEAD

    # 2. Статический анализ кода (SAST)
    - name: Run CodeQL Analysis
      uses: github/codeql-action/init@v2
      with:
        languages: javascript, python

    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

    # 3. Сканирование зависимостей (SCA)
    - name: Run Snyk to check vulnerabilities
      uses: snyk/actions/node@master
      env:
        SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
      with:
        args: --severity-threshold=high

    # 4. Проверка Docker образа
    - name: Build Docker image
      run: docker build -t myapp:${{ github.sha }} .

    - name: Scan Docker image with Trivy
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: 'myapp:${{ github.sha }}'
        format: 'sarif'
        output: 'trivy-results.sarif'

    - name: Upload Trivy results
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: 'trivy-results.sarif'

    # 5. Проверка Infrastructure as Code
    - name: Run Checkov on Terraform
      uses: bridgecrewio/checkov-action@master
      with:
        directory: terraform/
        framework: terraform
        output_format: sarif
        output_file_path: checkov-report.sarif

    - name: Upload Checkov results
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: checkov-report.sarif

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

Никогда не храните секреты в коде!

Проблемы хранения секретов в коде:

  • Утечка через публичные репозитории
  • Доступ к секретам всех разработчиков
  • Сложность ротации паролей
  • Отсутствие аудита доступа

HashiCorp Vault — централизованное управление

# Установка Vault
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/

# Запуск Vault в dev режиме (только для обучения!)
vault server -dev

# Сохранение секрета
vault kv put secret/myapp/db \
    password="super-secret-password" \
    username="dbuser"

# Получение секрета
vault kv get secret/myapp/db

# Получение только пароля
vault kv get -field=password secret/myapp/db

Интеграция Vault с приложениями

# Python приложение с Vault
import hvac
import os

def get_db_credentials():
    # Подключение к Vault
    client = hvac.Client(
        url=os.getenv('VAULT_URL', 'http://localhost:8200'),
        token=os.getenv('VAULT_TOKEN')
    )
    
    # Получение секретов
    response = client.secrets.kv.v2.read_secret_version(
        path='myapp/db'
    )
    
    credentials = response['data']['data']
    return credentials['username'], credentials['password']

# Использование в приложении
username, password = get_db_credentials()
db_url = f"postgresql://{username}:{password}@localhost:5432/myapp"

Kubernetes Secrets

# k8s-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  database-password: <base64-encoded-password>
  api-key: <base64-encoded-api-key>
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-password
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: api-key

🛡️ Сканирование контейнеров

Безопасный Dockerfile

# Используем минимальный базовый образ
FROM node:18-alpine

# Обновляем пакеты для устранения уязвимостей
RUN apk update && apk upgrade && \
    apk add --no-cache dumb-init && \
    rm -rf /var/cache/apk/*

# Создаем непривилегированного пользователя
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

# Устанавливаем рабочую директорию
WORKDIR /app

# Копируем только файлы зависимостей для кэширования
COPY package*.json ./

# Устанавливаем только production зависимости
RUN npm ci --only=production && \
    npm cache clean --force && \
    npm audit fix

# Копируем исходный код
COPY --chown=nextjs:nodejs . .

# Удаляем ненужные файлы
RUN rm -rf .git .gitignore README.md

# Переключаемся на непривилегированного пользователя
USER nextjs

# Используем init процесс для правильной обработки сигналов
ENTRYPOINT ["dumb-init", "--"]

# Указываем команду запуска
CMD ["npm", "start"]

# Открываем только необходимый порт
EXPOSE 3000

# Добавляем health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Добавляем метки для трекинга
LABEL org.opencontainers.image.source="https://github.com/user/repo"
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.created="2025-06-11"

Автоматическое сканирование с Trivy

# Сканирование локального образа
trivy image myapp:latest

# Сканирование с выводом только критических уязвимостей
trivy image --severity HIGH,CRITICAL myapp:latest

# Сканирование с сохранением в файл
trivy image --format json --output results.json myapp:latest

# Сканирование файловой системы
trivy fs .

# Сканирование Kubernetes манифестов
trivy config k8s/

# Сканирование Terraform файлов
trivy config terraform/

🛠️ Практические задания

Задание 11.1: Настройка security scanning в CI/CD

# 1. Создание проекта с уязвимостями для демонстрации
mkdir devsecops-demo
cd devsecops-demo

# 2. Создание package.json с уязвимыми зависимостями
cat > package.json << 'EOF'
{
  "name": "devsecops-demo",
  "version": "1.0.0",
  "dependencies": {
    "express": "4.16.0",
    "lodash": "4.17.4",
    "moment": "2.19.0"
  }
}
EOF

# 3. Создание простого приложения
cat > app.js << 'EOF'
const express = require('express');
const _ = require('lodash');
const moment = require('moment');

const app = express();
app.use(express.json());

// Уязвимый endpoint (SQL injection)
app.get('/user/:id', (req, res) => {
  const query = `SELECT * FROM users WHERE id = ${req.params.id}`;
  // Это уязвимо к SQL injection!
  res.json({ query, message: 'This is vulnerable!' });
});

// Секрет в коде (плохая практика)
const API_KEY = "sk-1234567890abcdef";
const DB_PASSWORD = "password123";

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
EOF

# 4. Создание GitHub Actions workflow (используйте пример выше)
mkdir -p .github/workflows
# Скопируйте security.yml из примера выше

Задание 11.2: Установка и настройка Vault

# 1. Установка Vault
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/

# 2. Создание конфигурации Vault
cat > vault-config.hcl << 'EOF'
storage "file" {
  path = "./vault-data"
}

listener "tcp" {
  address = "127.0.0.1:8200"
  tls_disable = true
}

ui = true
EOF

# 3. Инициализация Vault
vault server -config=vault-config.hcl &
export VAULT_ADDR='http://127.0.0.1:8200'

# Инициализация (сохраните ключи!)
vault operator init

# Разблокировка Vault (используйте 3 ключа из вывода init)
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>

# 4. Настройка секретов приложения
vault auth <root-token>

# Включение KV секретов
vault secrets enable -path=secret kv-v2

# Сохранение секретов
vault kv put secret/myapp/database \
    username="dbuser" \
    password="secure-password-123"

vault kv put secret/myapp/api \
    key="sk-secure-api-key-456" \
    url="https://api.example.com"

Задание 11.3: Сканирование безопасности

# 1. Установка инструментов сканирования
# Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# TruffleHog для поиска секретов
pip install truffleHog

# 2. Сканирование проекта
# Поиск секретов в Git истории
truffleHog --regex --entropy=False .

# Сканирование зависимостей
npm audit

# Сканирование Docker образа
docker build -t vulnerable-app .
trivy image vulnerable-app

# 3. Создание отчета безопасности
cat > security-scan.sh << 'EOF'
#!/bin/bash

echo "=== Security Scan Report ==="
echo "Date: $(date)"
echo

echo "=== Dependency Vulnerabilities ==="
npm audit --json > npm-audit.json
cat npm-audit.json | jq '.vulnerabilities | length'

echo "=== Secret Scanning ==="
truffleHog --regex --entropy=False . > secrets-report.txt
cat secrets-report.txt

echo "=== Container Scanning ==="
trivy image --format json vulnerable-app > container-scan.json
cat container-scan.json | jq '.Results[].Vulnerabilities | length'
EOF

chmod +x security-scan.sh
./security-scan.sh

Задание 11.4: Network Security в Kubernetes

# network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-netpol
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 8080
  - to: []  # DNS разрешение
    ports:
    - protocol: UDP
      port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-netpol
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432

🔍 Мониторинг безопасности

Falco для обнаружения аномалий

# falco-deployment.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco
  namespace: falco-system
spec:
  selector:
    matchLabels:
      app: falco
  template:
    metadata:
      labels:
        app: falco
    spec:
      serviceAccount: falco
      hostNetwork: true
      hostPID: true
      containers:
      - name: falco
        image: falcosecurity/falco:latest
        securityContext:
          privileged: true
        args:
          - /usr/bin/falco
          - --cri=/run/containerd/containerd.sock
          - --k8s-api=https://kubernetes.default:443
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: boot
          mountPath: /host/boot
        - name: lib-modules
          mountPath: /host/lib/modules
        - name: usr
          mountPath: /host/usr
        - name: etc
          mountPath: /host/etc
      volumes:
      - name: dev
        hostPath:
          path: /dev
      - name: proc
        hostPath:
          path: /proc
      - name: boot
        hostPath:
          path: /boot
      - name: lib-modules
        hostPath:
          path: /lib/modules
      - name: usr
        hostPath:
          path: /usr
      - name: etc
        hostPath:
          path: /etc

Пользовательские правила Falco

# custom-rules.yaml
- rule: Suspicious Network Activity
  desc: Detect suspicious network connections
  condition: >
    spawned_process and
    proc.name in (nc, ncat, netcat) and
    not proc.args contains "-l"
  output: >
    Suspicious network activity detected
    (user=%user.name command=%proc.cmdline container=%container.name)
  priority: WARNING

- rule: Unauthorized File Access
  desc: Detect access to sensitive files
  condition: >
    open_read and
    fd.name in (/etc/passwd, /etc/shadow, /etc/hosts) and
    not proc.name in (systemd, sshd)
  output: >
    Unauthorized access to sensitive file
    (user=%user.name file=%fd.name proc=%proc.name container=%container.name)
  priority: CRITICAL

📊 Compliance и аудит

CIS Kubernetes Benchmark

# Установка kube-bench
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml

# Просмотр результатов
kubectl logs job.batch/kube-bench

# Сохранение отчета
kubectl logs job.batch/kube-bench > cis-benchmark-report.txt

# Проверка соответствия с kube-score
kubectl score deployment.yaml

Policy as Code с Open Policy Agent

# security-policies.rego
package kubernetes.security

# Запрет запуска контейнеров от root
deny[msg] {
    input.kind == "Pod"
    input.spec.securityContext.runAsUser == 0
    msg := "Containers must not run as root user"
}

# Обязательное использование read-only root filesystem
deny[msg] {
    input.kind == "Pod"
    container := input.spec.containers[_]
    not container.securityContext.readOnlyRootFilesystem
    msg := sprintf("Container %s must have read-only root filesystem", [container.name])
}

# Запрет privileged контейнеров
deny[msg] {
    input.kind == "Pod"
    container := input.spec.containers[_]
    container.securityContext.privileged == true
    msg := sprintf("Container %s cannot run in privileged mode", [container.name])
}

# Обязательные resource limits
deny[msg] {
    input.kind == "Pod"
    container := input.spec.containers[_]
    not container.resources.limits.memory
    msg := sprintf("Container %s must have memory limits", [container.name])
}

# Запрет использования latest тегов
deny[msg] {
    input.kind == "Pod"
    container := input.spec.containers[_]
    endswith(container.image, ":latest")
    msg := sprintf("Container %s must not use 'latest' tag", [container.name])
}

📖 Полезные ресурсы

  • OWASP DevSecOps Guideline — практики безопасности в DevOps
  • NIST Cybersecurity Framework — стандарты кибербезопасности
  • CIS Controls — критичные контроли безопасности
  • YouTube: "DevSecOps: безопасность в CI/CD" — практические видеоуроки
  • Awesome DevSecOps — коллекция инструментов и ресурсов

✅ Чек-лист модуля

  • Понимаю принципы DevSecOps и Shift Left Security
  • Настроил автоматическое сканирование безопасности в CI/CD
  • Интегрировал проверку секретов с TruffleHog
  • Добавил сканирование зависимостей с Snyk
  • Настроил сканирование Docker образов с Trivy
  • Установил и настроил HashiCorp Vault
  • Создал безопасные Dockerfile согласно best practices
  • Настроил Network Policies в Kubernetes
  • Изучил мониторинг безопасности с Falco
  • Понимаю основы compliance и Policy as Code

🚀 Что дальше?

После освоения DevSecOps переходите к Финальному проекту, где объедините все изученные навыки для создания полноценной DevOps инфраструктуры с интегрированной безопасностью.