Manage SELinux boolean policies

Configuring a new service often means dealing with SELinux. The easiest way is most of the time to set an SELinux boolean. But what are SELiunx booleans and what exactly do they do? I will try to shed a little light onto these topics.

What are SELinux booleans?

SELinux is policy based and comes shipped with a quite comprehensive list of policies. As not every setup is the same, not all rules of a policy are meant to be active in every setup. To solve this, SELinux allows rules to be only active when needed – conditional rules.

SELinux booleans control such conditional rules inside SELinux policies. These SELinux booleans allow the administrator of the system to enable or disable these conditional rules without the need to create additional policies.

The predefined policies shipped with most distributions contain a long list of booleans to adjust the behavior of SELinux as needed.

What SELinux booleans are available?

To enable one or more of the conditional rules, it is important to know what booleans are available. The list of booleans is huge, which is why the following was reduced to what I believe are the most commonly used booleans.

With the default installation of apache, the daemon is allowed to serve web-content. Connecting to a database or acting as reverse proxy is not allowed by default.

$ getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off

The above getsebool(8) list of SELinux booleans shows all the booleans available for httpd (known as apache). The names of the different booleans already reveal a lot about what they do.

  • The ‘httpd_can_network_connect_db‘ would allow the apache daemon to connect to a database.
  • The ‘httpd_can_network_relay‘ would allow the apache daemon to act as a reverse proxy.

This sounds great and and works great in most setups. Questions start to arise when these booleans do not provide the expected effect.

What exactly is the effect of those booleans?

Enabling one of those booleans is easy. Understanding the effect is a bit more complex. Enabling a boolean, as explained earlier, will enable a set of predefined conditional rules inside the policies. To find out what those conditional rules do, an additional tool is needed.

$ yum install setools-console

SETools is a collection of tools to assist in working with SELinux. To get an idea of the complexity of the SELinux policies, one of the tools called seinfo(1) can be used.

$ seinfo 

Statistics for policy file: /etc/selinux/targeted/policy/policy.24
Policy Version & Type: v.24 (binary, mls)

   Classes:            81    Permissions:       238
   Sensitivities:       1    Categories:       1024
   Types:            3916    Attributes:        295
   Users:               9    Roles:              12
   Booleans:          236    Cond. Expr.:       276
   Allow:          320382    Neverallow:          0
   Auditallow:        141    Dontaudit:      273303
   Type_trans:      42419    Type_change:        38
   Type_member:        48    Role allow:         19
   Role_trans:        386    Range_trans:      6258
   Constraints:        90    Validatetrans:       0
   Initial SIDs:       27    Fs_use:             23
   Genfscon:           84    Portcon:           473
   Netifcon:            0    Nodecon:             0
   Permissives:        90    Polcap:              2

This little utility shows (without options) a nice statistic showing (besides other information as well) the amount of booleans – 236 – available. To find out what those booleans do, SETools contains another very useful utility called sesearch(1). The sesearch allows a search through the policies.

$ sesearch --bool httpd_can_network_relay --allow --show_cond --source httpd_t
Found 17 semantic av rules:
DT allow httpd_t gopher_client_packet_t : packet recv ; [ httpd_can_network_relay ]
DT allow httpd_t gopher_client_packet_t : packet send ; [ httpd_can_network_relay ]
DT allow httpd_t gopher_port_t : tcp_socket name_connect ; [ httpd_can_network_relay ]
DT allow httpd_t squid_client_packet_t : packet recv ; [ httpd_can_network_relay ]
DT allow httpd_t squid_client_packet_t : packet send ; [ httpd_can_network_relay ]
DT allow httpd_t memcache_port_t : tcp_socket name_connect ; [ httpd_can_network_relay ]
DT allow httpd_t http_cache_port_t : tcp_socket name_connect ; [ httpd_can_network_relay ]
DT allow httpd_t http_client_packet_t : packet recv ; [ httpd_can_network_relay ]
DT allow httpd_t http_client_packet_t : packet send ; [ httpd_can_network_relay ]
DT allow httpd_t ftp_client_packet_t : packet recv ; [ httpd_can_network_relay ]
DT allow httpd_t ftp_client_packet_t : packet send ; [ httpd_can_network_relay ]
DT allow httpd_t ftp_port_t : tcp_socket name_connect ; [ httpd_can_network_relay ]
DT allow httpd_t http_cache_client_packet_t : packet recv ; [ httpd_can_network_relay ]
DT allow httpd_t http_cache_client_packet_t : packet send ; [ httpd_can_network_relay ]
DT allow httpd_t http_port_t : tcp_socket name_connect ; [ httpd_can_network_relay ]
DT allow httpd_t ephemeral_port_type : tcp_socket name_connect ; [ httpd_can_network_relay ]
DT allow httpd_t squid_port_t : tcp_socket name_connect ; [ httpd_can_network_relay ]

A quick search through the policies for the boolean “httpd_can_network_relay” (–bool option) for any “allow” (–allow option) statements which are conditional (–show_cond option) reveals the list of rules which are controlled by this SELiunx boolean. The “–source” option additionally filters the result for rules matching the “httpd_t” type which is assigned to the apache daemon.

In this case, when the SELinux boolean is enabled, these rules are active and allow the httpd (apache) daemon to access …

  • gopher ports
  • ftp ports
  • http cache ports
  • http ports
  • squid ports
  • memcache ports

This information as it is can be very helpful, but does not yet reveal the exact port numbers allowed. To find the exact port numbers, another package of utilities needs to be installed.

$ yum install policycoreutils-python

The “policycoreutils-python” package contains tools like the following.

  • audit2allow(1) translates SELinux audit messages into SELinux policy
  • audit2why(8) translates SELinux audit messages into a nicely readable description
  • semanage(8) a SELinux policy management tool

Using the semanage tool, the port definition can be shown in more detail. When the “port” command is used together with the “-l” option, semanage will show all ports that are defined. A simple grep command will reduce it to what is interesting at this point

$ semanage port -l | grep -E "^(ftp_port_t|gopher_port_t|http_cache_port_t|http_port_t|memcache_port_t|squid_port_t) "
ftp_port_t                     tcp      21, 989, 990
ftp_port_t                     udp      989, 990
gopher_port_t                  tcp      70
gopher_port_t                  udp      70
http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
memcache_port_t                tcp      11211
memcache_port_t                udp      11211
squid_port_t                   tcp      3128, 3401, 4827
squid_port_t                   udp      3401, 4827

In the example above, the grep(1) command is filtering for all the “…_port_t” types shown in the “sesearch” output of the “httpd_can_network_relay” boolean. This reveals the list of allowed ports that are activated by this boolean.

The list reveals the default http (80) and https (443) port, fastcgi process manager (9000) port, … and many more. When apache is configured with php-fpm via default port 9000 or as reverse proxy to one of the ports listed, enabling this boolean will be enough to allow apache to access them.

For a more open rule, the “http_can_network_connect” boolean can be used.

$ sesearch --bool httpd_can_network_connect --allow --show_cond --source httpd_t
Found 1 semantic av rules:
DT allow httpd_t port_type : tcp_socket name_connect ; [ httpd_can_network_connect ]

The conditional rule of this SELinux boolean very generically allows socket connections without limiting them to any specific port.

How to set an SELiunx boolean

With the correct SELinux boolean identified, it needs to be enabled. Enabling a boolean can be done with the setsebool(8).

$ setsebool -P httpd_can_network_relay=on

The “-P” option ensures that the boolean is enabled permanently and therefore survives a reboot of the server. Without the -P option, the change is just temporary and will be gone after a reboot.


Read more of my posts on my blog at https://blog.tinned-software.net/.

This entry was posted in Linux Administration, Security and tagged , , . Bookmark the permalink.