• .te -> type enforcement = allow rules, new types, user etc (used most of the time)
  • .fc -> file context = define file context rules for module (<regexp> <security_context>)
  • .if -> interfaces = macros

Update policy

  • Use a unique policy name otherwise it can clash with system internals and result in strange error messages
grep qemu-system-x86 /var/log/audit/audit.log | audit2allow -M <policy_name>
semodule -i <policy_name>.pp
  • Or to allow all since the last policy change
audit2allow -alR

Show all policy modules

semodule -l

Get rid of a policy

  • Disable
semodule -d <policy_name>
  • Remove
semodule -r <policy_name>

Write your own policy module

  • Allow rules have the definition allow <from_type> <to_type> : <object_class> {permissions};
  • Every type / attribute / class used and not defined in module must be required
  • Choose a good name (not mypol) to avoid clashing with other predefined modules
  • Copy Makefile from /usr/share/selinux/devel/
policy_module(mypol, 1.0)

require {
  type httpd_t;

type my_type;
allow httpd_t my_type : file { getattr read };
  • All object classes can be found in /usr/src/redhat/BUILD/serefpolicy-<version>/policy/flask/security_classes
  • All permissions for a class can be found in /usr/src/redhat/BUILD/serefpolicy-<version>/policy/flask/access_vectors

Check policy module

checkmodule -m some.te

Compile a te file by hand

make -f /usr/share/selinux/devel/Makefile some.pp

Search a policy rule

sesearch -A | grep <whatever>
  • To see all allow rules with type httpd_t as source
sesearch -a -s httpd_t
  • or to see what a boolean / macro does (needs policy.conf see below)

Generate a policy skeleton

sepolicy generate --application /usr/bin/firefox
sepolicy generate --init /path/to/my/init-service


  • Show all booleans
semanage boolean -l
getselbool -a
  • Set a boolean
setsebool -P <boolean> <value>
  • All local changes are in /etc/selinux/<policy>/modules/booleans.local

Write your own boolean

bool mybool <defaultvalue>;
tuneable_policy(`mybool', `
  allow statements
  • Name can be combined with || or && and other boolean names to activated this boolean only if condition is true

Managing file contexts

  • SE Linux stores the security context for files directly in the filesystem (currently ext{2,3,4}, XFS, JFS, Btrfs)
  • Last rule matches
  • Show file context
ls -Z
  • Show all context rules
semanage fcontext -l
  • Set new file context rule
semanage fcontext -a -t mysqld_db_t '/some/dir(/.*)?'
  • Reset context rules for dir
restorecon -RFvv /some/dir
  • Copy context
chcon -R --reference=/old/dir /new/dir
  • Permanently set same context as other directory
semanage fcontext -a -e /var/www /srv/www
  • Delete a file context
semanage fcontext -d <dir>
  • Automatically relabel all files on next boot
touch /.autorelabel

List all roles

seinfo -r

Change role

newrole -r system_r -t unconfined_t
id -Z

Start a program in a specific role

runcon system_u:system_r:crond_t:s0 /bin/bash

Configure users

  • List all users
seinfo -u
  • Map Unix user to SELinux user
semanage login -a -s user_u <unix_user>
semanage login -l
  • Map SELinux user to roles
semanage user -a -R "user_r sysadm_r" user_u
semanage user -l

Log everything

semanage dontaudit off
  • or
semanage -DB

Reset base policy

semodule -B

Generate policy.conf (source file of your policy)

  • install src rpm of policy
rpmbuild -bp selinux-policy.spec
cd BUILD/serefpolicy-<version>
  • Edit build.conf and set type to mcs, name to whatever, distro to redhat and monolithic to y
make bare conf
cp ../../SOURCES/boolean-targeted.conf policy/booleans.conf
cp ../../SOURCES/modules-targeted.conf policy/modules.conf
make policy.conf
  • To make a module policy set MONOLITHIC=n and make base.pp instead of make policy.conf
  • If apol complains it cannot load policy due to whatever failure just delete those line(s)

Configure Non-executable stack / heap

setsebool -P allow_execstack 0
setsebool -P allow_execmem 0

Kernel parameter


Switch to MCS or MLS policy

  • Install policy rpm
  • Edit /etc/selinux/config
touch /.autorelabel
  • Boot with enforcing=0
  • Reboot after relabeling

Define new category

  • Edit /etc/selinux/targeted/setrans.conf
  • Restart mcstrans

Change category of a user

semanage login -a -r <category> <user>

Change category of file / dir

  • Multiple categories are AND conditions
chcat +|-<category> <file|dir>

Write your own macro

define(`macro_name', `allow $1 $2: file { getattr read }');

Domain transition

init_daemon_domain(myproc_t, myfile_exec_t)
domain_auto_trans(unconfined_t, myfile_exec_t, myproc_t)

Mysql config

  • Change datadir
semanage fcontext -a -t mysqld_db_t '/new/dir/mysql(/.*)?'
restorecon -RFvv /new/dir/mysql/
  • For more see man mysqld_selinux

Apache config

  • Allow cgi scripts
setsebool -P httpd_enable_cgi 1
  • Allow webserver scripts to connect to the network
setsebool -P httpd_can_network_connect 1
  • Run apache on non-standard port
semanage port -l | grep http
semanage port -a -t http_port_t -p tcp 8888
  • For more see man httpd_selinux

NFS / Mounting

  • Specify security context with mount parameter --context=<security_label> to have all files / dirs that security label or
  • --defcontext=<security_label> to define a label just for those unlabeled

Temporarily disable / enable SELinux

setenforce [0|1]

Audit Framework

  • For permanent rules edit /etc/audit/audit.rules
  • Show current status
auditctl -s
  • Enable / disable audit
auditctl -e 0/1
  • Show all rules
auditctl -l
  • Delete all rules
auditctl -D
  • Log all execve calls of user root
auditctl -a exit,always -S execve -F euid=0
  • Log all executions of a specific program
auditctl -A exit,always -F path=/path/to/executable -S execve
  • Suppress all successful executions of some program
auditctl -w /path/to/executable -F success=1
  • Show all logs of a specific timespan and from a certain user
ausearch --start month/day/year time --end month/day/year time -ui 0
  • Show recent events (last 5 minutes)
ausearch -ts recent