← RHCE in Ansible: automation and operations
14 / 15 · 55 MIN

SELinux: mappings and effective state

Correct persistent labels and distinguish policy, permissions and observed access.

Investigate the denial

A fictional httpd service must read static content from /srv/dr-status. The file has mode 0644, but requests receive 403 and an associated AVC denial exists. Unix mode does not describe the entire decision: process domain, object type and SELinux policy also matter. Confirm process identity and traversed directories before attributing the whole failure to one layer. Do not turn the symptom into a request to disable SELinux or grant everyone write access. The objective is to permit the required operation while retaining control over unnecessary operations.

Map and apply

The example targets a disposable RHEL 10 VM with SELinux enforcing. sefcontext maintains the persistent association between /srv/dr-status(/.*)? and httpd_sys_content_t. The pattern covers the directory and descendants rather than all of /srv. That choice represents static read content rather than an upload area. A later task applies restorecon to existing objects. These are separate actions: a correct rule can coexist with incorrectly labelled files. chcon changes object labels but does not replace the persistent rule used by future reconciliation.

The handler that misses drift

Imagine the rule is already correct and an operator changed index.html’s label. If restorecon runs only as a handler notified by sefcontext changed, the next execution may not repair that drift. The example invokes reconciliation after creating content even without a rule change. The command may run on every pass without every pass needing label changes. The stdout-based changed_when is only a reporting convention in this example; acceptance must compare effective context and access behavior. Avoid making the functional decision depend on localized terminal text.

Accept with policy active

Inspect the local rule, compare expected and observed context, and test reading through the httpd process while SELinux remains enforcing. A request working only in permissive is diagnostic evidence rather than control acceptance. If content needs writing, separate the writable area and assess the appropriate type instead of applying a broad label to the entire tree. A new denial does not justify automatically generating permissive policy from the whole audit log; first look for incorrect paths, labels, ports and configuration.

Example limits

Syntax was validated with community.general 10.7.6, but this review performed no RHEL relabel or access test. The playbook creates content and mapping; it does not configure httpd DocumentRoot, VirtualHost, TLS or listeners. Prepare that integration separately on the VM and retain enforcing policy during tests. After another reconciliation and reboot, repeat the read and confirm the persistent association remains valid.

# Exercise for a disposable enforcing RHEL 10 VM.
# Syntax checked only; actual labels and httpd access remain unverified.
- name: Maintain a narrow read-only web content label
 hosts: rhel_lab
 become: true
 gather_facts: true
 pre_tasks:
 - name: Require the intended lab and enforcing policy
 ansible.builtin.assert:
 that:
 - lab_confirmed | default(false) | bool
 - ansible_distribution == 'RedHat'
 - ansible_distribution_major_version == '10'
 - ansible_selinux.status == 'enabled'
 - ansible_selinux.mode == 'enforcing'
 tasks:
 - name: Install the policy management dependency
 ansible.builtin.package:
 name: policycoreutils-python-utils
 state: present
 - name: Create the dedicated content directory
 ansible.builtin.file:
 path: /srv/dr-status
 state: directory
 owner: root
 group: root
 mode: '0755'
 - name: Maintain the persistent path-to-type mapping
 community.general.sefcontext:
 target: '/srv/dr-status(/.*)?'
 setype: httpd_sys_content_t
 state: present
 - name: Install synthetic read-only content
 ansible.builtin.copy:
 content: "DR synthetic status page\n"
 dest: /srv/dr-status/index.html
 owner: root
 group: root
 mode: '0644'
 - name: Reconcile labels on existing files even if mapping did not change
 ansible.builtin.command:
 argv: [restorecon, -Rv, /srv/dr-status]
 register: relabel
 changed_when: relabel.stdout | length > 0
IN PRACTICE

The rule is unchanged but the label is wrong; object reconciliation is still needed.

Common pitfalls

Confusing rule with label; relying only on notification; permissive as acceptance; Unix permissions as the whole explanation.

Related topics: LVM, filesystem and persistent mounting · Services, firewall and external validation

Take this idea with you

Verify persistent rule, effective label and authorized operation with policy active.

Create account

Reference: SELinux path mapping module · EX294 current objectives inspected 2026-09-30; RHCE in Ansible framework effective 2026-05-11; booking product version not publicly pinned

Red Hat®, RHCE and Ansible are trademarks or registered trademarks of Red Hat, Inc. bigsavant.com is an independent preparation platform and is not affiliated with, associated with, sponsored, authorised or endorsed by Red Hat. Content and questions are original, are not official exam questions, and completing our tests does not award or guarantee any certification. Names are used only to identify the subject. All other trademarks belong to their respective owners.