Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
From 1b6a1a2c7836d3601b7af8ac453f9b89163eda3a Mon Sep 17 00:00:00 2001
From: Sean Dougherty <sdougherty@microsoft.com>
Date: Fri, 21 Aug 2026 22:12:09 +0000
Subject: [PATCH] container: Allow log reader to map journals

Journal readers such as journalctl memory-map systemd journal files. Grant the
existing read-only journal interface so container_logreader_t can consume
persistent journals without receiving write or watch access.

Signed-off-by: Sean Dougherty <sdougherty@microsoft.com>
---
policy/modules/services/container.te | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/policy/modules/services/container.te b/policy/modules/services/container.te
index 2fe1b51..4559fb5 100644
--- a/policy/modules/services/container.te
+++ b/policy/modules/services/container.te
@@ -614,6 +614,10 @@ logging_list_logs(container_logreader_t)
allow container_logreader_t logfile:lnk_file read_lnk_file_perms;
allow container_logreader_t container_log_t:file watch;

+optional_policy(`
+ systemd_read_journal_files(container_logreader_t)
+')
+
########################################
#
# Common container engine local policy
--
2.45.4

6 changes: 5 additions & 1 deletion acl/SPECS/selinux-policy/selinux-policy.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Summary: SELinux policy
Name: selinux-policy
Version: %{refpolicy_major}.%{refpolicy_minor}
Release: 9%{?dist}
Release: 10%{?dist}
Comment thread
SeanDougherty marked this conversation as resolved.
License: GPLv2
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand Down Expand Up @@ -81,6 +81,7 @@ Patch57: 0057-cloudinit-Add-sys_admin-to-set-security.sehash.patch
Patch58: 0058-sysnetwork-Silence-sys_admin-denials.patch
Patch59: 0059-container-Drop-unqualified-etc-dir-filetrans-to-conta.patch
Patch60: 0060-container-Add-log-reader-domain.patch
Patch61: 0061-container-Allow-log-reader-to-map-journals.patch
Comment thread
SeanDougherty marked this conversation as resolved.
BuildRequires: bzip2
BuildRequires: checkpolicy >= %{CHECKPOLICYVER}
BuildRequires: m4
Expand Down Expand Up @@ -359,6 +360,9 @@ exit 0
selinuxenabled && semodule -nB
exit 0
%changelog
* Fri Aug 21 2026 Sean Dougherty <sdougherty@microsoft.com> - 2.20250213-10
- Allow confined container log readers to map systemd journal files.

* Wed Aug 19 2026 Sean Dougherty <sdougherty@microsoft.com> - 2.20250213-9
- Add a confined container log reader domain.

Expand Down
1 change: 1 addition & 0 deletions acl/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Detailed documentation for Azure Container Linux.
| [Platforms](platforms.md) | Supported platforms and OEM packages |
| [Testing](testing.md) | Kola/Mantle framework, test categories, enforcing tests |
| [Kdump](kdump.md) | Enabling crash dump (kdump) collection via the UKI addon |
| [SELinux](selinux.md) | Container domains, privilege boundaries, and log-reader configuration |

## Operational Guides

Expand Down
2 changes: 1 addition & 1 deletion acl/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,4 @@ The ROOT partition is created at a minimal size in the shipped image. On first b

### SELinux

ACL ships with **SELinux in enforcing mode by default**. The policy is aligned with Flatcar's upstream SELinux policy, which focuses on strict separation between the host OS and container workloads — host system services run in confined domains while containers are isolated by the `container_t` type.
ACL ships with **SELinux in enforcing mode by default**. The policy is aligned with Flatcar's upstream SELinux policy, which focuses on strict separation between the host OS and container workloads — host system services run in confined domains while containers are isolated by the `container_t` type. See [SELinux Container Domains](selinux.md) for specialized workload domains and safe configuration examples.
132 changes: 132 additions & 0 deletions acl/docs/selinux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# SELinux Container Domains

Azure Container Linux (ACL) enables SELinux in enforcing mode by default.
Operators can configure a node to use permissive mode for troubleshooting;
use `getenforce` to verify its current mode. Container workloads use SELinux
domains to limit their access to the host and to other containers. The
container runtime selects a domain and allocates an MCS category set for each
workload.

## Workload domains

| Domain | Intended use | Host access |
| --- | --- | --- |
| `container_t` | Default container workload | No general access to host logs or host files |
| `container_logreader_t` | Opt-in log collector | Read-only access to objects labeled with an SELinux log type |
| `container_kvm_t` | Containerized KVM workload | KVM-specific device and process access |
| `spc_t` | Privileged container | Broad host access; may be unconfined when the unconfined policy module is enabled |

`container_engine_t` is reserved for the container engine itself and is not a
workload domain.

Use `container_t` unless the workload requires a documented specialized
domain. Do not use `spc_t` solely to collect logs.

## Confined log collectors

`container_logreader_t` extends the normal confined container policy with
read, directory traversal, and symlink access to types carrying the `logfile`
attribute. Inotify watch access applies only to `container_log_t`, not to other
host log types. Access is based on the SELinux label, not the path. Inspect
host labels with:

```bash
ls -ldZ /var/log
find /var/log -maxdepth 2 -type f -exec ls -lZ -- {} +
```

The domain intentionally does not grant:
Comment thread
SeanDougherty marked this conversation as resolved.

- Write, append, create, delete, rename, or relabel access to host logs.
- Blanket access to arbitrary host files beyond the common `container_domain`
policy it shares with `container_t`.
- The broad host privileges provided by `spc_t`.

Like Fedora, RHEL, and other distributions using `container-selinux`, ACL
allows this domain to read auditd-managed files labeled `auditd_log_t`.
Audit logs contain host-wide authentication, syscall, and AVC data; mount
`/var/log/audit` only when the collector requires that information.
Comment thread
SeanDougherty marked this conversation as resolved.
Comment thread
SeanDougherty marked this conversation as resolved.

ACL stores the systemd journal persistently under `/var/log/journal`. The
journal uses `systemd_journal_t` and can contain kernel audit and AVC records,
so it remains readable when mounted into the collector. Restrict mounted paths
when a collector should not receive audit data.

The host log path must still be mounted into the container. Make the mount
read-only as defense in depth, and do not relabel the host log directory.

### Kubernetes example

```yaml
apiVersion: v1
kind: Pod
metadata:
name: host-log-reader
spec:
containers:
- name: collector
image: <collector-image>
securityContext:
seLinuxOptions:
type: container_logreader_t
volumeMounts:
- name: host-journal
mountPath: /host/var/log/journal
readOnly: true
volumes:
- name: host-journal
hostPath:
path: /var/log/journal
type: Directory
```

Cluster admission policy must allow the `container_logreader_t` type. Do not
set the pod to `privileged: true`. Add a separate read-only
`/var/log/audit` mount only when the collector must read auditd-managed files.

### Podman example

```bash
podman run --rm \
--security-opt label=type:container_logreader_t \
--volume /var/log/journal:/host/var/log/journal:ro \
<collector-image>
```

Do not add `:z` or `:Z` to the volume. Those options relabel host content and
can interfere with host logging services. Add a separate
`/var/log/audit:/host/var/log/audit:ro` mount only when auditd files are
required.

## MCS isolation

`container_logreader_t` remains an `mcs_constrained_type` and retains normal
container MCS isolation. ACL builds the targeted policy in MCS mode, where
standard host log file contexts resolve to level `s0`. A container at its
runtime-assigned level, such as `s0:c123,c456`, dominates `s0` and can use the
domain's read permissions without receiving an all-category level.
Comment thread
SeanDougherty marked this conversation as resolved.

Do not set `seLinuxOptions.level` to `s0:c0.c1023` and do not remove the
runtime-assigned categories. Either action weakens isolation from other
containers.

## Validation

Confirm the selected process domain and mounted labels from the container:

```bash
cat /proc/self/attr/current
ls -ldZ /host/var/log/journal
Comment thread
SeanDougherty marked this conversation as resolved.
journalctl --file='/host/var/log/journal/*/system.journal' -n 5
```
Comment thread
SeanDougherty marked this conversation as resolved.

The process context should report `container_logreader_t`, and the journal
read should succeed when the collector image includes `journalctl`. A write
Comment thread
SeanDougherty marked this conversation as resolved.
attempt to a host log should fail. Stock ACL creates `/var/log/audit` but does
not run auditd, so the directory is normally empty. Hosts that add auditd
should treat access to its files as sensitive and mount them only when needed.
On the host, check unexpected SELinux denials with:

```bash
journalctl -g 'avc: denied' --since -10min
Comment thread
SeanDougherty marked this conversation as resolved.
```
Comment thread
SeanDougherty marked this conversation as resolved.
Loading