Ansible for SELinux

SELinux settings fall into four kinds, each with its module. Two collections are involved: ansible.posix (mode and booleans) and community.general (file contexts and ports).

yaml - ansible.posix.selinux: /etc/selinux/config + setenforce policy: targeted state: enforcing - community.general.sefcontext: semanage fcontext -a target: '/web(/.)?' setype: httpdsyscontentt state: present - ansible.builtin.command: restorecon -Rv /web register: r changedwhen: r.stdout | length 0 - ansible.posix.seboolean: setsebool [-P] name: httpdcannetworkconnect state: true persistent: true - community.general.seport: semanage port -a/-m ports: 82 proto: tcp setype: httpportt state: present

sefcontext only writes the rule, exactly like semanage fcontext; existing files keep their labels until restorecon runs. There is no restorecon module, so the command task above (with changedwhen) is the accepted pattern. The file module can also set setype directly, but that is a chcon, lost at the next relabel.

The system role. redhat.rhelsystemroles.selinux takes the same settings as variables, which suits one play that sets up everything:

yaml - hosts: prod vars: selinuxstate: enforcing selinuxpolicy: targeted selinuxbooleans: [{ name: httpdcannetworkconnect, state: on, persistent: yes }] selinuxfcontexts: [{ target: '/web(/.)?', setype: httpdsyscontentt }] selinuxrestoredirs: [/web] selinuxports: [{ ports: 82, proto: tcp, setype: httpportt }] roles: - redhat.rhelsystemroles.selinux

Checking your work. ansible prod -m command -a 'ls -Zd /web /web/index.html', getsebool httpdcannetworkconnect, semanage port -l filtered for httpportt, and grep ^SELINUX= /etc/selinux/config cover the four kinds of settings. Finally test the service from control with curl http://node3:82/; a 403 means labels, a refused connection means firewall or Listen.

Pitfalls. Booleans without persistent: true are lost at reboot. Switching from disabled to enforcing needs a reboot (the module warns; reboot module if the task asks). Forgetting the firewall port and the httpd Listen line when the task is "serve on port 82": SELinux is only one of three locks. Quoting the regex target so YAML keeps the parentheses.

In the WebAsha lab the SELinux simulator is invisible to the Python bindings these modules use, so the lab accepts equivalent idempotent command tasks; on the exam, use the modules.