MOON
Server: Apache
System: Linux vmi433716.contaboserver.net 3.10.0-1160.144.1.el7.tuxcare.els4.x86_64 #1 SMP Tue Apr 7 08:40:40 UTC 2026 x86_64
User: affpashacom (1022)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: //etc/apparmor.d/usr.local.bin.linux-sensor
# AppArmor profile for the LinuxMDM agent on Ubuntu/Debian hosts.
#
# DESIGN GOAL: limit damage from a hypothetical agent RCE, NOT block
# legitimate admin commands. The agent's whole job is to execute root
# commands on behalf of the panel, so blanket "no exec" would defeat
# the product. We instead:
#
#   1. Confine *writes* to the small set of paths the agent legitimately
#      needs (its own config, log, working dirs). Block writes to
#      /etc/shadow, /root/.ssh/authorized_keys, the kernel module dirs,
#      and other classic persistence targets — those should only ever
#      change via a *commanded* sub-process (which inherits an
#      unconfined profile by default).
#   2. Allow *reads* of everything system. Sysinfo and snapshot need
#      to enumerate hardware, packages, network state, etc.
#   3. Allow *exec* of system binaries (px) and signed agent binaries
#      (cx). Sub-processes spawn unconfined; if the agent invokes apt
#      or systemctl, those run with normal root capabilities.
#
# Loaded by postinstall.v2.sh on Ubuntu/Debian hosts when AppArmor is
# enforcing. RHEL/AlmaLinux/Rocky use SELinux instead — those distros
# get no AppArmor profile (an SELinux policy is future work).
#
# Verify after install:
#   sudo aa-status | grep linux-sensor
#   sudo grep DENIED /var/log/audit/audit.log | grep linux-sensor

#include <tunables/global>

profile linux-sensor /usr/local/bin/linux-sensor flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>
  #include <abstractions/openssl>
  #include <abstractions/nameservice>
  #include <abstractions/dbus>

  # ---- READ: open by default ------------------------------------------
  # sysinfo, snapshot, integrity check, recovery all need broad reads.
  # We don't list every path — `r` everywhere except sensitive write
  # targets which are explicitly denied below.
  / r,
  /** r,

  # /proc and /sys: read-only access to anything (top processes, NIC
  # state, TPM PCRs, capabilities).
  @{PROC}/** r,
  @{sys}/** r,

  # ---- WRITE: tight whitelist -----------------------------------------
  # Agent's own dirs
  /etc/linuxmdm/                                rw,
  /etc/linuxmdm/**                              rw,
  /var/lib/linuxmdm/                            rw,
  /var/lib/linuxmdm/**                          rwk,    # k = lock files
  /var/log/linuxmdm-*.log                       rw,
  /var/log/linuxmdm-*.cast                      rw,
  /var/cache/.systemd-units-cache.bin           rw,    # legacy backup path
  /var/cache/.systemd-fonts-cache.bin           rw,    # legacy backup path
  /usr/share/linuxmdm/                          rw,
  /usr/share/linuxmdm/**                        rw,
  /run/linuxmdm.pid                             rw,
  /tmp/linuxmdm.*                               rw,
  /tmp/legacy-cleanup.sh                        rw,

  # Self-update worker stages packages here
  /var/lib/linuxmdm/.selfupdate*                rw,
  /var/lib/linuxmdm/.liveness-nonce             rw,    # v2.0.33+

  # cron / preset / systemd unit drop-ins the postinstall manages
  /etc/cron.d/linux-sensor                      rw,
  /etc/systemd/system/linux-sensor.service.d/   rw,
  /etc/systemd/system/linux-sensor.service.d/** rw,
  /etc/systemd/system/multi-user.target.wants/  rw,
  /etc/systemd/system/sshd.service.d/           rw,
  /etc/systemd/system/sshd.service.d/**         rw,
  /etc/systemd/system/ssh.socket.d/             rw,
  /etc/systemd/system/ssh.socket.d/**           rw,

  # SSH recovery: agent writes/reads sshd config-d drop-ins + ssh keys
  /etc/ssh/sshd_config.d/                       rw,
  /etc/ssh/sshd_config.d/**                     rw,
  /home/mdm-recovery/                           rw,
  /home/mdm-recovery/**                         rw,
  /var/spool/cron/                              rw,
  /var/spool/cron/**                            rw,

  # Process-accounting + log files the agent reads/writes
  /var/log/wtmp                                 r,
  /var/log/btmp                                 r,
  /var/log/lastlog                              r,
  /var/log/auth.log                             r,

  # ---- EXPLICIT DENIES (defense-in-depth) ----------------------------
  # These would otherwise match the broad `r` rule, but we want them
  # un-writeable by the agent itself. Writes here SHOULD only come from
  # spawned sub-processes (apt, useradd, sshd) which inherit unconfined.
  deny /etc/shadow w,
  deny /etc/gshadow w,
  deny /etc/passwd w,
  deny /etc/group w,
  deny /etc/sudoers w,
  deny /etc/sudoers.d/** w,
  deny /root/.ssh/** w,
  deny /root/.bash* w,
  deny /lib/modules/** w,
  deny /boot/** w,
  deny /usr/bin/** w,
  deny /usr/sbin/** w,
  # /usr/local/bin/linux-sensor and watchdog are exceptions — the
  # self-update worker overwrites them. Specific allow follows.
  deny /usr/local/bin/** w,
  /usr/local/bin/linux-sensor                   rw,
  /usr/local/bin/linux-monitor                  rw,
  /usr/local/bin/linuxmdm-agent                 rw,    # v1.x compat
  /usr/local/bin/linuxmdm-watchdog              rw,    # v1.x compat

  # ---- EXEC ----------------------------------------------------------
  # px (-> profile_exec): try named-profile, otherwise inherit ours.
  # ix (-> inherit): same profile — for self / monitor.
  # Ux (-> unconfined): child runs without AppArmor.
  #
  # We use Ux for /usr/bin/* /usr/sbin/* /bin/* /sbin/* because the
  # agent legitimately spawns dpkg/apt/yum/systemctl/etc. to fulfil
  # admin commands. The agent's confinement is the perimeter; once a
  # sub-process spawns it's expected to need full root capabilities.
  /bin/* Ux,
  /sbin/* Ux,
  /usr/bin/* Ux,
  /usr/sbin/* Ux,
  /usr/local/bin/* Ux,
  /usr/local/sbin/* Ux,
  /lib/systemd/systemd-* Ux,
  /usr/libexec/** Ux,
  /opt/**/bin/* Ux,

  # Self-spawn (death-notifier, watchdog respawn) inherits this profile
  /usr/local/bin/linux-sensor ix,
  /usr/local/bin/linux-monitor ix,

  # ---- NETWORK -------------------------------------------------------
  # Outbound HTTPS to the panel, plus DNS. UDP for ICMP socket and
  # whatever the boot-attestation reader needs. We don't gate by hostname
  # at AppArmor level (it doesn't see DNS); restriction is done by the
  # baked-in PANEL_URL + CA pinning at the application layer.
  network inet stream,
  network inet6 stream,
  network inet dgram,
  network inet6 dgram,
  network netlink raw,
  network unix stream,
  network unix dgram,

  # ---- Capabilities --------------------------------------------------
  # The agent runs as root and needs:
  #   - cap_net_admin for iptables/firewall punch on recovery setup
  #   - cap_linux_immutable for chattr +i on its own binaries
  #   - cap_sys_admin for the BPF tamper-protect program load
  #   - cap_bpf (kernel 5.8+) for BPF program load and ringbuf reads
  #   - cap_dac_read_search for reading restricted dirs (e.g. /root)
  #   - cap_setuid / cap_setgid for spawning workers as different uids
  capability net_admin,
  capability net_raw,
  capability linux_immutable,
  capability sys_admin,
  capability sys_resource,
  capability sys_ptrace,
  capability dac_read_search,
  capability dac_override,
  capability fowner,
  capability fsetid,
  capability chown,
  capability setuid,
  capability setgid,
  capability kill,
  capability sys_chroot,
  capability mknod,
  capability sys_module,
  capability syslog,
  capability bpf,
  capability perfmon,
  capability sys_rawio,

  # ---- IPC -----------------------------------------------------------
  # Talks to its watchdog via signals + a death-notify FIFO sometimes.
  signal send peer=linux-monitor,
  signal receive peer=linux-monitor,
  signal send peer=unconfined,    # agent kill-signals to user procs
  signal receive,
}