Re: SELinux MLS for Apache Process

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Stephen ,

Many thanks for the detailed information , it has been very useful . Infact I have tested your steps in a similar environment (CentOS 6.10 , see versions below) as of yours in a Virtual machine based on Virtualbox  , I have reached to the step where the selinux module is installed on doing the range transition to enforce httpd to run on s4-s5:c1,c2 .

Unfortunately I still see the range transition denied errors in the audit logs (After installing the selinux module) and I do not see any errors related to httpd trying to perform writes on various directories/files that are labeled s0 as per your explanation .

Kindly see the details below 

[root@msc-ishara-system1 ~]# sestatus -v
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        mls

Process contexts:
Current context:                staff_u:sysadm_r:sysadm_t:s4-s5:c1,c2
Init context:                   system_u:system_r:init_t:s0-s15:c0.c1023
/sbin/mingetty                  system_u:system_r:getty_t:s0-s15:c0.c1023
/usr/sbin/sshd                  system_u:system_r:sshd_t:s0-s15:c0.c1023

File contexts:
Controlling term:               staff_u:object_r:user_devpts_t:s4
/etc/passwd                     system_u:object_r:etc_t:s0
/etc/shadow                     system_u:object_r:shadow_t:s0
/bin/bash                       system_u:object_r:shell_exec_t:s0
/bin/login                      system_u:object_r:login_exec_t:s0
/bin/sh                         system_u:object_r:bin_t:s0 -> system_u:object_r:shell_exec_t:s0
/sbin/agetty                    system_u:object_r:getty_exec_t:s0
/sbin/init                      system_u:object_r:init_exec_t:s0
/sbin/mingetty                  system_u:object_r:getty_exec_t:s0
/usr/sbin/sshd                  system_u:object_r:sshd_exec_t:s0



Dist: CentOS release 6.10 (Final)
Kernel : 2.6.32-754.6.3.el6.x86_64
SELinux MLS Policy RPM: selinux-policy-mls-3.7.19-312.el6.noarch
SELinux Policy version: 24


[root@msc-ishara-system1 ~]# id -Z
staff_u:sysadm_r:sysadm_t:s4-s5:c1,c2


[root@msc-ishara-system1 ~]# ls -lZ /usr/sbin/httpd
-rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd



[root@msc-ishara-system1 ~]# which run_init
/usr/sbin/run_init
[root@msc-ishara-system1 ~]# ls -lZ /usr/sbin/run_init
-rwxr-xr-x. root root system_u:object_r:run_init_exec_t:s0 /usr/sbin/run_init



[root@msc-ishara-system1 /]# cat httpdtrans.te
policy_module(httpdtrans, 1.0)

require {
        type initrc_t;
        type httpd_exec_t;
        type httpd_t;
}

range_transition initrc_t httpd_exec_t:process s4 - s5:c1,c2;

mls_rangetrans_source(initrc_t)
mls_rangetrans_target(httpd_t)



[root@msc-ishara-system1 /]# semodule -l | grep -i httpd
httpdtrans    1.0   



[root@msc-ishara-system1 ~]# sesearch --type | grep -i initrc_t | grep -i httpd_exec
   type_transition initrc_t httpd_exec_t : process httpd_t;


[root@msc-ishara-system1 ~]# id -Z
staff_u:sysadm_r:sysadm_t:s4-s5:c1,c2


[root@msc-ishara-system1 ~]# run_init /etc/init.d/httpd start
Authenticating root.
Password:
execvp: Permission denied


[root@msc-ishara-system1 ~]# ausearch -i -m AVC -ts recent
----
type=SYSCALL msg=audit(11/08/2018 18:32:36.457:160) : arch=x86_64 syscall=execve success=no exit=-13(Permission denied) a0=0x7ffd2309581a a1=0x7ffd230949b0 a2=0x7ffd230949c8 a3=0x7ffd23094610 items=0 ppid=1802 pid=3074 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=3 comm=run_init exe=/usr/sbin/run_init subj=staff_u:sysadm_r:run_init_t:s4-s5:c1,c2 key=(null)
type=AVC msg=audit(11/08/2018 18:32:36.457:160) : avc:  denied  { transition } for  pid=3074 comm=run_init path=/etc/rc.d/init.d/httpd dev=dm-0 ino=262967 scontext=staff_u:sysadm_r:run_init_t:s4-s5:c1,c2 tcontext=system_u:system_r:initrc_t:s0-s15:c0.c1023 tclass=process


[root@msc-ishara-system1 /]# cat  /var/log/audit/audit.log | grep -i httpd | grep -i write
[root@msc-ishara-system1 /]#

[root@msc-ishara-system1 /]# cat  /var/log/audit/audit.log | grep -i httpd | grep -i append
[root@msc-ishara-system1 /]#



I followed all your steps but not sure whether I have missed something which I still couldn't point out


Also regarding the constraint rules , now I understand how it works after your explanation about the httpd process running in the sshd_t domain :) . So therefore I have installed the SRC rpm to see the types for mlsfileread attribute to understand how it works .


[root@msc-ishara-system1 serefpolicy-3.7.19]# cd /root/rpmbuild/BUILD/serefpolicy-3.7.19

[root@msc-ishara-system1 serefpolicy-3.7.19]# grep -ir 'mlsfileread' ./tmp/all_te_files.conf  | grep -v toclr | sed -e 's/typeattribute//g' | sed -e 's/mlsfileread//g' | sed -e 's/attribute//g' | grep -i ssh
     sshd_t ;


So in that case If i have understood it right , I need to run the httpd process in a domain (type) which does NOT belong to the 'mlsfileread' attribute right ? Can we have it done using the same "httpdtrans.te" file you shared ?


Thanks & Regards
Mario Roshane Ishara Fernando




On Wed, Nov 7, 2018 at 9:12 PM Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:
On 11/7/18 2:04 AM, Ishara Fernando wrote:
> Thanks Stephen , so below are the details of my SELinux setup
>
>
> *Centos Version* : CentOS release 6.2 (Final)
> *Kernel version* : 2.6.32-220.el6.x86_64
> *RPM package* : selinux-policy-mls-3.7.19-312.el6.noarch

That's quite old.  Any particular reason you aren't at least on the
latest CentOS 6.x release if not CentOS 7.x?
CentOS/Fedora/RHEL-specific questions likely should go to the Fedora
selinux list,
https://lists.fedoraproject.org/admin/lists/selinux.lists.fedoraproject.org/

>
> *cat /etc/selinux/mls/contexts/securetty_types *
> console_device_t
> sysadm_tty_device_t
> user_tty_device_t
> staff_tty_device_t
> auditadm_tty_device_t
> secureadm_tty_device_t
> user_devpts_t
> sshd_devpts_t
>
> *
> *
> *sestatus -v *
> SELinux status:                 enabled
> SELinuxfs mount:                /selinux
> Current mode:                   enforcing
> Mode from config file:          enforcing
> Policy version:                 24
> Policy from config file:        mls
>
> Process contexts:
> Current context:                system_u:system_r:sshd_t:s0-s15:c0.c1023

Your shell shouldn't be running in sshd_t; sshd should have transitioned
to a user context (like root:sysadm_r:sysadm_t:... or
staff_u:staff_r:staff_t:... or user_u:user_r:user_t:...).  Were there
errors from sshd in /var/log/secure or elsewhere?

> Init context:                   unknown (Permission denied)
>
> File contexts:
> Controlling term:               system_u:object_r:sshd_devpts_t:s0
> /etc/passwd                     system_u:object_r:etc_t:s0
> /bin/bash                       system_u:object_r:shell_exec_t:s0
> /bin/sh                         system_u:object_r:bin_t:s0 ->
> system_u:object_r:shell_exec_t:s0
> /usr/sbin/sshd                  system_u:object_r:sshd_exec_t:s0
>
>
> *Regarding the httpd process , i started the process by switching to a
> new role as follows , so that's why it has obtained the sshd_t type on
> the 'httpd' process*
>
> [root@msc-ishara-system1 ~]# newrole -l s4-s5:c1,c2
> Password:
>
> [root@msc-ishara-system1 ~]# id -Z
> system_u:system_r:*sshd_t*:s4-s5:c1,c2*
> *
> [root@msc-ishara-system1 ~]# /etc/init.d/httpd start

You first need to be in a proper user context before you do anything
else.  Otherwise any processes you start are likely to be in the wrong
context too.

I created a CentOS 6.10 VM, installed the mls policy, changed
/etc/selinux/config to specify permissive and mls, touched
/.autorelabel, rebooted to relabel filesystems, then changed
/etc/selinux/config to enforcing and rebooted again.  If I try to ssh in
as root, I get an error ("Unable to get valid context for root") and the
connection is closed; /var/log/secure contains some additional error
reporting from sshd.  That seems like a bug in selinux-policy-mls.

If I run the following command:
# semanage login -m -s staff_u root # map root to staff role
then I can ssh in as root albeit with some errors about accessing /root
files.

Then I can do the following to switch to the sysadm role:
# newrole -r sysadm_r

I can't directly run /etc/init.d/httpd at all:
# /etc/init.d/httpd start
-bash: /etc/init.d/httpd: Permission denied

Or via service:
# service httpd start
env: /etc/init.d/httpd: Permission denied

I think -mls policy required the use of run_init to run init scripts in
the proper context, ala the original SELinux policy:
# run_init /etc/init.d/httpd start
# ps -eZ | grep httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1704 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1706 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1707 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1708 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1709 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1710 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1711 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1712 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0-s15:c0.c1023 1713 ? 00:00:00 httpd

However, if I switch levels before trying to do this, it fails:
# newrole -l s4-s5:c1,c2
# run_init /etc/init.d/httpd restart
execvp: Permission denied

And the denial is due to the change in levels:
# ausearch -i -m AVC -ts recent
type=SYSCALL msg=audit(11/07/2018 09:37:14.703:318) : arch=x86_64
syscall=execve success=no exit=-13(Permission denied) a0=0x7fffaf68a871
a1=0x7fffaf6893d0 a2=0x7fffaf6893e8 a3=0x7fffaf689030 items=0 ppid=1824
pid=1838 auid=root uid=root gid=root euid=root suid=root fsuid=root
egid=root sgid=root fsgid=root tty=pts0 ses=7 comm=run_init
exe=/usr/sbin/run_init subj=staff_u:sysadm_r:run_init_t:s4-s5:c1,c2
key=(null)
type=AVC msg=audit(11/07/2018 09:37:14.703:318) : avc:  denied  {
transition } for  pid=1838 comm=run_init path=/etc/rc.d/init.d/httpd
dev=dm-0 ino=133288 scontext=staff_u:sysadm_r:run_init_t:s4-s5:c1,c2
tcontext=system_u:system_r:initrc_t:s0-s15:c0.c1023 tclass=process

run_init always tries to run the init script in the initrc_context, so
you'd lose the caller's level even if you altered policy to allow this.

If I define a range_transition policy rule instead to automatically
start httpd in that level:
# cat > httpdtrans.te <<EOF
policy_module(httpdtrans, 1.0)

require {
        type initrc_t;
        type httpd_exec_t;
        type httpd_t;
}

range_transition initrc_t httpd_exec_t:process s4 - s5:c1,c2;

mls_rangetrans_source(initrc_t)
mls_rangetrans_target(httpd_t)
EOF
# make -f /usr/share/selinux/devel/Makefile httpdtrans.pp
# semodule -i httpdtrans.pp

And then try to start httpd:
# run_init /etc/init.d/httpd start
Starting httpd:                                            [FAILED]

it still fails but due to various denials when httpd tries to write to
various directories/files that are labeled s0.

# ausearch -i -m AVC -ts recent
type=SYSCALL msg=audit(11/07/2018 10:13:37.915:445) : arch=x86_64
syscall=open success=no exit=-13(Permission denied) a0=0x5565fcd6a070
a1=O_RDWR|O_CREAT|O_EXCL a2=0600 a3=0x7ffd99b94c80 items=0 ppid=2324
pid=2325 auid=root uid=root gid=root euid=root suid=root fsuid=root
egid=root sgid=root fsgid=root tty=(none) ses=7 comm=httpd
exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s4-s5:c1,c2 key=(null)
type=AVC msg=audit(11/07/2018 10:13:37.915:445) : avc:  denied  { write
} for  pid=2325 comm=httpd name=tmp dev=dm-0 ino=12
scontext=system_u:system_r:httpd_t:s4-s5:c1,c2
tcontext=system_u:object_r:tmp_t:s0-s15:c0.c1023 tclass=dir
----
type=SYSCALL msg=audit(11/07/2018 10:13:37.919:450) : arch=x86_64
syscall=open success=no exit=-13(Permission denied) a0=0x5565fcde6e88
a1=O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC a2=0666 a3=0x7f9275f59af0 items=0
ppid=2324 pid=2325 auid=root uid=root gid=root euid=root suid=root
fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=7 comm=httpd
exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s4-s5:c1,c2 key=(null)
type=AVC msg=audit(11/07/2018 10:13:37.919:450) : avc:  denied  { append
} for  pid=2325 comm=httpd name=error_log dev=dm-0 ino=261766
scontext=system_u:system_r:httpd_t:s4-s5:c1,c2
tcontext=system_u:object_r:httpd_log_t:s0 tclass=file

You'd have to run httpd with a private /tmp and label httpd's persistent
data directories/files appropriately to make that work. Doing this
without using containers or VMs looks painful.  And if using
containers/VMs, you'd get MCS labeling and isolation for free under the
default targeted policy, without needing to use MLS.

>
>
> [root@msc-ishara-system1 ~]# ps auxZ  |  grep -i httpd
> system_u:system_r:*sshd_t*:s4-s5:c1,c2 root 29220 0.0  0.4 262888  9244
> ?        Ss   00:18   0:00 /usr/sbin/httpd
> system_u:system_r:*sshd_t*:s4-s5:c1,c2 apache 29223 0.0  0.2 262888 5264
> ?       S    00:18   0:00 /usr/sbin/httpd
>
> *
> *
> *And on the mlsconstraint statements for file read , i see the following
> constrain *
>
> mlsconstrain { file } { read getattr execute  }
> (  l1 l2  dom  t1 { sysadm_t aide_t system_cronjob_t ksmtuned_t sssd_t
> virtd_t xserver_t } ==  h1 l2  dom  &&  ||  t1 { bootloader_t
> pam_console_t logrotate_t dmidecode_t iptables_t auditadm_wm_t
> myuser_wm_t setfiles_mac_t initrc_t mcelog_t secadm_t sysadm_t fsadm_t
> getty_t kudzu_t lvm_t mdadm_t quota_t rpm_t xdm_t xguest_wm_t
> myuser2_wm_t setsebool_t newrole_t setrans_t user_wm_t local_login_t
> rpm_script_t tmpreaper_t devicekit_disk_t NetworkManager_t audisp_t
> auditd_t kernel_t crond_t cupsd_t hald_t init_t kdump_t klogd_t mount_t
> rshd_t sshd_t udev_t fsdaemon_t sssd_selinux_manager_t load_policy_t
> remote_login_t secadm_wm_t readahead_t system_dbusd_t staff_wm_t
> setfiles_t semanage_t consoletype_t auditctl_t rlogind_t vbetool_t } == 
> ||  t2 { cupsd_var_run_t sssd_var_lib_t kvm_device_t null_device_t
> zero_device_t system_dbusd_var_run_t devlog_t devtty_t tmpfs_t xdm_t
> vhost_device_t httpd_bool_t tun_tap_device_t faillog_t setrans_t
> qemu_var_run_t anon_inodefs_t setrans_var_run_t crond_t cupsd_t ptmx_t
> *sshd_t* sssd_t virt_log_t system_dbusd_t proc_numa_t security_t
> initctl_t sudo_db_t syslogd_t xserver_t } ==  || );

Due to your kernel/policy version, the attribute names aren't preserved
in the binary policy constraints so the above is the expanded list of
types instead of showing the attribute name used in the source policy.
You can see the attribute name in the source policy from the .src.rpm or
from the upstream refpolicy.  As noted above, sshd_t is exempted by the
constraint so it isn't being confined for MLS file reads.

> Also I would like to understand about the precedence check by the
> SELinux security server , assume if a *type is allowed* to read the file
> by the mlsconstrain statements as shown above , then does the security
> server check and compare for the security levels as well of the source
> process and the destination ? (In this case the apache process runs in
> *s4-s5:c1,c2 *, the linux user running the curl is mapped on SELinux
> user *s4-s5:c1,c2 *and the php file : /var/www/html/info.php is on *s0:c3 *)

The permission has to first be allowed by a TE allow rule, and then any
constraints on the permission are evaluated and the permission is only
allowed if all such constraints evaluate to true.  This constraint
includes the dominance comparison. In source form, the constraint is:
# the file "read" ops (note the check is dominance of the low level)
mlsconstrain { file } { read getattr execute }
         (( l1 dom l2 ) or
          (( t1 == mlsfilereadtoclr ) and ( h1 dom l2 )) or
          ( t1 == mlsfileread ) or
          ( t2 == mlstrustedobject ));

which means:
File read/getattr/execute permission are only allowed if:
1) the process low-level (l1) dominates the file low-level (l2), or
2) the process type (t1) has the mlsfilereadtoclr (read-up-to-clearance)
atttribute and the process high-level (h1) dominates the file low-level
(l2), or
3) the process type (t1) has the mlsfileread (read-up) attribute, or
4) the file type (t2) has the mlstrustedobject (e.g. /dev/null) attribute.

> **
>
> So in that case , any suggestions to bypass the constrain rule ?
>
> I tried to create a new SELinux role so that it has no types at all
> (This didn't work though as it gets the selinux types for *user_u* for
> some reason) . Then I was planning to add just 1 new type (eg:
> testuser_t) and then map this new 'type' to the new SELinux role and
> then map this role to a Linux User . So in that case the Linux User will
> have one single type accessible and then I can run the 'curl' command on
> the apache endpoint to see if the Bell Lapadula condition works :) .

You would just need apache to run in its own domain (or any other domain
that lacks mlsfileread).  The problem you are currently having is that
it is running in sshd's domain.
_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux