Recently, we were trying to update a WordPress
installation that was running under apache
in a CentOS 7
. When we would press the lovely blue button to update WordPress
we would get the following error:
The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.: wp-admin/includes/update-core.php
Installation Failed
At first we thought it was an issue with the privileges on the folder, so we did the following steps to fix the issue:
Find which user is controlling apache
server:
We executed the following command to get the name of the local user that was handling the apache
web server:
ps -ef | grep apache;
From which, we got the following results:
apache 7289 8523 1 10:35 ? 00:00:03 /usr/sbin/httpd -DFOREGROUND
apache 7293 8523 0 10:35 ? 00:00:02 /usr/sbin/httpd -DFOREGROUND
apache 7316 8523 0 10:35 ? 00:00:01 /usr/sbin/httpd -DFOREGROUND
apache 7317 8523 0 10:35 ? 00:00:01 /usr/sbin/httpd -DFOREGROUND
apache 7335 8523 1 10:35 ? 00:00:03 /usr/sbin/httpd -DFOREGROUND
apache 7347 8523 0 10:35 ? 00:00:01 /usr/sbin/httpd -DFOREGROUND
apache 7348 8523 0 10:35 ? 00:00:01 /usr/sbin/httpd -DFOREGROUND
apache 7349 8523 0 10:35 ? 00:00:01 /usr/sbin/httpd -DFOREGROUND
apache 7350 8523 0 10:35 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 7351 8523 0 10:35 ? 00:00:01 /usr/sbin/httpd -DFOREGROUND
root 8071 7978 0 10:40 pts/1 00:00:00 grep --color=auto apache
The first column is the name of the user, so we found out that apache
local user is the user executing the apache
web server.
Repair all file and folder access rights:
After getting the above information we proceeded to update the access rights in our WordPress
installation folder (/var/www/example.com
)
find /var/www/example.com -type d -exec chmod 755 '{}' \;
find /var/www/example.com -type f -exec chmod 644 '{}' \;
chown -R apache:apache /var/www/example.com;
To our disappointment, nothing changed and we would still get the same error. Luckily enough we had another ace in our sleeve!
Checking the security context of each file and folder:
We executed the following command (ls -Z
) to get the security context of the files and folders in the installation folder of WordPress
:
ls -Z /var/www/example.com;
Where we got the following results:
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 api
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 favicon.ico
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 index.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 license.txt
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 readme.html
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 r-file.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wordfence-waf.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-activate.php
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-admin
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-blog-header.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-comments-post.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-config.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-config-sample.php
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_rw_content_t:s0 wp-content
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-cron.php
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-includes
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-links-opml.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-load.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-login.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-mail.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-settings.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-signup.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 wp-trackback.php
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 xmlrpc.php
What we got from this result: all files and folders marked with the httpd_sys_content_t
are not directly editable by the apache
web server even though the user has the rights to do so as it is a security step by SELinux
.
httpd_sys_content_t
Use this type for static web content, such as .html
files used by a static website. Files labeled with this type are accessible (read only) to httpd
and scripts executed by httpd
. By default, files and directories labeled with this type cannot be written to or modified by httpd
or other processes. Note that by default, files created in or copied into /var/www/html/
are labeled with the httpd_sys_content_t
type.
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/managing_confined_services/sect-managing_confined_services-the_apache_http_server-types
The simple solution
We just changed the security context for the folders and files to httpd_sys_rw_content_t
which allows apache
web server to edit the files:
httpd_sys_rw_content_t
Files labeled with this type can be written to by scripts labeled with the httpd_sys_script_exec_t
type, but cannot be modified by scripts labeled with any other type. You must use the httpd_sys_rw_content_t
type to label files that will be read from and written to by scripts labeled with the httpd_sys_script_exec_t
type.
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/managing_confined_services/sect-managing_confined_services-the_apache_http_server-types
chcon -R --type httpd_sys_rw_content_t /var/www/example.com;
After this command finished, we updated WordPress
as normal!
(In case you want to change the security context back to the original just execute chcon
with httpd_sys_content_t
as parameter on the folders and files you want to operate as read-only).