# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2022-2024 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only

abi <abi/3.0>,

include <tunables/global>

@{exec_path} = @{bin}/dockerd
profile dockerd @{exec_path} flags=(attach_disconnected) {
  include <abstractions/base>
  include <abstractions/bus-system>
  include <abstractions/nameservice-strict>
  include <abstractions/ssl_certs>

  capability chown,
  capability dac_override,
  capability dac_read_search,
  capability fowner,
  capability fsetid,
  capability kill,
  capability mknod,
  capability net_admin,
  capability setfcap,
  capability sys_admin,
  capability sys_chroot,
  capability sys_ptrace,

  network inet dgram,
  network inet6 dgram,
  network inet stream,
  network inet6 stream,
  network netlink raw,

  mount /var/lib/docker/overlay2/**/,
  mount options=(rw, bind) -> /run/docker/netns/*,
  mount options=(rw, rbind) -> /var/lib/docker/tmp/docker-builder@{int}/,
  mount options=(rw, rprivate) -> /.pivot_root@{int}/,
  mount options=(rw, rslave) -> /,

  umount /.pivot_root@{int}/,
  umount /run/docker/netns/*,
  umount /var/lib/docker/overlay*/**/,

  pivot_root oldroot=/var/lib/docker/overlay*/**/.pivot_root@{int}/ /var/lib/docker/overlay2/**/,
  pivot_root oldroot=/var/lib/docker/tmp/**/.pivot_root@{int}/ /var/lib/docker/tmp/**/,

  ptrace (read) peer=docker-*,
  ptrace (read) peer=unconfined,

  signal (send) set=int peer=docker-proxy,
  signal (send) set=kill peer=docker-*,
  signal (send) set=term peer=containerd,

  @{exec_path} mrix,

  @{bin}/apparmor_parser         rPx,
  @{bin}/containerd              rPx,
  @{bin}/docker-init             rix,
  @{bin}/docker-proxy            rPx,
  @{bin}/kmod                    rPx,
  @{bin}/ps                      rPx,
  @{bin}/runc                    rUx,
  @{bin}/unpigz                  rix,
  @{bin}/xtables-nft-multi       rix,

  # Docker needs full access of the containers it manages.
  # TODO: should be in a sub profile started with pivot_root, not supported yet.
  /{,**} rwl,

  owner @{lib}/docker/overlay2/*/work/{,**} rw,
  owner /var/lib/docker/{,**} rwk,
  owner /var/lib/docker/tmp/qemu-check@{int}/check rix,

  @{sys}/fs/cgroup/cgroup.controllers r,
  @{sys}/fs/cgroup/cpuset.cpus.effective r,
  @{sys}/fs/cgroup/cpuset.mems.effective r,
  @{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r,
  @{sys}/kernel/security/apparmor/profiles r,
  @{sys}/module/apparmor/parameters/enabled r,

        @{PROC}/1/cgroup r,
        @{PROC}/1/environ r,
        @{PROC}/cmdline r,
        @{PROC}/sys/kernel/keys/root_maxkeys r,
        @{PROC}/sys/kernel/osrelease r,
        @{PROC}/sys/kernel/threads-max r,
        @{PROC}/sys/net/bridge/bridge-nf-call-ip*tables r,
        @{PROC}/sys/net/core/somaxconn r,
        @{PROC}/sys/net/ipv{4,6}/conf/all/disable_ipv{4,6} rw,
        @{PROC}/sys/net/ipv{4,6}/conf/docker@{int}/accept_ra rw,
        @{PROC}/sys/net/ipv{4,6}/ip_forward rw,
        @{PROC}/sys/net/ipv{4,6}/ip_local_port_range r,
  owner @{PROC}/@{pids}/attr/current r,
  owner @{PROC}/@{pids}/cgroup r,
  owner @{PROC}/@{pids}/fd/ r,
  owner @{PROC}/@{pids}/mountinfo r,
  owner @{PROC}/@{pids}/net/ip_tables_names r,
  owner @{PROC}/@{pids}/uid_map r,

  include if exists <local/dockerd>
}

# vim:syntax=apparmor
