Apache Security with SELinux

by Mike on May 21, 2009 · 1 comment

in Server Security

SELinux is an open source project sponsored by the National Security Agency. The focus is to use SELinux to implement mandatory access control in a limited fashion. SELinux provides security at the kernel level. What this does for security is provide a security system at a fundamental level that will not be as impacted by security settings of individual programs. In effect, SELinux takes programs and isolates each program from the system so that it still functions with the system but is in a security sense independent of the system. In other words, if a program is compromised it does not offer more access to the system, rather it offers less access to the system. An added benefit to this isolation is that it protects data from being shared incorrectly, by removing discretion of the user.   The image below illustrates this concept.  Daemons and their support programs are placed in domains or jails.  These jails prevent access to other parts of the operating system.  DNS (bind) is separated from the rights to Apache so that if one is compromised the entire system is not compromised.


SELinux with Apache

Security with Apache is an important topic, of which SELinux is a part. The reason for discussing SELInux at this point is so that you have SELinux enabled throughout the discussion and learn how to manage SELinux instead of just turning it off.

View Processes protected by SELinux
You may view processes which are restricted by SELinux with ps.

# ps -ZC httpd


root:system_r:httpd_t 11759 ? 00:00:00 httpd

root:system_r:httpd_t 15899 ? 00:00:00 httpd

root:system_r:httpd_t 15900 ? 00:00:00 httpd

root:system_r:httpd_t 15901 ? 00:00:00 httpd

root:system_r:httpd_t 15902 ? 00:00:00 httpd

root:system_r:httpd_t 15903 ? 00:00:00 httpd

root:system_r:httpd_t 15918 ? 00:00:00 httpd

root:system_r:httpd_t 15919 ? 00:00:00 httpd

root:system_r:httpd_t 15920 ? 00:00:00 httpd

If you wanted to view the entire list of processes currently protected with SELinux you would use this command:

# ps -eZ


system_u:system_r:init_t 1 ? 00:00:00 init

system_u:system_r:kernel_t 2 ? 00:00:00 migration/0

system_u:system_r:kernel_t 3 ? 00:00:00 ksoftirqd/0

system_u:system_r:kernel_t 4 ? 00:00:00 watchdog/0

system_u:system_r:kernel_t 5 ? 00:00:00 events/0

system_u:system_r:kernel_t 6 ? 00:00:00 khelper

system_u:system_r:kernel_t 7 ? 00:00:00 kthread

system_u:system_r:kernel_t 10 ? 00:00:00 kblockd/0

system_u:system_r:kernel_t 11 ? 00:00:00 kacpid


user: role: type: sensitivity: category

# ls -Z

-rw-r–r– root root root:object_r:httpd_sys_content_t index.html

user: root:

role: object_r:

type: httpd_sys_content_t



If you are going to use the apache web server you will need to know how to adjust the SELinux for that daemon. The first step in this process is to evaluate the booleans that are set for httpd in SELinux.  These booleans allow you to either turn on or off features of SELinux that are useful for protecting Apache.

# getsebool -a | grep httpd

allow_httpd_anon_write –> off

allow_httpd_mod_auth_pam –> off

allow_httpd_sys_script_anon_write –> off

httpd_builtin_scripting –> on

httpd_can_network_connect –> off

httpd_can_network_connect_db –> off

httpd_can_network_relay –> off

httpd_disable_trans –> off

httpd_enable_cgi –> on

httpd_enable_ftp_server –> off

httpd_enable_homedirs –> on

httpd_rotatelogs_disable_trans –> off

httpd_ssi_exec –> off

httpd_suexec_disable_trans –> off

httpd_tty_comm –> off

httpd_unified –> on


Set files with httpd_sys_content_t for content which is available from all httpd scripts and the daemon.


Set cgi scripts with httpd_sys_script_exec_t to allow them to run with access to all sys types.


Set files with httpd_sys_script_ro_t if you want httpd_sys_script_exec_t scripts to read the data, and disallow other sys scripts from access.


Set files with httpd_sys_script_rw_t if you want httpd_sys_script_exec_t scripts to read/write the data, and disallow other non sys scripts from access.


Set files with httpd_sys_script_ra_t if you want httpd_sys_script_exec_t scripts to read/append to the file, and disallow other non sys scripts from access.


Set cgi scripts with httpd_unconfined_script_exec_t to allow them to run without any SELinux protection. This should only be used for a very complex httpd scripts, after exhausting all other options. It is better to use this script rather than turning off SELinux protection for httpd.

SELinux policy is customizable based on least access required. So by default SElinux prevents certain http scripts from working. httpd policy is extremely flexible and has several booleans that allow you to manipulate the policy and run httpd with the tightest access possible.  The -P sets a policy that will carry over after a reboot.

Enable cgi

# setsebool -P httpd_enable_cgi 1

Enable User home Directories and Change Context

# setsebool -P httpd_enable_homedirs 1

# chcon -R -t httpd_sys_content_t ~user/public_html

Enable Access to Terminal
httpd may need to prompt for a password on a certificate file

# setsebool -P httpd_tty_comm 1

Disable File Control Contexts

# setsebool -P httpd_unified 0

Disable PHP

# setsebool -P httpd_builtin_scripting 0

Enable Network Connections from httpd
Disabled to prevent hackers from attacking other machines from httpd.

# setsebool -P httpd_can_network_connect 1

Disable suexec Transition

# setsebool -P httpd_suexec_disable_trans 1

Disable Protection for httpd Daemon
This is the option that you could use if yoou wanted to turn everyting off for protection of apache but you wanted to use SELinux to protect the rest of the box.

# setsebool -P httpd_disable_trans 1

# service httpd restart

Changing a http Port

You may want to change a port number for http. You cannot do this without editing the configuration for SELinux.

# semanage port -l | grep http

http_cache_port_t tcp 3128, 8080, 8118

http_cache_port_t udp 3130

http_port_t tcp 80, 443, 488, 8008, 8009, 8443

pegasus_http_port_t tcp 5988

pegasus_https_port_t tcp 5989

Change httpd to port 81 in the httpd.conf file.

Listen 81

Now restart, and you will see that it will fail to restart. Check /var/log/messages for output.

Dec 10 08:03:46 cent2 setroubleshoot: SELinux is preventing the /usr/sbin/httpd (httpd_t) from binding to port 81. For complete SELinux messages. run sealert -l 9d1872a0-da1f-48b3-b7bc-4ed7094387e5

In order to fix this you will need to use the semanage command to add port 81 to the ports allowed by SELinux.

# semanage port -a -t http_port_t -p tcp 81

Restart httpd and you will find that it works. Now verify that port 81 was added to the default allowed ports.

# semanage port -l | grep http

http_cache_port_t tcp 3128, 8080, 8118

http_cache_port_t udp 3130

http_port_t tcp 81, 80, 443, 488, 8008, 8009, 8443

pegasus_http_port_t tcp 5988

pegasus_https_port_t tcp 5989

{ 1 comment }

Alex January 20, 2010 at 11:13 pm

very, very nice and easy tutorial!
Thank you!

Previous post:

Next post: