Docker Apparmor

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску

Apparmor и Docker

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

Если вдруг по какой-то причине нужно исправить - то нужен грязный хак

  • забекапть оригинальный бинарник /usr/sbin/apparmor_parser
  • создать скрипт /usr/sbin/apparmor_parser_wrapper
  • создать симлинк apparmor_parser -> /usr/sbin/apparmor_parser_wrapper

По сути скрипт проверяет, а не докер ли пробует применить профиль (полагаясь на то что докер создает файл по опреденному пути /var/lib/docker/tmp/docker-default*** и если докер - то перекрывает профиль
Если же это не докер - то запускает как-есть Про аппармор (к которому тоже есть вопросы, например я не нашел способа как посмотреть уже загруженные правила)

Скрипт-обертка

#!/bin/bash

set -o pipefail
set -e

APPARMOR_PARSER="/usr/sbin/apparmor_parser.original"
DEFAUT_DOCKER_POLICY_FILE="/etc/docker/apparmor-defaut-policy"
TAG="apparmor_parser_wrapper"

echo "$*" 2>&1 | logger -t "[${TAG}]"


create_defaut_policy_file() {
    DEFAULT_POLICY=$(cat <<EOF
#include <tunables/global>


profile docker-default flags=(attach_disconnected,mediate_deleted) {

  #include <abstractions/base>


  network,
  capability,
  file,
  umount,

  # Host (privileged) processes may send signals to container processes.
  signal (receive) peer=unconfined,
  # dockerd may send signals to container processes (for "docker kill").
  signal (receive) peer=unconfined
,
  # Container processes may send signals amongst themselves.
  signal (send,receive) peer=docker-default,


  deny @{PROC}/* w,   # deny write for all files directly in /proc (not in a subdir)
  # deny write to files not in /proc/<number>/** or /proc/sys/**
  deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9]*}/** w,
  deny @{PROC}/sys/[^k]** w,  # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel)
  deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w,  # deny everything except shm* in /proc/sys/kernel/
  deny @{PROC}/sysrq-trigger rwklx,
  deny @{PROC}/kcore rwklx,

  deny mount,

  deny /sys/[^f]*/** wklx,
  deny /sys/f[^s]*/** wklx,
  deny /sys/fs/[^c]*/** wklx,
  deny /sys/fs/c[^g]*/** wklx,
  deny /sys/fs/cg[^r]*/** wklx,
  deny /sys/firmware/** rwklx,
  deny /sys/kernel/security/** rwklx,


  # suppress ptrace denials when using 'docker ps' or using 'ps' inside a container
  #ptrace (trace,read,tracedby,readby) peer=docker-default,
  # Allow ptrace
  ptrace (trace,read,tracedby,readby),

}
EOF
    )
    echo -e "${DEFAULT_POLICY}" > ${TMP_FILE}
    echo -e "${DEFAULT_POLICY}" 2>&1 | logger -t "[$TAG]"

}


if [ $# -eq 2 ]; then
    cat $2 >> /tmp/PROF
fi
echo $@ | grep -q "/var/lib/docker/tmp/docker-default" && {

    echo "DOCKER DETECTED, build-in policy will be overriden" | logger -t "[${TAG}]"

    if [[ -f "${DEFAUT_DOCKER_POLICY_FILE}" ]];
    then
        echo "Found defined default poicy: ${DEFAUT_DOCKER_POLICY_FILE}" | logger -t "[${TAG}]"
        ${APPARMOR_PARSER} -rK ${DEFAUT_DOCKER_POLICY_FILE} 2>&1 | logger -t "[]"
        exit $?
    else
        echo "Not found default policy in the docker configuration (${DEFAUT_DOCKER_POLICY_FILE})" | logger -t "[${TAG}]"
        TMP_FILE=$(mktemp)
        create_defaut_policy_file
        echo "Excecuting: ${APPARMOR_PARSER} -rK ${TMP_FILE} " 2>$1 | logger -t "[${TAG}]"
        ${APPARMOR_PARSER} -rK ${TMP_FILE} 2>&1 | logger -t "[${TAG}]"
        rm -f ${TMP_FILE} 2>&1 | logger -t "[${TAG}]"
        exit $?
    fi
} || {
    echo "NO DOCKER DETECTED, normal execution" | logger -t "[${TAG}]"
    echo "${APPARMOR_PARSER} $*" | logger -t "[${TAG}]"
    ${APPARMOR_PARSER} $*
}