Cloning Linux Permissions
Ever have that moment where you’re working on your SELinux enabled webserver and you’ve put in a fancy new file into /var/www/html
and the darn thing just won’t show up properly, even though everything else is working? Then that sinking realization that you have to deal with three different aspects of troubleshooting permissions - ownership, Unix file permissions and SELinux permissions?
Turns out, as long as you have at least one file around that already has the correct owner, permissions and SELinux contexts you can rapidly clone everything with the --reference
flag - a trick that took me way too long to discover.
Syntax
To clone owner and group, use the chown command, like so:
chown file_to_update --reference=correct_file
To clone Unix permissions, use the chmod command, like so:
chmod file_to_update --reference=correct_file
To clone SELinux context, use the chcon command, like so:
chcon file_to_update --reference=correct_file
As you can see, all three use the same syntax, so only the command has to change - this makes it easy to rapidly ensure that all potential permissions have been cloned by entering the command once then updating just the base command, leaving the syntax the same.
Example - Handling Apache Files
In this example, there are two files in /var/www/html/
: index.html
which was created earlier and has all the right permissions, and new_file.html
which was copied in from /root
and has some issues as a result. Here’s the output of ls -lZ
(the Z
flag outputs SELinux context).
-rw-r--r--. 1 apache apache unconfined_u:object_r:httpd_sys_content_t:s0 0 Apr 15 14:39 index.html
-rwx--x-w-. 1 root root unconfined_u:object_r:admin_home_t:s0 0 Apr 15 14:46 new_file.html
As you can see, the permissions on new_file.html
are wrong, the owner and group are wrong, and so is the SELinux context. Happily we know that everything is good on index.html
, so we’ll run our three commands:
chown new_file.html --reference=index.html
Running ls -lZ
now shows that the owner and group are fixed, as we expected.
-rw-r--r--. 1 apache apache unconfined_u:object_r:httpd_sys_content_t:s0 0 Apr 15 14:39 index.html
-rwx--x-w-. 1 apache apache unconfined_u:object_r:admin_home_t:s0 0 Apr 15 14:46 new_file.html
So far, so good. Let’s run the chmod - we won’t even have to type everything out again, just go back in our terminal history and update the first part of the chown command!
chmod new_file.html --reference=index.html
And now ls -lZ
shows us the permissions are corrected, all that’s left is SELinux.
-rw-r--r--. 1 apache apache unconfined_u:object_r:httpd_sys_content_t:s0 0 Apr 15 14:39 index.html
-rw-r--r--. 1 apache apache unconfined_u:object_r:admin_home_t:s0 0 Apr 15 14:46 new_file.html
Finally, we’ll run the chcon command.
chcon new_file.html --reference=index.html
Sure enough, one last ls -lZ
proves that now everything is correct, including the SELinux context.
-rw-r--r--. 1 apache apache unconfined_u:object_r:httpd_sys_content_t:s0 0 Apr 15 14:39 index.html
-rw-r--r--. 1 apache apache unconfined_u:object_r:httpd_sys_content_t:s0 0 Apr 15 14:46 new_file.html
Obviously this command isn’t a substitute for knowing how all these different commands work, and what the permissions need to be for different applications - but if you’re replacing or adding some files, it sure is a quick way to get an update in place.