Поделиться через


Доступ к ресурсам контейнера безопасности с помощью встроенных функций безопасности Linux

В этой статье вы узнаете, как защитить доступ к контейнерам к ресурсам для рабочих нагрузок Служба Azure Kubernetes (AKS).

Обзор

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

Встроенные контексты безопасности pod Kubernetes можно использовать для определения дополнительных разрешений, таких как пользователь или группа для запуска от имени, возможности Linux для предоставления или настройки allowPrivilegeEscalation: false в манифесте pod. Другие советы см. в разделе Secure pod access to resources (Обеспечение безопасного доступа pod к ресурсам).

Для более детального управления действиями контейнера можно использовать встроенные функции безопасности Linux, такие как AppArmor и seccomp.

  1. Определите функции безопасности Linux на уровне узла.
  2. Реализуйте функции с помощью манифеста pod.

Встроенные функции безопасности Linux доступны только на узлах и POD под управлением Linux.

Примечание.

В настоящее время среды Kubernetes не полностью безопасны для враждебного мультитенантного использования. Дополнительные функции безопасности, такие как Microsoft Defender для контейнеров, AppArmor, seccomp, прием безопасности pod или RBAC Kubernetes для узлов, эффективно блокируют эксплойты.

Для истинной безопасности при выполнении враждебных мультитенантных рабочих нагрузок доверяйте только гипервизору. Домен безопасности для Kubernetes становится целым кластером, а не отдельным узлом.

Для таких типов враждебных мультитенантных рабочих нагрузок следует использовать физически изолированные кластеры.

AppArmor

Чтобы ограничить действия контейнеров, можно использовать модуль безопасности ядра Linux AppArmor. AppArmor доступен в составе базовой ОС узла AKS и включен по умолчанию. Вы создаете профили AppArmor, которые ограничивают действия чтения, записи и выполнения, а также системные функции, такие как подключение файловых систем. Профили AppArmor по умолчанию ограничивают доступ к различным /proc расположениям и /sys предоставляют средства для логического изоляции контейнеров от базового узла. AppArmor работает с любыми приложениями под управлением Linux, а не только с группами pod Kubernetes.

Профили AppArmor, использующиеся в кластере AKS для ограничения действий контейнера

Чтобы увидеть AppArmor в действии, в следующем примере создается профиль, который запрещает запись в файлы.

  1. Подключитесь к узлу AKS по протоколу SSH.

  2. Создайте файл с именем deny-write.profile.

  3. Скопируйте и вставьте следующее содержимое:

    #include <tunables/global>
    profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
      #include <abstractions/base>
    
      file,
      # Deny all file writes.
      deny /** w,
    }
    

Профили AppArmor добавляются с помощью команды apparmor_parser.

  1. Добавьте профиль в AppArmor.

  2. Укажите имя профиля, созданного на предыдущем шаге:

    sudo apparmor_parser deny-write.profile
    

    Если профиль правильно проанализирован и применен к AppArmor, вы не увидите выходные данные и вернетесь в командную строку.

  3. На локальном компьютере необходимо создать манифест pod с именем aks-apparmor.yaml. Этот манифест:

    • определяет заметку для container.apparmor.security.beta.kubernetes;
    • ссылается на профиль deny-write, созданный на предыдущих шагах.
    apiVersion: v1
    kind: Pod
    metadata:
      name: hello-apparmor
      annotations:
        container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write
    spec:
      containers:
      - name: hello
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
    
  4. При развертывании модуля pod выполните следующую команду и убедитесь , что модуль pod hello-apparmor отображает состояние "Выполнение ".

    kubectl get pods
    
    NAME             READY   STATUS    RESTARTS   AGE
    aks-ssh          1/1     Running   0          4m2s
    hello-apparmor   0/1     Running   0          50s
    

Дополнительные сведения об AppArmor см. в разделе AppArmor profiles in Kubernetes (Профили AppArmor в Kubernetes).

Безопасные вычисления (seccomp)

Несмотря на то, что AppArmor работает с любым приложением Linux, seccomp (secure computing, безопасные вычисления) работает на уровне процесса. Seccomp также является модулем безопасности ядра Linux и изначально поддерживается containerd средой выполнения, используемой узлами AKS. С помощью seccomp можно ограничить системные вызовы контейнера. Seccomp устанавливает дополнительный уровень защиты от распространенных уязвимостей вызова системы, эксплуатируемых вредоносными субъектами, и позволяет указать профиль по умолчанию для всех рабочих нагрузок в узле.

Настройка профиля seccomp по умолчанию (предварительная версия)

Вы можете применить профили seccomp по умолчанию с помощью пользовательских конфигураций узлов при создании пула узлов Linux. В AKS поддерживаются два значения: RuntimeDefault и Unconfined. Для некоторых рабочих нагрузок может потребоваться меньшее количество ограничений syscall, чем другие. Это означает, что они могут завершиться ошибкой во время выполнения с профилем RuntimeDefault. Чтобы устранить такой сбой, можно указать Unconfined профиль. Если для рабочей нагрузки требуется пользовательский профиль, см. раздел "Настройка настраиваемого профиля seccomp".

Ограничения

  • SeccompDefault не является поддерживаемым параметром для пулов узлов Windows.
  • SeccompDefault доступен начиная с 2024-09-02-preview API.

Внимание

Предварительные версии функций AKS доступны на уровне самообслуживания. Предварительные версии предоставляются "как есть" и "при наличии". На них не распространяются соглашения об уровне обслуживания и ограниченная гарантия. Предварительные версии AKS предоставляются с частичной клиентской поддержкой по мере возможности. Следовательно, эти функции не предназначены для использования в рабочей среде. Дополнительные сведения доступны в следующих статьях поддержки.

Регистрация флага компонента KubeletDefaultSeccompProfilePreview

  1. KubeletDefaultSeccompProfilePreview Зарегистрируйте флаг компонента с помощью az feature register команды.

    az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    

    Через несколько минут отобразится состояние Registered (Зарегистрировано).

  2. Проверьте состояние регистрации с помощью az feature show команды.

    az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    
  3. Когда состояние отражает зарегистрировано, обновите регистрацию поставщика ресурсов Microsoft.ContainerService с помощью az provider register команды.

    az provider register --namespace Microsoft.ContainerService
    

Ограничение системных вызовов контейнера с помощью seccomp

1. Выполните действия, чтобы применить профиль seccomp в конфигурации kubelet, указав "seccompDefault": "RuntimeDefault".

RuntimeDefault использует профиль seccomp по умолчанию контейнера, ограничивающий определенные системные вызовы для повышения безопасности. Ограниченные системные списки завершаются ошибкой. Дополнительные сведения см. в профиле seccomp по умолчанию containerD.

2. Проверьте, применена ли конфигурация.

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

3. Устранение неполадок с рабочими нагрузками.

Если параметр SeccompDefault включен, профиль среды выполнения контейнера по умолчанию используется по умолчанию для всех рабочих нагрузок, запланированных на узле. Это может привести к сбою рабочих нагрузок из-за заблокированных системных списков. Если произошел сбой рабочей нагрузки, могут появиться такие ошибки, как:

  • Рабочая нагрузка непредвиденная после включения функции с ошибкой "отказано в разрешении".
  • Сообщения об ошибках Seccomp также можно просмотреть в аудите или системном журнале, заменив SCMP_ACT_ERRNO на SCMP_ACT_LOG в профиле по умолчанию.

При возникновении указанных выше ошибок рекомендуется изменить профиль Unconfinedseccomp на . Unconfined не устанавливает ограничений на системные вызовы, позволяя всем системным вызовам, что снижает безопасность.

Настройка пользовательского профиля seccomp

С помощью настраиваемого профиля seccomp вы можете иметь более детализированный контроль над ограниченными syscalls. В соответствии с рекомендациями предоставления минимального разрешения контейнера только для запуска выполняются следующие действия.

  • Определение с помощью фильтров, какие действия разрешить или запретить.
  • Добавление заметок в манифест YAML модуля pod для связи с фильтром seccomp.

Чтобы увидеть seccomp в действии, создайте фильтр, который предотвращает изменение разрешений для файла.

  1. Подключитесь к узлу AKS по протоколу SSH.

  2. Создайте фильтр seccomp с именем /var/lib/kubelet/seccomp/prevent-chmod.

  3. Скопируйте и вставьте следующее содержимое:

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "name": "chmod",
          "action": "SCMP_ACT_ERRNO"
        },
        {
          "name": "fchmodat",
          "action": "SCMP_ACT_ERRNO"
        },
        {
          "name": "chmodat",
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    

    В версии 1.19 и более поздних версий необходимо настроить следующее:

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "names": ["chmod","fchmodat","chmodat"],
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    
  4. На локальном компьютере создайте манифест pod с именем aks-seccomp.yaml и вставьте следующее содержимое. Этот манифест:

    • определяет заметку для seccomp.security.alpha.kubernetes.io;
    • ссылается на фильтр prevent-chmod, созданный на предыдущем шаге.
    apiVersion: v1
    kind: Pod
    metadata:
      name: chmod-prevented
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod
    spec:
      containers:
      - name: chmod
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command:
          - "chmod"
        args:
         - "777"
         - /etc/hostname
      restartPolicy: Never
    

    В версии 1.19 и более поздних версий необходимо настроить следующее:

    apiVersion: v1
    kind: Pod
    metadata:
      name: chmod-prevented
    spec:
      securityContext:
        seccompProfile:
          type: Localhost
          localhostProfile: prevent-chmod
      containers:
      - name: chmod
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command:
          - "chmod"
        args:
         - "777"
         - /etc/hostname
      restartPolicy: Never
    
  5. Разверните пример pod с помощью команды kubectl apply.

    kubectl apply -f ./aks-seccomp.yaml
    
  6. Просмотрите состояние групп pod с помощью команды kubectl get pods.

    • Группа pod сообщает об ошибке.
    • Команда chmod не запускается фильтром seccomp, как показано в примере выходных данных:
    kubectl get pods
    
    NAME                      READY     STATUS    RESTARTS   AGE
    chmod-prevented           0/1       Error     0          7s
    

Параметры профиля безопасности Seccomp

Профили безопасности Seccomp — это набор определенных системныхcalls, которые разрешены или ограничены. Большинство сред выполнения контейнеров имеют профиль seccomp по умолчанию, аналогичный, если он не совпадает с используемым Docker. Дополнительные сведения о доступных профилях см. в разделе Docker или containerD default seccomp profiles.

AKS использует профиль seccomp по умолчанию containerD для среды выполненияDefault при настройке seccomp с помощью настраиваемой конфигурации узла.

Значительные системные списки, заблокированные по умолчанию

Docker и containerD поддерживают списки разрешений безопасных системных списков. В этой таблице перечислены значительные (но не все) syscalls, которые фактически блокируются, так как они не находятся в списке разрешений. Если для рабочей нагрузки требуются какие-либо заблокированные системные списки, не используйте RuntimeDefault профиль seccomp.

При внесении изменений в Docker и containerD AKS обновляет конфигурацию по умолчанию для сопоставления. Обновления этого списка могут привести к сбою рабочей нагрузки. Сведения об обновлениях выпуска см. в заметках о выпуске AKS.

Заблокированный syscall Description
acct Системный расчет, который может позволить контейнерам отключить собственные ограничения ресурсов или учет процессов. Кроме того, заготовка CAP_SYS_PACCT.
add_key Запретить контейнерам использовать ключ ядра, который не является пространством имен.
bpf Запретить загрузку потенциально постоянных программ bpf в ядро, уже зашитых CAP_SYS_ADMIN.
clock_adjtime Время и дата не пространству имен. Кроме того, заготовка CAP_SYS_TIME.
clock_settime Время и дата не пространству имен. Кроме того, заготовка CAP_SYS_TIME.
clone Запрет клонирования новых пространств имен. Кроме того, заготовка флагов CAP_SYS_ADMIN for CLONE_* , за исключением CLONE_NEWUSER.
create_module Запрет манипуляций и функций в модулях ядра. Является устаревшей. Кроме того, заготовка CAP_SYS_MODULE.
delete_module Запрет манипуляций и функций в модулях ядра. Кроме того, заготовка CAP_SYS_MODULE.
finit_module Запрет манипуляций и функций в модулях ядра. Кроме того, заготовка CAP_SYS_MODULE.
get_kernel_syms Запретить извлечение экспортированных символов ядра и модуля. Является устаревшей.
get_mempolicy Syscall, который изменяет память ядра и параметры NUMA. Уже воротили CAP_SYS_NICE.
init_module Запрет манипуляций и функций в модулях ядра. Кроме того, заготовка CAP_SYS_MODULE.
ioperm Запретить контейнерам изменять уровни привилегий ядра ввода-вывода. Уже воротили CAP_SYS_RAWIO.
iopl Запретить контейнерам изменять уровни привилегий ядра ввода-вывода. Уже воротили CAP_SYS_RAWIO.
kcmp Ограничить возможности проверки процесса, уже заблокированные путем удаления CAP_SYS_PTRACE.
kexec_file_load Сестра syscall kexec_load, которая делает то же самое, немного разные аргументы. Кроме того, заготовка CAP_SYS_BOOT.
kexec_load Запретить загрузку нового ядра для последующего выполнения. Кроме того, заготовка CAP_SYS_BOOT.
keyctl Запретить контейнерам использовать ключ ядра, который не является пространством имен.
lookup_dcookie Трассировка и профилирование syscall, которая может утечка информации на узле. Кроме того, заготовка CAP_SYS_ADMIN.
mbind Syscall, который изменяет память ядра и параметры NUMA. Уже воротили CAP_SYS_NICE.
mount Запретить подключение, уже заготовленное CAP_SYS_ADMIN.
move_pages Syscall, который изменяет память ядра и параметры NUMA.
nfsservctl Запретить взаимодействие с управляющей программой ядра nfs. Устаревшее с версии 3.1 Linux.
open_by_handle_at Причина разрыва старого контейнера. Кроме того, заготовка CAP_DAC_READ_SEARCH.
perf_event_open Трассировка и профилирование syscall, которая может утечка информации на узле.
personality Запретить контейнеру включить эмуляцию BSD. Не по сути опасно, но плохо протестирован, потенциал для виртуальных машин ядра.
pivot_root Запретить pivot_root должно быть привилегированной операцией.
process_vm_readv Ограничить возможности проверки процесса, уже заблокированные путем удаления CAP_SYS_PTRACE.
process_vm_writev Ограничить возможности проверки процесса, уже заблокированные путем удаления CAP_SYS_PTRACE.
ptrace Трассировка и профилирование syscall. Заблокировано в версиях ядра Linux до версии 4.8, чтобы избежать обхода seccomp. Трассировка и профилирование произвольных процессов уже заблокирована путем удаления CAP_SYS_PTRACE, так как она может утечка информации на узле.
query_module Запрет манипуляций и функций в модулях ядра. Является устаревшей.
quotactl Системный параметр квоты, который может позволить контейнерам отключить собственные ограничения ресурсов или учет процессов. Кроме того, заготовка CAP_SYS_ADMIN.
reboot Не позволяйте контейнерам перезагружать узел. Кроме того, заготовка CAP_SYS_BOOT.
request_key Запретить контейнерам использовать ключ ядра, который не является пространством имен.
set_mempolicy Syscall, который изменяет память ядра и параметры NUMA. Уже воротили CAP_SYS_NICE.
setns Запретить связывание потока с пространством имен. Кроме того, заготовка CAP_SYS_ADMIN.
settimeofday Время и дата не пространству имен. Кроме того, заготовка CAP_SYS_TIME.
stime Время и дата не пространству имен. Кроме того, заготовка CAP_SYS_TIME.
swapon Запретить переключение запуска и остановки на файл или устройство. Кроме того, заготовка CAP_SYS_ADMIN.
swapoff Запретить переключение запуска и остановки на файл или устройство. Кроме того, заготовка CAP_SYS_ADMIN.
sysfs Устаревший syscall.
_sysctl Устаревшее, замененное /proc/sys.
umount Должна быть привилегированной операцией. Кроме того, заготовка CAP_SYS_ADMIN.
umount2 Должна быть привилегированной операцией. Кроме того, заготовка CAP_SYS_ADMIN.
unshare Запрет клонирования новых пространств имен для процессов. Кроме того, за CAP_SYS_ADMINисключением unshare --user.
uselib Старый системный вызов, связанный с общими библиотеками, неиспользуемый в течение длительного времени.
userfaultfd Обработка ошибок страниц пользовательского пространства, в основном необходимая для миграции процессов.
ustat Устаревший syscall.
vm86 Виртуальная машина в режиме реального режима ядра x86. Кроме того, заготовка CAP_SYS_ADMIN.
vm86old Виртуальная машина в режиме реального режима ядра x86. Кроме того, заготовка CAP_SYS_ADMIN.

Следующие шаги

См. соответствующие рекомендации по обеспечению безопасности и обновлению кластера в AKS и обеспечению безопасности модулей pod в AKS.