SELinux can be a pain to work with at times, but that does not justify setting it to permissive mode or disabling it. Wordpress’ popularity makes it a script kiddie’ favourite target. Other than always keeping your Wordpress instance updated, you should be running httpd/Apache in a confined SELinux domain. It reduces the damage someone can do, if (at all) they manage to upload and execute files onto your webserver (ever noticed those random named, hidden binary files in /tmp owned by the user running your webserver ? )
Lets make sure that the stage is setup correctly
sestatus must report the below output. If it doesn’t - you either have it disabled or running in permissive mode. Don’t proceed until you have output that looks exactly like below
[ec2-user@ip-172-30-10-10 ~]$ sestatus | grep 'SELinux status\|Current mode' SELinux status: enabled Current mode: enforcing
httpd must be running in domain
httpd_t. If its
unconfined_t then its running in the wrong domain and rules meant to secure it won’t apply.
[ec2-user@ip-172-30-10-10 ~]$ ps uax -Z | grep httpd unconfined_u:system_r:httpd_t:s0 root 22884 0.0 1.0 324744 11188 ? Ss Jan15 0:01 /usr/sbin/httpd unconfined_u:system_r:httpd_t:s0 apache 22887 0.0 2.7 342656 28556 ? S Jan15 0:00 /usr/sbin/httpd unconfined_u:system_r:httpd_t:s0 apache 23138 0.0 0.6 324876 6812 ? S Jan15 0:00 /usr/sbin/httpd unconfined_u:system_r:httpd_t:s0 apache 23206 0.0 0.5 324744 6064 ? S Jan15 0:00 /usr/sbin/httpd unconfined_u:system_r:httpd_t:s0 apache 23483 0.0 0.5 324744 6064 ? S Jan15 0:00 /usr/sbin/httpd unconfined_u:system_r:httpd_t:s0 apache 23486 0.0 0.5 324744 6064 ? S Jan15 0:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ec2-user 24944 0.0 0.0 110256 644 pts/0 S+ 03:58 0:00 grep httpd
If your /usr/sbin/httpd is running in domain
unconfined_t instead of
httpd_t, then your context of
/usr/sbin/httpd has somehow changed. Restoring the context should fix it
To restore context run restorecon
[ec2-user@ip-172-30-10-10 ~]$ sudo restorecon -v /etc/init.d/httpd /usr/sbin/httpd
If you are hosting your database on a remote server, httpd must be allowed to connect to it.
[ec2-user@ip-172-30-10-10 ~]$ sudo setsebool -P httpd_can_network_connect_db 1
Note: Connection to local database i.e. localhost:3306 does not need this to be set to true
When uploading images and other media from wp-admin, httpd needs access to write to wordpress’ upload directory. By default all files and directories in /var/www/html are labeled with type
httpd_sys_content_t. In this context files are not writeable by process httpd running in domain
httpd_t. Changing this to type
httpd_sys_rw_content_t will allow write/create/delete access
[ec2-user@ip-172-30-10-10 ~]$ sudo semanage fcontext -f "" -a -t httpd_sys_rw_content_t '/var/www/html/wp-content/uploads(/.*)?'
To apply the change in context for directories and files in /var/www/html/wp-content/uploads/* use restorecon
[ec2-user@ip-172-30-10-10 ~]# restorecon -Rv /var/www/html [ec2-user@ip-172-30-10-10 ~]# ls -all -Z /var/www/html/wp-content/uploads/ drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_rw_content_t:s0 . drwxr-xr-x. nobody 65534 unconfined_u:object_r:httpd_sys_content_t:s0 .. drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_rw_content_t:s0 2015
httpd_unifiedon CentOS/RHEL distributions
httpd_unified is enabled on CentOS/RHEL systems older than version 7.
This allows Apache write access to files and directories labeled with context
httpd_sys_content_t. We want to make sure that Apache can only write to the directory/files we whitelisted (/var/www/html/wp-content/uploads/). Turning this off is highly recommended to control writes to the filesystem and within the DocRoot
[ec2-user@ip-172-30-10-10 ~]# sudo setsebool -P httpd_unified 0
A list of all boolean interfaces that are exposed by selinux_httpd can be listed using getsebool. An explanation of boolean interface is documented on selinux_httpd’ man page
[ec2-user@ip-172-30-10-10 ~]$ sudo getsebool -a | grep httpd allow_httpd_anon_write --> off allow_httpd_mod_auth_ntlm_winbind --> off allow_httpd_mod_auth_pam --> off allow_httpd_sys_script_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_zabbix --> off httpd_can_network_connect --> on 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_enable_cgi --> on httpd_enable_ftp_server --> off httpd_enable_homedirs --> off httpd_execmem --> off httpd_graceful_shutdown --> off httpd_manage_ipa --> off httpd_read_user_content --> off httpd_run_stickshift --> off httpd_setrlimit --> off httpd_ssi_exec --> 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_verify_dns --> off
At this point, you should have a working instance of Wordpress served by httpd running in confined domain
httpd_t. It should minimised the damage that someone can do, if at all they manage to upload files to your server and attempt to execute them.
These simple steps should keep your Wordpress instance fairly secure and the random binary files in /tmp at bay.