Доступ к логам хоста при включённом SELinux
Научимся читать логи всех контейнеров, запущенных на ноде, при активном SELinux.
Монтирование логов
Запустим под и подмонтируем логи контейнеров из хоста:
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
Пробуем листинг каталога:
# ls -lah /var/log/containers
Если нет SELinux или он неактивен, то команда выполнится успешно. Иначе будет ошибка Permission denied.
SELinux
В Oracle Linux каталоги, содержащие логи контейнеров, имеют тип container_log_t:
# 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
# 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
которому разрешён доступ на чтение к логам
# 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:
spec:
containers:
- name: logreader
securityContext:
seLinuxOptions:
type: container_logreader_t
...
inotify
Некоторые программы (например, Crowdsec) устанавливают наблюдение за изменениями файловой системы (inotify watch).
На момент написания статьи в OracleLinux у container_logreader_t нет таких прав:
# inotifywatch /var/log/containers/c1/log
Establishing watches...
Failed to watch /var/log/containers/c1/log: Permission denied
Напишем свою политику - container-log-watch.te:
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 };
Скомпилируем:
# checkmodule -M -m -o container-log-watch.mod container-log-watch.te
# semodule_package -o container-log-watch.pp -m container-log-watch.mod
и применим:
# semodule -i container-log-watch.pp