Безопасность k3s: NetworkPolicy, Pod Security и шифрование Secrets

Безопасность k3s: NetworkPolicy, Pod Security и шифрование Secrets

Компактная установка k3s не делает кластер безопасным автоматически. Дистрибутив включает ряд защитных настроек, но не усиливает операционную систему за администратора, не определяет доверие между приложениями и не решает, кому нужен доступ к Kubernetes API. Рабочая защита строится слоями: Linux-хосты, сеть, control plane, RBAC, политики Pod, NetworkPolicy, секреты, журналирование и восстановление.

Изменения ниже способны остановить несовместимые workloads. Сначала применяйте их в тестовом кластере, фиксируйте текущую конфигурацию и готовьте откат. Ориентируйтесь на руководство hardening именно для установленной ветки k3s: параметры Kubernetes меняются между версиями.

1. Защитите Linux до запуска Kubernetes

K3s работает с высокими системными привилегиями, поэтому компрометация узла опаснее компрометации обычного приложения. Минимизируйте установленные пакеты, включите автоматическое получение уведомлений об обновлениях, используйте отдельные административные учётные записи и SSH-ключи, запретите прямой root-вход. Доступ к SSH и Kubernetes API разрешайте только из управляющего VLAN или VPN.

Синхронизация времени необходима для журналов и сертификатов. Настройте мониторинг заполнения диска, памяти, нагрузки и состояния systemd-службы. Не устанавливайте на control-plane случайные панели, CI runners и пользовательские приложения: они увеличивают поверхность атаки и конкурируют с datastore за ресурсы.

Где разместить проект

Для сайтов, ботов и pet-проектов можно использовать Beget: виртуальный хостинг от 420 ₽/мес., VPS от 330 ₽/мес. и тестовый период.

Перейти на Beget →

2. Ограничьте сетевые порты

TCP 6443 нужен узлам и администраторам, но не всему интернету. UDP 8472 стандартного Flannel VXLAN должен быть доступен только между узлами: официальная документация прямо предупреждает, что его публикация наружу открывает кластерную сеть. Порты etcd 2379–2380 разрешайте только между server-узлами. Метрики kubelet на 10250 также не являются публичным сервисом.

Разместите узлы в серверном VLAN и создайте на граничном маршрутизаторе минимальные разрешающие правила. Локальный firewall на Linux оставьте включённым, но сверьте правила с выбранным CNI: бессистемная фильтрация overlay-трафика приводит к трудно диагностируемым сбоям.

3. Включите шифрование Secrets at rest

Объекты Secret закодированы base64, но без дополнительной настройки не считаются зашифрованными в datastore. При первой установке k3s можно включить:

# /etc/rancher/k3s/config.yaml
secrets-encryption: true

Для поддерживаемых новых версий доступен выбор провайдера, включая secretbox. Не копируйте параметр из случайной статьи: сначала проверьте version gate в официальной документации. На всех server-узлах критичные настройки шифрования должны совпадать.

Шифрование datastore не отменяет RBAC: пользователь с разрешением читать Secret через API увидит его содержимое. Оно защищает прежде всего резервные копии и украденный файл базы от прямого чтения. Ключи и server token резервируйте отдельно и защищайте не слабее самой базы.

4. Настройте RBAC по ролям

Не раздавайте файл /etc/rancher/k3s/k3s.yaml разработчикам: он обычно содержит административный доступ. Создавайте отдельные группы и RoleBinding для namespace. Разработчику приложения могут быть нужны просмотр Deployment и журналов, но не чтение Secret, изменение ClusterRole или доступ к другим командам.

Регулярно ищите избыточные привязки:

kubectl get clusterrolebindings
kubectl get rolebindings -A
kubectl auth can-i --list --as=developer@example.com -n payments
kubectl auth can-i get secrets --as=developer@example.com -n payments

Последняя команда для обычного разработчика чаще должна вернуть no. Сервисным аккаунтам выдавайте минимальные права и не монтируйте API-токен в Pod, которому он не нужен: задавайте automountServiceAccountToken: false.

5. Включите Pod Security Admission

Pod Security Standards определяют профили Privileged, Baseline и Restricted. Для нового прикладного namespace разумно стремиться к Restricted, но сначала включить режимы warn и audit, чтобы увидеть несовместимости. Системные namespace и некоторые инфраструктурные компоненты могут требовать отдельных правил.

Пример меток для тестового namespace:

kubectl label namespace demo 
  pod-security.kubernetes.io/enforce=restricted 
  pod-security.kubernetes.io/enforce-version=latest 
  pod-security.kubernetes.io/audit=restricted 
  pod-security.kubernetes.io/warn=restricted

В воспроизводимой среде не полагайтесь на ручную команду: храните Namespace с метками в Git. Версию политики в production лучше закрепить на проверенной версии Kubernetes, чтобы обновление не изменило требования неожиданно.

6. Усильте SecurityContext

Приложение должно запускаться непривилегированным пользователем, без повышения привилегий и с минимальным набором Linux capabilities. Типовая основа контейнера:

securityContext:
  allowPrivilegeEscalation: false
  runAsNonRoot: true
  capabilities:
    drop:
      - ALL
  seccompProfile:
    type: RuntimeDefault

На уровне Pod добавьте runAsNonRoot и по возможности read-only root filesystem. Но не копируйте UID наугад: образ должен действительно поддерживать непривилегированный запуск и записывать данные только в разрешённые тома.

7. Запретите сетевой обмен по умолчанию

Без NetworkPolicy скомпрометированный Pod часто может обращаться к другим сервисам в namespace и соседним приложениям. Начните с default deny для входящего и исходящего трафика:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: demo
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

После применения DNS и внешние API перестанут работать, пока не появятся разрешающие политики. Добавляйте их по фактической схеме: frontend → backend:8080, backend → database:5432, workloads → CoreDNS, приложение → конкретный внешний сервис. Проверяйте, что выбранный CNI действительно реализует NetworkPolicy и что bundled network policy controller не отключён.

Не разрешайте весь egress только ради быстрого исправления. Временно зафиксируйте исключение, определите необходимые назначения и сузьте правило. Политики тестируйте из реального Pod, а не только с узла.

8. Защитите образы и цепочку поставки

Не используйте плавающий тег latest. Закрепляйте образ по версии, а для критичных workloads — по digest. Проверяйте образы сканером уязвимостей, удаляйте компиляторы и пакетные менеджеры из runtime-слоя, формируйте SBOM и обновляйте базовые образы по контролируемому процессу.

Ограничьте реестры, из которых разрешено развёртывание. Пароль imagePullSecret не должен быть общим для всей организации и иметь право публикации, если кластеру требуется только чтение.

9. Audit log и наблюдаемость

Системный журнал k3s показывает состояние службы, но для расследования нужен Kubernetes audit log: кто и когда создал RoleBinding, прочитал Secret или изменил Deployment. Руководство CIS для k3s приводит параметры audit policy, пути журнала, ротации и admission plugins. Политику выбирайте осознанно: слишком подробный аудит быстро заполнит диск и может записать чувствительные данные.

Отправляйте важные события на отдельный сервер, где злоумышленник с узла не сможет легко стереть историю. Настройте оповещения на создание ClusterRoleBinding, запуск privileged Pod, изменение NetworkPolicy, массовые ошибки авторизации и отключение журналирования.

10. Резервные копии и проверка восстановления

Для embedded etcd настройте регулярные snapshots, срок хранения и копирование за пределы кластера. Отдельно резервируйте PersistentVolume и внешние базы приложений. Snapshot Kubernetes не содержит автоматически все пользовательские данные.

Минимум раз в квартал поднимайте из копии изолированный кластер, сверяйте объекты, запускайте приложение и проверяйте бизнес-данные. RPO и RTO должны быть измеряемыми: «копия выполняется ночью» не отвечает на вопрос, сколько данных будет потеряно и за какое время сервис вернётся.

Порядок внедрения

  1. Инвентаризировать узлы, версии, открытые порты и администраторов.
  2. Закрыть API, overlay и etcd от недоверенных сетей.
  3. Настроить обновления, SSH, мониторинг и резервное копирование Linux.
  4. Включить Secrets encryption и проверить резервирование ключей.
  5. Разделить доступ RBAC и убрать общий admin kubeconfig.
  6. Включить Pod Security сначала в warn/audit, затем enforce.
  7. Ввести NetworkPolicy по одному приложению с тестами.
  8. Настроить audit log и регулярное восстановление.

Документация

Хотите системно изучить программирование?

Подборка онлайн-курсов для разработчиков — Python, Java, веб и DevOps.

Смотреть курсы →

Бесплатные инструменты

Калькулятор подсетей · SSH-конфиг · Nginx · Docker Compose

Нужно настроить сервер, сайт или автоматизацию?

Разберём задачу по VPS/Linux, DNS, WordPress, Telegram-ботам и интеграциям. Стоимость определяется после оценки объёма.

Обсудить задачу → 8 918 532 81 08

Статья может содержать партнёрские ссылки. Это не влияет на стоимость для вас, но помогает развивать блог.