danwalsh


Dan Walsh's Blog

Got SELinux?


New Security Feature in Fedora 18 Part 6: KRB5 Credential Cache Moved under /run/user directory
danwalsh

KRB5 Credential Cache Move

The default location of a user's Kerberos Credential Cache (CC) has moved from /tmp to user directory under /run/user.

Back in the 1980's, when Kerberos was first developed, various login programs were enhanced to talk to the Kerberos servers to authenticate users, and to store credentials (tickets and session keys) that they obtained while doing so in a file, sometimes called a ticket file, but now more commonly called a credential cache (ccache for short), for the user to use during their session.

The cache had to be owned by the user, so that additional tickets obtained by the user could be added to the cache, and so that it could be cleared or just destroyed.

For the sake of users whose credentials were needed for accessing a remote home directory, login programs could not store the credentials in the user's home directory.  Since the only other location where a user could write to was the /tmp directory, the cache file was stored there by default.

Security Problems with the Credential Cache file in /tmp.

There were a couple of problems with storing the cache file in /tmp:

  1. All users of the system can write to /tmp.  To sidestep the possibility that a rogue user could trick the system into writing a user's credentials to an incorrect location, many login facilities would generate uniquely-named credential caches for users.  Others used predictable but different names for various other reasons.
  2. But when the name of a user's credential cache isn't predictable, it can cause problems for services which don't run as part of the user's session, and which therefore can't consult the $KRB5CCNAME environment variable to discover which cache to use.  Services like these, for example rpc.gssd (the daemon which handles the client parts of Kerberized NFS), have historically had to make a best-guess as to what the Kerberos credential cache file's name was, and they had to do that by trawling through /tmp, looking for potential matches.
  3. /tmp can be setup using pam_namespace such that processes running in the "root" namespace will see a different /tmp then the user sees when he logs in.  This can prevent services from even being able to find the Credential Cache.
  4. The /tmp directory is often not a temporary file system.   Logging out of the system or rebooting the system would not guarantee the Credential Cache would be removed/destroyed.

SSSD to the rescue in Fedora 18

In Fedora 18 the Credential Cache file was moved by SSSD, System Security Services Daemon, to /run/user/UID/krb5cc_XXXXXX/tkt.
Where XXXXXX is a random number. 

For example on my box when I execute klist i see the following:

> klist
Ticket cache: DIR::/run/user/3267/krb5cc_ca3a4331e17e8e80cb0c46ea507840bc/tkt
Default principal: dwalsh@REDHAT.COM

Valid starting     Expires            Service principal
10/12/12 12:48:17  10/12/12 22:48:17  krbtgt/REDHAT.COM@REDHAT.COM
    renew until 10/12/12 12:48:17

Note: There are two colons between "DIR" and the path part of the ccache name gives away that the parent of the named path is the directory that's being used to hold the cache file (or possibly more than one cache file).

The main benefit here is that /run/user/3267 and all its sub-directories have a mask of 700 and are owned by dwalsh:dwalsh. No other users know that the cache is there, and they can't tell how big it is or when it was last touched.  This means we don't have to deal with other users trying to mess around in /tmp.

 Secondarily /run is always tmpfs,  if the user logs out cache gets destroyed and if the system crashes the cache file is also gone.

Since the tickets are stored in a predictable path, privileged processes like rpc.gssd have an easy time finding the correct tickets.   And since they are off of /tmp, pam_namespace will not hide the credential cache from the system services.

Finally now SSSD can actually get multiple tickets from different domains and easily store them in the /run directory, allowing a user
to login into multiple kerberos domains at the same time.


New Security Feature in Fedora 18 Part 5: Systemd Secures Journald from attack
danwalsh
Forward Secure Sealing (FSS)

Forward Secure Sealing is a new feature of systemd/journald in Fedora 18.

If your machine is cracked, (Did you disable SELinux?) and a hacker gets administrative control, he wants to cover their tracks, by modifying the system log files.  This presents a problem in that you might not know when the machine was hacked and whether any of your log files have been tampered with.  Before FSS  the only way to know your log files have not been tampered with is to store them on a different machine, IE Setup rsysog and auditlogs to be sent to different machines.  With FSS you can verify the journald logs on your system and know if they have been tampered with.  Even better you will have an idea when the hacker started tampering with them, and which part of the logs files are still valid.

The basic idea is you establish a verification ID and store it externally or just use a QR code and store it on a smart phone.

Read Lennart Poettering posting on Google+ For more explanation.




New Security Feature in Fedora 18 Part 4: FreeIPA/SSSD distributes Confined SELinux Users
danwalsh
FreeIPA now supports the distribution of SELinux Users

Confined SELinux Users was introduced a while ago.  The basic idea is to give users different access depending on the machine they log into. 

Using myself as an example, I regularly login to 5 different machines, not including VMs.  My Laptop, My Test machine, shell.devel.redhat.com, people.redhat.com and people.fedoraproject.com. 
  • people.redhat,com and people.fedoraproject.com: I should login as guest_u:guest_r:guest_t:s0.  These machines are used to share content via the Web Servers.  I should be only allowed to modify my home directory.  I should not have access to the network, setuid applications like su and sudo, or be able to build and execute code in the home directory.
  • shell.devel.redhat.com.  This machine is a shared developer shell machine, to be used by all developers.  I should be allowed to execute content in the home directory and maybe setup and test networking applications, since this is a development machine.  But I am not an administrator, I should not be allowed to execute su or sudo.  user_u:user_r:user_t:s0-s0:c0.c1023  would be a good SELinux user label for this machine.
  • My Laptop and test machines, (holycross and redsox), should either be setup to use unconfined_t or staff_t.  In my case I run them with staff_u:staff_r:staff_t:s0-s0:c0.c1023, and administrator processes as staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023.
The problem with this configuration is that each one of these machines has to be setup individually.  My identity is shared by a directory server and authorization is confirmed by kerberos.  But until now, there was no standard way to setup these confined users on a centralized server.

One big advantage of FreeIPA is it adds identity to machines.  FreeIPA knows the difference between dwalsh on people.redhat.com versus dwalsh on shell.devel.redhat.com.  The FreeIPA team added the ability to store SELinux Users definitions based on User/Machine mappings.

In Fedora 18 you will be able to setup confined users using the FreeIPA gui.



At Red Hat we could setup a user/machine mapping like all users on people.redhat.com will login with the SELinux user/level  guest_u:s0.

SSSD plays a large role in assigning the SELinux User/Level from IPA to the user process at login.

When a user logins to a box say through sshd, sshd uses the pam stack.  One of the first pam modules used is pam_sss. pam_sss sends a request to SSSD telling it that dwalsh is logging in.  SSSD contacts the FreeIPA server and asks what SELinux User/Level should dwalsh get when he logs in.  SSSD takes the string returned and creates a file in /etc/selinux/POLICYTYPE/logins/dwalsh.  During the session of the pam stack, the pam_selinux  module is called.  pam_selinux reads /etc/selinux/POLICYTYPE/logins/dwalsh and tells the kernel to launch the user process with the SELinux User specified in FreeIPA, for example guest_u:guest_r:guest_t:s0.

Currently SSSD only supports FreeIPA for this transaction.  In the future it could be modified to use other sources for SELinux information.
Note: In FreeIPA you can set up a set of the Host Based Access Control rules. These rules define which users (and groups of users) have access to which machines (and groups of machines) via which login services (like ssh, ftp, sudo, su etc.) The administrator can reuse the user-host associations defined in the HBAC rules to define SELinux user mapping rules. This helps to avoid duplicate management and express a notion: user set X can access set of hosts Y and would get SELinux user Z.

I have been asked many times when I have given the Confined SELinux Users talk, about how would you manage confined users in a large environment, now we have a solution.

New Security Feature in Fedora 18 Part 3: New Confined/Permissive Process Domains
danwalsh
Each Fedora we release a bunch of new domains that will run in permissive mode for the release.  When the next release is released, the permissive domains are made enforcing.

In my blog,10 things you probably did not know about SELinux.. #4, I describe how you can interact with permissive domains.

In Fedora 17, we added 11 new permissive domains, 10 of which are now enforcing in Fedora 18.  matahari policy was removed, since the project was cancelled.

Fedora 17 Permissive Domains/ Now Confined in Fedora 18

couchdb_t, blueman_t, httpd_zoneminder_script_t, zoneminder_t, selinux_munin_plugin_t, sge_shepherd_t, sge_execd_t,
sge_job_t, keystone_t, pacemaker_t


Fedora 18 Permissive Domains

   pkcsslotd_t (daemon manages PKCS#11 objects between PKCS#11-enabled applications)
   slpd_t  (Server Location Protocol Daemon)
   sensord_t (Sensor information logging daemon)
   mandb_t  (Cron job used to create /var/cache/man content)
   glusterd_t (policy for glusterd service)
   stapserver_t (Instrumentation System Server) Note: This was back ported to Fedora 17.
   realmd_t (dbus system service which manages discovery and enrollment in realms and domains like Active Directory or IPA)
   phpfpm_t (FastCGI Process Manager)


Fedora 18 Confined Domains
With the open sourcing of OpenShift we have created several new process domains.  openshift controls separation between each of its users and users applications, which means it needs to be confined out of the box.  openshift_t is the type that each application runs as, with a difference MCS label.  I will blog on the openshift policy in the future.
      openshift_app_t, openshift_cgroup_read_t, openshift_initrc_t, httpd_openshift_script_t, openshift_t

Fedora 18 Domains Removed
matahari (Project cancelled)

Fedora 18 Domains Reorganization
We split sandbox and sandboxX policy apart, in order to shrink the policy size. and now disable sandbox policy by default.  We are doing this because not many people use sandbox (Character only version of sandbox, used for pipes and streams) versus sandboxX.  sandbox policy is very big, and disabling by default reduces the size of policy by around 8%.

New Security Feature in Fedora 18 Part 2: Mutual Trusts with Active Directory domains
danwalsh

FreeIPA has a couple of new features that are showing up in Fedora 18.  Support for SELinux Confined User labelling will be covered in a future blog...  In this blog I will be talking about better integration with Windows environments.

I am saddened to realize that there are still people out there using Microsoft Windows!  

My house has been Windows free for a number of years now.  It is a lot darker, but much more secure! :^)

I also have heard that those Windows environments are using Active Directory. 

Well Fedora 18 will make these environments a little more secure.

FreeIPA and Active Directory can be setup with mutual trust.

In Fedora 18 it is possible to create a trust relationship between an FreeIPA and an Active Directory domain.  This means users defined in Active Directory can access resources defined in FreeIPA.  In a future release,  users defined in FreeIPA will be able to access resources defined in Active Directory.  You can manage all of your user accounts in a single place.  If you are using Active Directory to manage your users, you can now use the same user accounts on your Linux boxes.

Fedora 17 FreeIPA used winsync to allow users from an Active Directory domain to access resources in the IPA domain. To achieve this winsync had to replicate the user and password data from an Active Directory server to FreeIPA server and attempt to keep them in sync.  Causing potential race conditions.

In Fedora 18,  SSSD, System Security Services Daemon, has been enhanced to work with AD.  SSSD understands some of the native AD controls and features that it did not understand in the previous Fedoras. 

You can set this up without using FreeIPA at all!

In addition SSSD can work in the environment where it is connected to FreeIPA that is in trust relationships with AD. In this case, SSSD not only recognises users defined in FreeIPA but also recognizes users coming from the trusted AD domains.  SSSD can read user and group directory data directly from the Active Directory server.  

Additionally if you do use FreeIPA you can setup Kerberos cross realm trust.  This allows Single-Sign-On between the Active Directory and the IPA domain.

  • A user from the Active Directory Domain can access kerberized resources from the FreeIPA domain without being asked for a password.
  • If you choose to setup users in the FreeIPA Domain, they will be able to access resources from the Active Directory domain. No need to set POSIX attributes in the Active Directory Domain
  • Single sign-on for all kerberized services is possible
We may never get to full single sign on, where I only have one password asked of me, but this is a step in right direction.

Where does SELinux allow my application to write?
danwalsh
SELinux's Number one goal:

Stop confined application/process from affecting other processes on the system. 


One of the biggest ways that a process can affect another process is by writing content that that process reads. 
  • If a hacked process can write ~/.bashrc in a users home directory; the next time the user logs in, the hacker gets control of a process running as unconfined_t.
  • If a hacked process can write to /etc/httpd/config, the hacker gets control of the Apache process.
Because of this SELinux blocks confined applications the ability to write content, unless the directories/files have the proper labels.

Users want to know:

What label is my application allowed to write to? 
Where on the file system are these labels?


For example in another blog, I got asked today where can mozilla_plugins write their logs?

Well in an effort to better document SELinux policy we have been auto-generating man pages, and have just added a new section called MANAGED FILES.  This section of the man page will list the files/directories that a confined application is able to write.

man mozilla_plugin_selinux
...
MANAGED FILES
       The SELinux user type mozilla_plugin_t can manage  files  labelled  with
       the  following  file types.  The paths listed are the default paths for
       these file types.  Note the processes UID still need to have  DAC  per‐
       missions.

       gnome_home_type

       home_cert_t

            /root/.cert(/.*)?
            /home/[^/]*/.kde/share/apps/networkmanagement/certificates(/.*)?
            /home/[^/]*/.pki(/.*)?
            /home/[^/]*/.cert(/.*)?

       mozilla_home_t

            /home/[^/]*/.java(/.*)?
            /home/[^/]*/.adobe(/.*)?
            /home/[^/]*/.gnash(/.*)?
            /home/[^/]*/.galeon(/.*)?
            /home/[^/]*/.spicec(/.*)?
            /home/[^/]*/.mozilla(/.*)?
...


In Fedora 18, we now have 951 man pages related to SELinux.

> man -k selinux | wc -l
951


We will be generating these Man Pages in Fedora 17 and RHEL6/RHEL6 and hope to put them up on a web site so that "search engines" will have an easier time searching them.

You can generate your own man pages using these tools, which should be showing up in policycoreutils soon.

http://people.fedoraproject.org/~dwalsh/SELinux/genman/segenman
http://people.fedoraproject.org/~dwalsh/SELinux/genman/senetwork.py


New Security Feature in Fedora 18 Part 1: SELinux Systemd Access Control
danwalsh

For Fedora 17 I did a series of blogs on new security features. I guess it is time to start it for Fedora 18.
If you want me to talk about a new security feature,  email dwalsh@redhat.com, or comment on this blog.

New Feature in Fedora 18 SELinux Systemd Access Control.

In previous versions of Fedora/RHEL SELinux could control which processes were able to start/stop services based on the label of the process and the label on the Init Script.

For example NetworkManager (NetworkManager_t) was allowed to execute /etc/init.d/ntp (ntp_initrc_exec_t) but not allowed to access /etc/init.d/httpd (httpd_initrc_exec_t).

With the advent of systemd we lost this ability since systemd starts and stops all services.

We had to allow NetworkManager (NetworkManager_t) to execute systemctl which would send a dbus message to systemd, and systemd would start/stop whatever service NetworkManager requested. Actually we ended up allowing NetworkManager to do everything systemctl could do.   We also wanted to setup confined administrators, but we ended up having to allow them to either start/stop all services or no services.  We could no longer allow the webadm_t to only start/stop httpd_t.

In Fedora 18, we have fixed this by making systemd an SELinux Access Manager.  Now systemd will retrieve the label of the process running systemctl or the process that sent systemd a dbus message.  systemd will then look up the label of the unit file that the process wanted to configure.  Finally systemd will ask the kernel if SELinux policy allows the specific access between the process label and the unit file label.  This means a hacked NetworkManager or any other application that needs to interact with systemd for a specific service can now be confined via SELinux.  Policy writers can use these fined grained controls to confine administrators.

Policy changes.

We have added a new class to SELinux Policy called "service".  The service class has the following permissions defined:

start stop status reload kill load enable disable

This means a policy writer can allow a domain to get the status on a service or start and stop a service, but not enable or disable a service.  This gives us better control then we have ever had in the past.

To demonstrate this, I setup webadm_t as my root process:
Note: For more information on setting up confined users see my other blogs.

# id -Z
staff_u:webadm_r:webadm_t:s0-s0:c0.c1023
# /bin/systemctl status httpd.service
httpd.service - The Apache HTTP Server
      Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
      Active: inactive (dead)
      CGroup: name=systemd:/system/httpd.service

# /bin/systemctl status NetworkManager.service
Failed to issue method call: SELinux policy denies access.


In a separate window running as unconfined_t, I can look at the AVC message created.

# id -Z
staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# ausearch -m user_avc
time->Thu Sep 27 08:54:10 2012
type=USER_AVC msg=audit(1348750450.105:135): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='avc:  denied  { status } for auid=3267 uid=0 gid=0 path="/usr/lib/systemd/system/NetworkManager.service" cmdline="/bin/systemctl status NetworkManager.service" scontext=staff_u:webadm_r:webadm_t:s0-s0:c0.c1023 tcontext=system_u:object_r:NetworkManager_unit_file_t:s0 tclass=service  exe="/usr/lib/systemd/systemd" sauid=0 hostname=? addr=? terminal=?'

And of course you could use audit2allow to write policy to allow this access.

audit2allow -la
#============= webadm_t ==============
allow webadm_t NetworkManager_unit_file_t:service status;

# audit2allow -laR
#============= webadm_t ==============
networkmanager_systemctl(webadm_t)


Make sure you have the latest systemd and selinux-policy to try this out.  These are my current versions:

rpm -q selinux-policy systemd
selinux-policy-3.11.1-26.fc18.noarch
systemd-191-2.fc18.x86_64


Running unconfined scripts from a confined domain
danwalsh
I received the following email from an engineer named Marko.

I've got a program (actually a shell script) which does various things and sudoers is configured so that users can run it without a pw being asked. By using sudo from the cmd line everything works as expected.

However, if the script is invoked by udev rules (and thus run as root) under certain circumstances, it fails on several cases due to AVCs as the commands it is trying to execute won't work or the services it starts/stops fail partially as the context (udev_t) is not what it'd be when run with sudo from the command line. Examples include inability to communicate with dbus, accessing log/config files, etc. So figuring out all of those would be quite a task and if the local program is later changed it might require even more policy changes.

So what would a custom policy look like for a program "foo" so that it would work equally well when invoked by udev like it now works when a user invokes it from the command like with sudo? Any examples, blog posts, howtos, etc to look at?


Basically since his users are most likely running as unconfined_t, the sudo command is running the script as unconfined_t and SELinux is not blocking anything.  When he runs the command out of udev, it is running as udev_t and udev_t is not allowed the access.

To solve this problem, Marko has three choices:
  1. Add the allow rules to allow udev to have all the access required to run his application
  2. Write policy for his application and transition from udev and unconfined_t to this new domain.
  3. Write policy to allow udev_t to transition to unconfined_t when running only his application.
Since Marko did not want to all udev scripts this access, he chose not to do 1.  Marko decided it would be to difficult to do 2 and difficult to maintain, so he chose to do 3.

Here is the original policy written by Marko.

# cat myapp.fc /usr/sbin/myapp --
gen_context(system_u:object_r:myapp_exec_t, s0)

# cat myapp.te
policy_module(myapp, 1.0.0)

require {
    type fs_t; type setfiles_t;
    type udev_t; type unconfined_t;
    class process transition;
}

type myapp_exec_t;

allow setfiles_t myapp_exec_t:file { getattr relabelto };
allow myapp_exec_t fs_t:filesystem { associate };

allow unconfined_t myapp_exec_t:file *;

domain_auto_trans(udev_t, myapp_exec_t, unconfined_t);


Not bad. 

The first problem I notice is lots of rules around myapp_exec_t.  Since the myapp_exec_t was never defined as a particular TYPE of type.  Since myapp_exec_t is planned to be used on a file or directory it needs to have the attribute  file_type.  All domains that interact with all files/directories, have rules defined in policy which allow them to interact with the attribute file_type.  You can add the file_type attribute to a file by using the files_type(myapp_exec_t) interface.  This will eliminate most of the rules involving myapp_exec_t.

As a rule of thumb, anytime you define a new type in policy you should call an interface to define the "TYPE" of the type.  domain_type() for processes, files_type for files/directories, dev_node() for devices corenet_port() for network ports etc.

Here is a my simpler policy.

policy_module(myapp, 1.0.1)
gen_require(`
  type udev_t;
  type unconfined_t;
  role system_r;
')

type myapp_exec_t;
files_type(myapp_exec_t)

domain_auto_trans(udev_t, myapp_exec_t, unconfined_t);
allow unconfined_t myapp_exec_t:file entrypoint;
role system_r types unconfined_t;


The domain_auto_trans rule tells the SELinux kernel, when a process labeled udev_t executes a file labeled myapp_exec_t, transition the new process to unconfined_t. 

SELinux controls the labels of "entrypoint", so we need to state that myapp_exec_t is an entrypoint to the unconfined_t domain.
For a further description of the entrypoint access see: SELinux By Example 2.2.4

Finally I added the role definition for system_r, since udev_t will be running as system_r, when it executes myapp_t it will attempt to run unconfined_t was system_u:system_r:unconfined_t:s0.  roles system_r types unconfined_t, states that the unconfined_t type can be executed in the system_r role.

While the ideal solution for this problem from a security point of view would have been to write policy for myapp_t, and have unconfined_t and udev_t transition to this domain, as a work around and not shutting SELinux off this is a decent alternative.

Note:  When ever you write a shell script that will have more privs then the calling app, you should be really carefull that the calling application can not effect the running app.  The script needs to up its environment and ignores stuff from the calling program, if the script takes arguments you must be sure these arguments are handled properly and can not get the script to do something unexpected.  SELinux will protect you somewhat but you need to be careful.  Every python scripts I write, I always use "#! /usr/bin/python -Es" for example.  Apple has a nice page on this.

Article I wrote on Harvard PAAS.
danwalsh
Occasionally I write longer articles that I feel are too long for a blog...

Harvard CS Uses PAAS and Fedora.

Kind of nice to get the message out to other people also.  Thanks to OpenSource.com for publishing it.



SELinux Apache Security Study
danwalsh
Kirill Ermakov recently posted a study he did of SELinux protections against a vulnerable Apache server.

After reading the study you might come a way with the idea that SELinux did not block anything.  After all it allowed the hacked process to read /etc/passwd.  SELinux also allowed a hacked Apache to upload a file and execute it.

This points out what most people do not understand about SELinux.  SELinux does not necessarily block errors in applications from happening.  SELinux will just contain them.  If you are able to subvert the Apache application then you can become the Apache application and will have the rights allowed to the apache application.  In his examples he was able to take over the Apache server and do what an apache server needs to do, including reading the /etc/passwd file.  A better test would be:
  • Try to connect to a few network ports like the mail port  - Out of the box we should not allow Apache to connect to many network ports.
  • Read /secrets/mysecrets  - Random content on the file system should not be readable by Apache
  • Read /home/dwalsh/creditcard.txt - Random content in a users home dir should not be readable by apace
  • Read /var/lib/mysql/mysqld.data. - Database data should not be readable by Apache except if allowed through a constricted path like a unix domain socket.
  • Try to run su or sudo, or strace, or network sniffer.
All things the Apache server should not be allowed to do.

If an Apache server has a bug in its code, then it can be owned whether or not SELinux is in enforcing mode, the goal is to confine the attacker to just the Apache data and not allow him to attack other data or processes on the system.

Apache Booleans

Now lets look further at Apache SELinux policy configuration.  A while ago I wrote a blog on "Security vs Usability", in which I explained the continuing conflict between setting up a machine with security as tight as possible, but not so tight as forcing people to turn the security off.  When we ship SELinux policy we have to make compromises on security, to avoid the "Just turn it off crowd".
Lets look at some of these compromises,  and maybe explain how you could tighten the security in your Apache.

Out of the box SELinux in RHEL6 has the following boolean settings for an Apache server.

On RHEL6 we have

# semanage boolean -l | grep httpd | grep -v off
httpd_enable_cgi               (on   ,   on)  Allow httpd cgi support
httpd_dbus_avahi               (on   ,   on)  Allow Apache to communicate with avahi service via dbus
httpd_unified                      (on   ,   on)  Unify HTTPD handling of all content files.
httpd_builtin_scripting         (on   ,   on)  Allow httpd to use built in scripting (usually php)
httpd_tty_comm                  (on   ,   on)  Unify HTTPD to communicate with the terminal. Needed for entering the passphrase for certificates at the terminal.


On RHEL7 and Fedora we have

#  semanage boolean -l | grep httpd | grep -v off
httpd_enable_cgi               (on   ,   on)  Allow httpd cgi support
httpd_graceful_shutdown    (on   ,   on)  Allow HTTPD to connect to port 80 for graceful shutdown
httpd_builtin_scripting        (on   ,   on)  Allow httpd to use built in scripting (usually php)


I was interested on how he was able to execute tmp_t content.

# sesearch -A -s httpd_t -t httpd_tmp_t -p execute -C
Found 1 semantic av rules:
DT allow httpd_t httpd_tmp_t : file { ioctl read getattr lock execute
execute_no_trans open } ; [ httpd_tmp_exec httpd_builtin_scripting && ]

# sesearch -A -s httpd_sys_script_t -t httpd_tmp_t -p execute -C
Found 1 semantic av rules:
DT allow httpd_sys_script_t httpd_tmp_t : file { ioctl read getattr lock execute execute_no_trans open } ; [ httpd_tmp_exec httpd_enable_cgi && ]


Reading this, it looks like SELinux should have blocked the ability for the Apache process or a cgi script to execute the content by default. IE You would need to turn on the httpd_tmp_exec boolean as well as the httpd_enable_cgi boolean.

But examining further the booleans, I wanted to know what content could httpd_t (Apache) or httpd_sys_script_t (Apache CGI Scripts) could execute and write.

# sesearch -A -s httpd_sys_script_t -t httpd_sys_content_t -p execute -C
Found 3 semantic av rules:
   allow httpd_sys_script_t exec_type : file { ioctl read getattr lock execute execute_no_trans open } ;
   allow httpd_sys_script_t httpd_sys_content_t : file { ioctl read getattr lock execute entrypoint open } ;
ET allow httpd_sys_script_t httpd_sys_content_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ; [ httpd_enable_cgi httpd_unified && ]


So the problem here is actually httpd_unified.  httpd_unified basically says to SELinux allow Apache processes to treat all Apache content with the same rules.  In RHEL7 we feel users are familiar enough with SELinux to disable the httpd_unified boolean by default.   If this boolean is off, then users would have to label files/directories as httpd_sys_content_rw_t if they wanted Apache to be able to write to a directory rather then the read/only label of httpd_sys_content_t.  With the boolean on, Apache processes can read/write/execute all httpd_sys_content* labels.

If you are not uploading data to Apache then it is a good idea to turn off this boolean.

# setsebool -P httpd_unified 0

Now lets look at other booleans that are turned on by default in RHEL6. (And RHEL7 for that matter).

httpd_enable_cgi

This boolean enables your Apache server to run cgi scripts.  We leave this on by default because out of the box, any person running Apache would blow up with a permission denied when they tried to execute a cgi script.  If you were not running cgi scripts, it would be a good idea to turn this off.

# setsebool -P httpd_enable_cgi 0

httpd_builtin_scripting

This boolean your Apache server to run builtin scripting, mod_php, mod_python, mod_perl ...
We leave this on by default because out of the box, any person running Apache would blow up with a permission denied when they tried to execute a php script.


If you are just allowing users to view Apache content, then you really should turn off both of these booleans.

# setsebool -P httpd_builtin_scripting 0

httpd_tty_comm                 

This boolean allows httpd to talk to the terminal that launches it.  The risk here is a hacked apache server could trick an admin into entering his password, by putting a passwd: prompt on the screen and then reading the admins commands.  This access is necessary for people who setup apache servers which require a passwd from the admin when they start, it also allow apache to output errors to the screen, like the configuration is screwed up.  In Fedora and RHEL7 this output is handled by systemd, so this access is no longer needed, and can be disabled by default.  If your apache server does not require a password at start and you know that your config is correct you should turn this boolean off.

# setsebool -P httpd_tty_comm 0

httpd_dbus_avahi

This boolean allows apache to communicate with the avahi daemon over DBUS.  This boolean should have been disabled by default, but most likely does not add much risk.  It is turned off by default in Fedora and RHEL7.

# setsebool -P httpd_dbus_avahi 0

Bottom line as people grow to peoples understanding of SELinux, we can slowly tighten up the controls...

You are viewing danwalsh