Skip to content
Search Rocky Linux

    Browse this documentation

    Rocky 10: SELinux modes, labels and semanage

    In a Rocky Linux 10.2 VM (kernel 6.12.0-211.16.1.el10_2): sestatus, setenforce transitions, ls -Z, chcon, restorecon -Rv, adding and removing semanage fcontext rules, and ausearch -m avc. Log: plans/content-expansion/evidence/logs/rocky-selinux-basics.log.

    Terminal window
    getenforce
    sestatus | head -5
    setenforce 0 && getenforce
    setenforce 1 && getenforce
    Enforcing
    Loaded policy name: targeted
    Current mode: enforcing
    Mode from config file: enforcing
    Permissive
    Enforcing

    setenforce only toggles Enforcing ↔ Permissive; it cannot disable SELinux. Disabled requires editing /etc/selinux/config and rebooting, and going from Disabled back to Enforcing forces a full relabel on the next boot.

    Terminal window
    mkdir -p /srv/lab && echo hi > /srv/lab/f.txt
    ls -Z /srv/lab/f.txt
    unconfined_u:object_r:var_t:s0 /srv/lab/f.txt

    The format is user:role:type:level; for troubleshooting the type is what matters — var_t, httpd_sys_content_t, and so on.

    Terminal window
    chcon -t user_home_t /srv/lab/f.txt
    ls -Z /srv/lab/f.txt
    restorecon -Rv /srv/lab
    ls -Z /srv/lab/f.txt
    unconfined_u:object_r:user_home_t:s0 /srv/lab/f.txt
    Relabeled /srv/lab/f.txt from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:var_t:s0
    unconfined_u:object_r:var_t:s0 /srv/lab/f.txt

    chcon changes the current label only; restorecon restores the policy default. Use chcon for temporary changes and semanage for anything persistent.

    Rocky Linux 10.2: restorecon restoring the default label after chcon

    semanage: teach restorecon about your directory

    Section titled “semanage: teach restorecon about your directory”
    Terminal window
    semanage fcontext -a -t httpd_sys_content_t "/srv/lab(/.*)?"
    restorecon -Rv /srv/lab
    ls -Z /srv/lab/f.txt
    Relabeled /srv/lab/f.txt from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    unconfined_u:object_r:httpd_sys_content_t:s0 /srv/lab/f.txt

    Removing the rule and relabelling:

    Terminal window
    semanage fcontext -d "/srv/lab(/.*)?"
    restorecon -Rv /srv/lab
    Relabeled /srv/lab from ...httpd_sys_content_t:s0 to ...var_t:s0
    Relabeled /srv/lab/f.txt from ...httpd_sys_content_t:s0 to ...var_t:s0
    Terminal window
    ausearch -m avc -ts recent
    <no matches>

    A clean system has no denials; when they appear, ausearch shows denied { ... } with scontext/tcontext/tclass, and audit2why explains the cause.

    • Treating chcon as permanent: a single restorecon reverts it;
    • Confusing Disabled with Permissive: Disabled loads no policy at all and returning to Enforcing requires a relabel;
    • semanage not found: it ships in policycoreutils-python-utils, which minimal and cloud images may omit.

    Practice: add a custom context and remove it

    Section titled “Practice: add a custom context and remove it”
    Terminal window
    sudo dnf install -y policycoreutils-python-utils
    sudo mkdir -p /srv/lab && echo hi | sudo tee /srv/lab/f.txt
    ls -Z /srv/lab/f.txt
    sudo semanage fcontext -a -t httpd_sys_content_t "/srv/lab(/.*)?"
    sudo restorecon -Rv /srv/lab
    ls -Z /srv/lab/f.txt
    sudo semanage fcontext -d "/srv/lab(/.*)?" && sudo restorecon -Rv /srv/lab
    ls -Z /srv/lab/f.txt

    Checks:

    1. The initial type is var_t
    2. After semanage plus restorecon it becomes httpd_sys_content_t
    3. Deleting the rule returns it to var_t
    4. sestatus still reports enforcing

    常见问题

    Can setenforce 0 replace disabling SELinux?

    It only switches to permissive (log but do not deny). Full disable requires /etc/selinux/config and a reboot; coming back from disabled to enforcing requires a relabel.

    Why does my chcon change revert?

    restorecon restores the policy default. Persistent changes need a semanage fcontext rule followed by restorecon.

    ausearch finds no AVC — what now?

    Confirm auditd is running and the time range covers the failure (-ts recent or -ts today); containers usually have no auditd, so host AVCs are invisible there.