chmodding files with an SELinux security context / ACL
ACLs and SELinux contexts are entirely different. There's a good tutorial here for CentOS
To see if SELinux is actually what is blocking your access use sestatus
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28
Enforcing
in my output says that SELinux is actively blocking out-of-context accesses.
Temporarily set SELinux to permissive using # sudo setenforce Permissive
$ sudo setenforce Permissive
[sudo] password for trogdor:
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28
Permissive mode will still alert you of SELinux context violations but will not block them. This is a good way to check if SELinux is actually the problem. If it was, and now everything works, set SELinux back to Enforcing with sudo setenforce Enforcing
. (as an aside changes to SELinux with setenforce will not survive reboot).
If SELinux is the problem you have to find the correct context that the scripts should be, or maybe its a simple fix with a boolean.
If you are in your home directory it could be as simple as setting an SELinux boolean. To view booleans, there's a description of CentOS booleans here but I notice my user_exec_content example below is not listed there, a more convenient tool for boolean discriptions is semanage boolean -l
# getsebool -a | grep exec
...
user_exec_content --> off
...
#sudo semanage boolean -l
...
user_exec_content (off , off) Allow user to exec content
...
The first off shows its current state, that it is currently set to off; the next off shows the default, meaning that it will still be off after reboot or file system relabeling.
In that case use #setsebool -P user_exec_content on
The -P flag makes the boolean change permanent across reboots
If it is a context problem, good, contexts are much nicer to work with because they are more intuitive. It seems to be trial, error and experience as to what actually does what with the SELinux booleans, for example, no idea what user_exec_content actually does.
Use the -Z flag with ls to view the context of your files, eg. ls -alZ.
$ ls -alZ
-rwxrwxr-x. trogdor trogdor unconfined_u:object_r:user_home_t:s0 backup.sh
Here user_home_t is the context for backup.sh. Say you have another directory that has the correct contexts to execute scripts, you can mirror that context onto the ./scripts directory by using:
# chcon -R --reference /onethatworks ./scripts
To double-check the change was made use ls -alZ ./scripts
restorecon -Rv ./scripts
should relabel the filesystem, relabeling all the files and directories recursively to the updated contexts. In this case it is just doing the scripts directory and its contents.
If that works, the changes made here will not survive reboot, and you can use the following to make the change permanent.
# semanage fcontext -a -s system_u -t <context_that_worked> "./scripts(/.*)?
Another option for managing SELinux is to install policycoreutils-gui
so you have access to an selinux configuration gui by entering # system-config-selinux
. By filtering using 'script' I found that many scripts use bin_t as their context. You can also change the enforcing mode with it. My scripts in my home directory execute happily with user_home_t
but I suspect you are somewhere else if you're having these troubles.
Related videos on Youtube
voices
Updated on September 18, 2022Comments
-
voices over 1 year
Okay, so I have a bunch of
bash
&python
scripts that I've written, all just chilling together in one big directory. Well, actually there are separate subdirectories, but they're all nested in this main directory.
So for argument's sake, the directory structure looks something like this:find . -type d
. ./scripts/sh ./scripts/sh/a ./scripts/sh/b ./scripts/sh/c ./scripts/py ./scripts/py/x ./scripts/py/y ./scripts/py/z
Anyway, I tried to make the entire collection of scripts executable, all in one fell swoop with
find
andchmod
:find . -type f -exec chmod +x {} +
Usually, that's all I'd have to do, but I noticed the
+x
bit was still unset. All their permissions still look like this:ls -l ./scripts/py/z
-rw-rw----. 1 root 1015 801 May 7 12:00 script_name.py
Supposedly. the
.
character (trailing the permission flags) implies some kind of SELinux security context, with an access control list, or similar. I checked withgetfacl
, not really knowing what to lool for; first is a directory, second is one of the script files:getfacl -acp ./scripts/py/z && getfacl -acp ./scripts/py/z/*
user::rwx group::rwx other::--x user::rw- group::rw- other::---
I experimented with the following
setfacl
options, to no avail:setfacl --help | grep 'remove'
-x, --remove=acl remove entries from the ACL(s) of file(s) -X, --remove-file=file read ACL entries to remove from file -b, --remove-all remove all extended ACL entries -k, --remove-default remove the default ACL
So, in a situation where the
root
users authority isn't respected, andsudo
is no use, I have to ask; How am I supposed to regain access control of my own files?Migrated from security.stackexchange.com
-
voices about 6 yearsIf this question belongs elsewhere please forward it to the relevant site, rather than closing it. Thanks.
-
forest about 6 yearsClosure can be used alongside migration (there is a vote-to-close reason "Belongs on another site").
-
Admin about 6 yearsNormally the seuid bit only makes sense on executable and not on scripts. What is executed for a python script will be the Python executable.
-
-
Arthur Weborg over 4 yearsGreat answer, thank you for the detailed response! Looking for some clarity, when you mentioned
Permissive mode will still alert you of SELinux context violations
, would that alert be in a log somewhere or part of the failed access for a command? Also, I realize the following goes against the comments suggestions. However, I just couldn't resist as it added some comedic relief to this long debugging trail I've been on:[sudo] password for trogdor
> burninating the countryside, burninating the peasants, burninating all the peoples ... TROGDOOOOOOOOR!!!!