Understanding

SELinux

Daniel J Walsh

Red Hat Consulting Engineer

Twitter: @rhatdan

Blog: danwalsh.livejournal.com

Email: dwalsh@redhat.com

What is SELinux trying to tell you?

SELinux 4 Things

1. You have something wrong with your labels

2. You changed the system defaults
but did not tell SELinux about it

3. Applications or SELinux
has bugs
that have not been fixed yet

4. You could be COMPROMIZED!!!

Everyone Please Stand Up

Repeat with me

SELinux is a LABELING system

Every Process has a LABEL

Every File, Directory, System object has a LABEL

Policy rules control access between labeled processes and labeled objects

The Kernel enforces the rules

SELinux is a labeling System

If the labels are wrong, SELinux will generate issues.

Solution? Fix your labels.

Your visual guide to SELinux Policy Enforcement
http://opensource.com/business/13/11/selinux-policy-guide
SELinux Coloring Book:
http://people.redhat.com/duffy/selinux/selinux-coloring-book_A4-Stapled.pdf

SELinux Labels - Type Field

user:role:type:level

system_u:system_r:httpd_t:s0

system_u:object_r:httpd_sys_rw_content_t:s0

Type Enforcement

Type Enforcement

Type Enforcement

Type Enforcement

Type Enforcement

Type Enforcement

SELinux Labels - Level

user:role:type:level

system_u:system_r:svirt_t:s0:c1,c2

system_u:object_r:svirt_sandbox_file_t:s0:c1,c2

MCS Enforcement

Multi Category Security Based on Multi Level Security (MLS)

MCS Enforcement

MCS Enforcement

MCS Enforcement

MCS Enforcement

MCS Enforcement

Sadly not everyone wants to store their content where

Dan Walsh wants or expects :^(

Every process and object on
machine has a label

If your files are not labeled correctly
access might be denied

Alternative paths for confined domains?
SELinux needs to KNOW.

http files in /srv/myweb instead of /var/www/html?
Tell SELinux.

# semanage fcontext -a -t httpd_sys_content_t '/srv/myweb(/.*)?'
# restorecon -R /srv/myweb

File labeling

SELinux File labels definitions stored in
/etc/selinux/targeted/contexts/file_context.*

semanage fcontext command is used to change default labeling

File labels are stored in the inode Xattrs

restorecon command to apply labels to the file system objects

# semanage fcontext -a -t httpd_sys_content_t '/srv/myweb(/.*)?'
# restorecon -R /srv/myweb

File labeling

Acme Inc uses Tivoli

Tivoli stores log files in /var/ibm/tivoli/common/COD/logs

I see AVCs on confined domains denied access var_t files

What is the label of /var/logs directory?

ls -ldZ /var/log
drwxr-xr-x. 16 root root system_u:object_r:var_log_t:s0 4096 Dec  2 10:48 /var/log
# semanage fcontext -a -t var_log_t '/var/ibm/tivoli/common/COD/logs(/.*)?'
# restorecon -R -v /var

Problem solved

default_t files

By default all non distribition directories in "/"
will be labeled as default_t

SELinux has no idea what type of content is in a default_t file

All confined domains are blocked from accessing default_t files

default_t files

Acme Inc moves it Home Dirs to /u/home/

This means all home directory content is labeled default_t

Confined applications like sshd and httpd are blocked from read/writing default_t files

We probably want to label /u/home the same we label /home directory

File labeling equivalence

Some times you want entire directory trees to be labeled the same as another directory tree

semanage fcontext -a -t home_root_t '/u(/.*)?'

semanage fcontext -a -e /u/home /home

Label all files under /u/home as if they were under /home

/u/home/dwalsh/.ssh will get labeled ssh_home_t

/u/home/dwalsh/pubic_html will get labeled httpd_user_content_t

2. You changed the system defaults
but did not tell SELinux about it

SELinux needs to know

Booleans

Booleans are If-Then-Else rules written into SELinux

If you want httpd to send email

# setsebool -P httpd_can_sendmail 1

If you want user to use ftp to access homedir

# setsebool -P ftp_home_dir 1

How do I know what Booleans are available

semanage boolean --list lists all booleans with explanation

man httpd_selinux lists booleans for the Apache application

setroubleshoot will tell you if there is a boolean available for an AVC

audit2allow -i /var/log/audit/audit.log will tell you if there is a boolean available for an AVC

Audit2allow searches for booleans that will allow the Access being denied in an AVC.

		  
# grep ftp /var/log/audit/audit.log | audit2allow 
#============= ftpd_t ==============
#!!!! This avc can be allowed using one of the these booleans:
#     allow_ftpd_full_access, ftp_home_dir
allow ftpd_t home_root_t:dir search;

Used audit2allow to diagnose issues with
Apache running passenger.

setsebool -P httpd_run_stickshift=1 httpd_execmem=1 allow_httpd_write_anon_write=1

Problem solved

2. You changed the system defaults
but did not tell SELinux about it

SELinux needs to know

Port types

I want sshd to listen on port 55

Use "semanage port" to change the port definition for application

# semanage port -a -t ssh_port_t -p tcp 55

How do I tell what port types are available

man sshd_selinux lists ports for the Apache application

semanage port --list lists ports for the system

port prefix usually matches the type associated with the confined domain

In RHEL7 sepolicy network very handy

sepolicy network to display port information

sepolicy network -t ssh_port_t 
ssh_port_t: tcp: 22
		  

sepolicy network to display confined process network port information

sepolicy network -d sshd_t
sshd_t: tcp name_connect
	111 (portmap_port_t) -- Allowed False [ nis_enabled=0 ]
	113 (auth_port_t) -- Allowed False [ daemons_use_tcp_wrapper=0 || nis_enabled=0 ]
	53 (dns_port_t)
	80, 81, 443, 488, 8008, 8009, 8443, 9000 (http_port_t) -- Allowed False [ nis_enabled=0 || authlogin_yubikey=0 ]
	88, 750, 4444 (kerberos_port_t) -- Allowed True [ nis_enabled=0 || kerberos_enabled=1 ]
	389, 636, 3268, 7389 (ldap_port_t) -- Allowed False [ nis_enabled=0 || authlogin_nsswitch_use_ldap=0 ]
...
sshd_t: tcp name_bind
	22 (ssh_port_t)
	5900-5983, 5985-5999 (vnc_port_t)
	6000-6020 (xserver_port_t)
	32768-61000 (ephemeral_port_t) -- Allowed False [ nis_enabled=0 ]
...

3. Applications or SELinux has bugs
that have not been fixed yet

SELinux policy can have bugs

Unusual Code Paths

Configurations that we never tried

Redirection of stdout

3. Applications or SELinux has bugs
that have not been fixed yet

Applications have bugs

Leaked File Descriptors

Executable Memory

Badly built libraries

Report the bugs in Bugzilla so we can fix them

3. Applications or SELinux has bugs
that have not been fixed yet

You can tell SELinux to just allow using audit2allow

Selinux is blocking postgresql

Did you make sure the Labeling is correct?

Did you make sure there were no appropriate boolean?

Most important thing you will learn today?

Or most abused thing you will learn today?

Use audit2allow to build a policy module

# grep postgresql /var/log/audit/audit.log | audit2allow -M mypostgresql
# semodule -i mypostsgresql.pp

Examine mypostgresql.te

Make sure you are not allowing too much?

Ask for help?
TAM and Red Hat Support
#fedora
Fedora-selinux mail list
dwalsh@redhat.com

Report the Bug to TAM, Support or Bugzilla

4. You could be COMPROMIZED!!!

If you have a confined domain that tries to:

Load a kernel module

Turn off SELinux enforcing mode

Write to etc_t? shadow_t

Modify iptables rules

You might be compromised

setroubleshoot not a intrusion detection tool But it will notify you of these situations.

But how do you manage SELinux in the enterprise?

How do you configure your remote machines?

How do you manage your remote content.

SELinux customization is just configuration.

SELinux should be managed the same as other configuration.

Advanced semanage

Semanage is sloooooow

Most semanage commands compile/load policy

Semanage Transactions
Allows several semanage commands with one command.

semanage -S targeted -i - << _EOF
boolean -m --on allow_polyinstantiation 
boolean -m --on xguest_connect_network
boolean -m --on xguest_mount_media
boolean -m --on xguest_use_bluetooth
			     _EOF

http://danwalsh.livejournal.com/41593.html

How do I setup identical machines with SELinux

Modify one machine the way you like?

Now apply to five other identical machines.

# semanage -o /tmp/selinux.mods

# scp /tmp/selinux.mods to remote machine

On remote machine:
# semanage -i /tmp/selinux.mods

http://danwalsh.livejournal.com/41794.html

boolean -D
boolean -1 allow_polyinstantiation
boolean -0 authlogin_nsswitch_use_ldap
user -D
fcontext -D
fcontext -a -f 'all files' -t httpd_sys_content_t '/myweb(/.*)?'
fcontext -a -f 'all files' -t public_content_t '/shared(/.*)?'
fcontext -a -f 'all files' -t samba_share_t '/shared/samba(/.*)?'
...
		  

Options for shipping SELinux modifications

Shipping SELinux commands in RPM

Run semanage commands in post install

Packaging SELinux Policy modules within RPM

In RHEL7
“sepolicy generate” will generate an example rpm spec file.

%define relabel_files() \
restorecon -R /usr/sbin/rwhod; \

%define selinux_policyver 3.12.1-44

Name:   rwhod_selinux
Version:	1.0
Release:	1%{?dist}
Summary:	SELinux policy module for rwhod

Group:	System Environment/Base		
...
Source0:	rwhod.pp
Source1:	rwhod.if
Source2:	rwhod_selinux.8
...
Requires: policycoreutils, libselinux-utils
Requires(post): selinux-policy-base >= %{selinux_policyver}, policycorutils
Requires(postun): policycoreutils
BuildArch: noarch

%description
This package installs and sets up the  SELinux policy security module for rwhod.

%install
install -d %{buildroot}%{_datadir}/selinux/packages
install -m 644 %{SOURCE0} %{buildroot}%{_datadir}/selinux/packages
install -d %{buildroot}%{_datadir}/selinux/devel/include/contrib
install -m 644 %{SOURCE1} %{buildroot}%{_datadir}/selinux/devel/include/contrib/
%post
semodule -n -i %{_datadir}/selinux/packages/rwhod.pp
if /usr/sbin/selinuxenabled ; then
    /usr/sbin/load_policy
    %relabel_files
fi;
exit 0

%postun
if [ $1 -eq 0 ]; then
    semodule -n -r rwhod
    if /usr/sbin/selinuxenabled ; then
       /usr/sbin/load_policy
       %relabel_files
    fi;
fi;
exit 0

%files
%attr(0600,root,root) %{_datadir}/selinux/packages/rwhod.pp
%{_datadir}/selinux/devel/include/contrib/rwhod.if
%{_mandir}/man8/rwhod_selinux.8.*

...

Can I ship the same policies in RHEL5, RHEL6 and RHEL7?

NO

Newer Major Version include new access checks
open is checked in RHEL6 but not in RHEL5

Policy should be stable for a major version

Policy should be compiled and on the lowest minor version.

Puppet

SELinux bindings

Builtin restorecon and semanage functions directly.

Puppet recipes should include SELinux commands
Also shell out to run other SELinux commands

class proxy {
    include selinux-enforcing
    selboolean { [
        "httpd_can_network_connect_db",
        "httpd_can_network_relay",
        "httpd_can_network_connect",
        "allow_ypbind",
    ]:
        value      => on,
        persistent => true,
    }
    semanage_port { "8081-8089":
        type  => "http_port_t",
        proto => "tcp",
    }
    semanage_port { "10001-10003":
        type  => "http_cache_port_t",
        proto => "tcp",
    }
    semanage_fcontext { "/srv/cache/mod_cache(/.*)?":
        type => "httpd_cache_t",
    }
}

Ansible

http://www.ansible.com

Uses ssh protocol

advantage no destination daemon.

Builtin selinux and seboolean functions.

Ansible playbooks should include SELinux commands

Execute semanage, same way administrator would.

Fedora and OpenShift infrastructure runs on Ansible

Other distributed tools for managing SELinux

cfengine

pulp

func

tivoli?

openview?

OpenLMI

We are working on SELinux providers.

Modifying SELinux in kickstart

Example: Configure MLS/LSPP system in RHEL6

sed -i 's/SELINUXTYPE=targeted/SELINUX=mls/g' /etc/selinux/config
setenforce 0
load_policy 2>&1 | grep -v no.longer.in.policy
echo "Fixing file labels..."
# FIXME: fixfiles ignores allegedly R/O filesystems due to bad /etc/mtab ?
cat /proc/mounts > /etc/mtab
fixfiles -Ff  restore
restorecon -Fr /root /home
- name: set selinux bools appropriately
    action: seboolean state=true persistent=yes name=$item
    with_items:
    - httpd_unified
    - httpd_can_network_connect
    - httpd_can_network_relay
    - named_write_master_zones
    - allow_ypbind
   - name: selinux module install - stickshift
    action: command semodule -i /usr/share/selinux/packages/rubygem-stickshift-common/stickshift.pp
  
  - name: selinux module disable - passenger
    action: command semodule -d passenger
    ignore_errors: True
  
  - name: selinux module install - other passenger
    action: command semodule -i /usr/share/selinux/packages/rubygem-passenger/rubygem-passenger.pp
  
  - name: fix up files for selinux
    action: command $item
    with_items:
    - "fixfiles -R rubygem-passenger restore"
    - "fixfiles -R mod_passenger restore"
    - "restorecon -rv /var/run"
    - "restorecon -rv /usr/lib/ruby/gems/1.8/gems/passenger-*"
- "restorecon -rv /usr/sbin/mcollectived /var/log/mcollective.log /run/mcollective.pid"

questions?