Skip to content

_apparmor

_apparmor

AppArmor profile helpers for the per-container dnsmasq DNS tier.

terok-shield runs a per-container dnsmasq whose config/pid/log live under the sandbox-live tasks/<project>/<task>/shield tree in the operator's home. Distros that ship an enforcing AppArmor profile for /usr/sbin/dnsmasq (Arch/Manjaro, the apparmor.d set) confine it to the conventional server paths and deny that tree, so shield falls back to the dig tier. This module detects that confinement and points the operator at the bundled installer that adds an addendum permitting the shield tree.

Detection is by file presence — unprivileged, no aa-status/root: an AppArmor-enabled host that has dnsmasq and a stock dnsmasq profile but no terok addendum is PROFILE_MISSING. Install is delegated to resources/apparmor/install_profile.sh — a short, auditable script run with sudo bash (no compilation, just apparmor_parser -r).

AppArmorStatus

Bases: Enum

Outcome of check_status.

NOT_APPLICABLE = 'not_applicable' class-attribute instance-attribute

No AppArmor, no dnsmasq, or no dnsmasq profile — nothing to do.

PROFILE_MISSING = 'profile_missing' class-attribute instance-attribute

dnsmasq is AppArmor-profiled but the terok addendum isn't installed.

OK = 'ok' class-attribute instance-attribute

The terok addendum is installed.

AppArmorCheckResult(status) dataclass

Structured outcome of check_status.

status instance-attribute

is_apparmor_enabled()

Return True if the kernel has AppArmor enabled (sysfs Y).

Source code in src/terok_sandbox/_util/_apparmor.py
def is_apparmor_enabled() -> bool:
    """Return ``True`` if the kernel has AppArmor enabled (sysfs ``Y``)."""
    try:
        return _APPARMOR_ENABLED.read_text().strip() == "Y"
    except OSError:
        return False

check_status()

Evaluate whether the dnsmasq AppArmor addendum is needed or installed.

File-based and unprivileged: an AppArmor-enabled host with dnsmasq and a stock dnsmasq profile but no terok addendum is PROFILE_MISSING; everything else is NOT_APPLICABLE or OK.

Source code in src/terok_sandbox/_util/_apparmor.py
def check_status() -> AppArmorCheckResult:
    """Evaluate whether the dnsmasq AppArmor addendum is needed or installed.

    File-based and unprivileged: an AppArmor-enabled host with dnsmasq and
    a stock dnsmasq profile but no terok addendum is ``PROFILE_MISSING``;
    everything else is ``NOT_APPLICABLE`` or ``OK``.
    """
    if not is_apparmor_enabled() or shutil.which("dnsmasq") is None:
        return AppArmorCheckResult(AppArmorStatus.NOT_APPLICABLE)
    profile = _dnsmasq_profile()
    if profile is None:
        return AppArmorCheckResult(AppArmorStatus.NOT_APPLICABLE)
    if _addendum_installed(profile):
        return AppArmorCheckResult(AppArmorStatus.OK)
    return AppArmorCheckResult(AppArmorStatus.PROFILE_MISSING)

install_script_path() cached

Return the path to the bundled install_profile.sh AppArmor installer.

Installation is delegated to this short, inspectable shell script — run with sudo bash <path> <state_root> — so it can be cat-ed and audited before the privilege escalation.

Source code in src/terok_sandbox/_util/_apparmor.py
@lru_cache(maxsize=1)
def install_script_path() -> Path:
    """Return the path to the bundled ``install_profile.sh`` AppArmor installer.

    Installation is delegated to this short, inspectable shell script —
    run with ``sudo bash <path> <state_root>`` — so it can be ``cat``-ed
    and audited before the privilege escalation.
    """
    return Path(str(_resource_files("terok_sandbox.resources.apparmor") / "install_profile.sh"))

install_command(state_root)

Return the sudo bash <script> <state_root> installer invocation.

state_root is the sandbox-live root whose tasks/*/*/shield tree the rendered profile must permit. The caller supplies it because the script runs under sudo and cannot resolve the operator's home.

Source code in src/terok_sandbox/_util/_apparmor.py
def install_command(state_root: Path) -> str:
    """Return the ``sudo bash <script> <state_root>`` installer invocation.

    *state_root* is the sandbox-live root whose ``tasks/*/*/shield`` tree
    the rendered profile must permit.  The caller supplies it because the
    script runs under ``sudo`` and cannot resolve the operator's home.
    """
    return f"sudo bash {install_script_path()} {state_root}"