Содержание

Доступ к логам хоста при включённом SELinux

Научимся читать логи всех контейнеров, запущенных на ноде, при активном SELinux.

Запустим под и подмонтируем логи контейнеров из хоста:

yaml

apiVersion: v1
kind: Pod
metadata:
  name: logreader
spec:
  containers:
    - name: logreader
      image: debian
      command: ["sleep", "infinity"]
      volumeMounts:
        - name: container-logs
          mountPath: /var/log/containers
          readOnly: true
        - name: pod-logs
          mountPath: /var/log/pods
          readOnly: true
      volumes:
        - name: container-logs
          hostPath:
            path: /var/log/containers
        - name: pod-logs
          hostPath:
            path: /var/log/pods

Пробуем листинг каталога:

shell-session

# ls -lah /var/log/containers

Если нет SELinux или он неактивен, то команда выполнится успешно. Иначе будет ошибка Permission denied.

В Oracle Linux каталоги, содержащие логи контейнеров, имеют тип container_log_t:

shell-session

# ls -Z /var/log | grep container
    system_u:object_r:container_log_t:s0 containers
    system_u:object_r:container_log_t:s0 pods

В политике SELinux есть тип container_logreader_t

shell-session

# seinfo -acontainer_domain -x

Type Attributes: 1
   attribute container_domain;
        container_device_plugin_init_t
        container_device_plugin_t
        container_device_t
        container_engine_t
        container_init_t
        container_kvm_t
        container_logreader_t
        container_logwriter_t
        container_t
        container_userns_t

которому разрешён доступ на чтение к логам

shell-session

# sesearch -A --source=container_logreader_t --target=container_log_t
allow container_logreader_t logfile:dir { ioctl lock read };
allow container_logreader_t logfile:file { getattr ioctl lock map open read };

Соответственно, нужно запустить под в контексте container_logreader_t:

yaml

spec:
  containers:
    - name: logreader
      securityContext:
        seLinuxOptions:
          type: container_logreader_t
      ...

Некоторые программы (например, Crowdsec) устанавливают наблюдение за изменениями файловой системы (inotify watch). На момент написания статьи в OracleLinux у container_logreader_t нет таких прав:

shell-session

# inotifywatch /var/log/containers/c1/log
Establishing watches...
Failed to watch /var/log/containers/c1/log: Permission denied

Напишем свою политику - container-log-watch.te:

text

module container-log-watch 1.0;

require {
        type container_log_t;
        type container_logreader_t;
        class file { watch watch_reads };
        class dir { watch watch_reads };
}

#============= container_logreader_t ==============
allow container_logreader_t container_log_t:file { watch watch_reads };
allow container_logreader_t container_log_t:dir { watch watch_reads };

Скомпилируем:

shell-session

# checkmodule -M -m -o container-log-watch.mod container-log-watch.te
# semodule_package -o container-log-watch.pp -m container-log-watch.mod

и применим:

shell-session

# semodule -i container-log-watch.pp
  1. Minimally Privileged Containers in OpenShift — An Example using a Logging Agent
  2. K3S SELinux
  3. Troubleshooting problems related to SELinux
  4. How to modify the .te file generated by audit2allow and recompile it into .pp file
  5. [SELinux] kernel 5.4.x: No support for “watch”