SELinux

Einige Notizen zu SELinux.

In SELinux wird jedes mal wenn ein Process (aka. Subject) auf eine Resource (aka. Object) per Systemcall (aka. AccessVector) geprüft, ob genau dieser Zugriff erlaubt wurde. Dazu wir nach einer allow regel in der Policy gesucht die dem SELinux-Context des Subject den aus den SELinux-Context des Objects mittels dem geforderten AccessVector erlaubt. Der Context besteht dabei aus foldenden Teilen:

user:role:type[:LEVEL]

Context Beispiele

root unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Apache system_u:system_r:httpd_t:s0
sshd system_u:system_r:sshd_t:s0-s0:c0.c1023

Ein SELinux-User darf dabei in die von der Policy fuer ihn erlaubten Rollen wechseln. Einer SELinux-Rolle hat wiederum zugriff auf die von Policy für sie erlaubenten Typen/Domains. Die SELinux-User haben nichts mitden Linux-Usern zu tun. Weiter gibt es bei MLS oder MCS noch ein Level, bestehend aus Sensitivity und Clearance. Bei Subjekten kann dies auch ein Range sein worauf Sie zugriff haben. Rollen und Typen/Domains kann der User wechseln. Das Level kann er nicht veraendern.

Bei jedem zugriff wird gepüft ob der Type/Domain des Subjekts auf den Type des Objekts die Erlaubniss hat um den AccessVector, bestehend aus Object-Kind und Access-Permission, zuzugreiffen. Bei MLS und MCS muss zusätzlich die Sensitivity und Clearance entspechend stimmen, respektive sich im entsprechneden Range befinden. Wird ein Zugriff verweigert, erscheint (meist) ein entsprechender Logeintrag im audit.log.

Neben allow zum erlauben sind auch weitere Regeln in der Policy möglich. Gerade dontaudit kann einem bei Debugen von SELinux-Problemen behindern. “semanage dontaudit off” sollte da Abhilfe leisten können.

Aktion Bedeutung
allow Erlaubt einen Zugriff.
neverallow Verbietet das erlauben eines Zugriffes.
auditallow Log wenn der Zugriff erlaubt wird.
dontaudit Verhindert das Logen eines (verbotenen) Zugriffes.

Targeted Policy

Bei der targeted-Policy ist die Idee, dass die Abgesicherten Dienste beim Starten in ihre eigende Domain wechseln und mit dieser Domain (Type) nur noch die für Sie wichtigen berechtigungen haben. Diese Domaintransition wir meist über einen “Auto transition Point” in der Policy ausgelöst. Programme die SELinux-aware sind können auch selbst wechseln, sofern die Policy das erlaubt. Meist wird die auto domain transition ausgelöst wenn aus der Damain unconfined_t_ oder initrc_t ein Binary mit dem Type exec_t gestartet wird, so das dieses dann in der Domain t läuft. z.B: hat /usr/sbin/httpd den Type httpdexec_t und leuft dann in der Domain httpdt. Dies Domain hat dann nur noch auf die in der Policy fuer Sie erlaubten Objekte zugriff.

Multi Category Security

Die targeted-Policy ist MCS fähig. Dies wir meist nich verwendet. Durch verändern/setzen der Category mit chcat und gleichzeitigem entziehen der der Clearance fuer diese Category bei einem SELinux-User kann ich ihn problemlos von gewissen bereichen aussperren ohne an der Policy zu drehen. Boolean

Gewisse teile der Policy lassen sich mit sogenannten SELinux-Booleans ein-, respektive ausschalten. Auf diese weiste werden unterschiedliche Anwendungsfälle abgefangen ohne einfach alles zu erlauben. Zu beispiel ist es möglich mit dem bool httpd_enable_homedirs der Domain httpd_t zugriff auch user_home_t zu erlauben.

Boolean

Gewisse teile der Policy lassen sich mit sogenannten SELinux-Booleans ein-, respektive ausschalten. Auf diese weiste werden unterschiedliche Anwendungsfälle abgefangen ohne einfach alles zu erlauben. Zu beispiel ist es möglich mit dem bool httpd_enable_homedirs der Domain httpd_t zugriff auch user_home_t zu erlauben.

Debuging Tricks

SELinux-Context Anzeigen (und Ändern)

Dateien:

[root@localhost ~]# ls -Z file
[root@localhost ~]# chcon -t httpd_sys_content_t file

Prozesse:

[root@localhost ~]# ps -ZC httpd

Ports:

[root@localhost ~]# semanage port -l
[root@localhost ~]# semanage port -a -t httpd_port_t -p tcp 8888 

User:

[root@localhost ~]# id -Z root

SELinux-Mode

SELinux Status anzeigen und ändern:

[root@localhost ~]# getenforce 
Enforcing 
[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce 
Permissive
[root@localhost ~]# setenforce 1
[root@localhost ~]# getenforce 
Enforcing

SELinux Status für einzelne Domains ändern:

[root@localhost ~]# semanage permissive -a httpd_t 
[root@localhost ~]# semanage permissive -d httpd_t 

Booleans

Booleans anzeigen:

[root@localhost ~]# getsebool -a

Boolean setzen

[root@localhost ~]# setsebool -P bool_name=[0|1]

Allow eines boolean anzeigen:

[root@localhost ~]# sesearch --allow -b bool_name

Boolean mit wirkung auf eine Domain finden:

[root@localhost ~]# sesearch --allow -R -b ".+" -C -s DOMAIN_t

Domain Transitions

Finden möglicher Domain transitions:

[root@localhost ~]# sesearch --type -c process -s SOURCE_DOMAIN_t

Module

Module anzeigen:

[root@localhost ~]# semodule -l

Module Installieren, aktualisieren und entfernen:

[root@localhost ~]# semodule -i Module.pp
[root@localhost ~]# semudule -u Module.pp
[root@localhost ~]# semodule -r Module

Modul übersetzen:

[root@localhost ~]# make -f /usr/share/selinux/devel/makefile Module.pp

Example Policy Module

Compile

[root@localhost example_policy]# ls
example.fc example.te
[root@localhost example_policy]# make -f /usr/share/selinux/devel/Makefile example.pp
Compiling targeted example module
/usr/bin/checkmodule:  loading policy configuration from tmp/example.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 10) to tmp/example.mod
Creating targeted example.pp policy package
rm tmp/example.mod tmp/example.mod.fc

example.te

policy_module(example, 1.0.0)

require {
    type unconfined_t;
    type nfs_t;
    attribute domain;
    attribute exec_type;
    attribute file_type;
}

# Create Domain Type
type example_t, domain;

# Create Domain Transition Source Type
type example_exec_t, exec_type;

# Create Config File Type
type example_conf_t, file_type;

# Create Data File Type
type example_data_t, file_type;

# Create Log File Type
type example_log_t, file_type;

# Create Log Dir Type
type example_logdir_t, file_type;

# Create Bool to allow data on NFS
bool example_enable_nfs false;

# Create Domain Transition with Macros
#  Allow/force initrc_t and to switch to example_t when executing a
#  binary with example_exec_t context.
init_daemon_domain(example_t, example_exec_t);
domain_auto_trans(unconfined_t, example_exec_t, example_t);

# Allow example_t R/W acces to example_data_t
manage_files_pattern(example_t, example_data_t, example_data_t);
# allow example_t example_data_t:dir rw_dir_perms;
# allow example_t example_data_t:file manage_file_perms;
# admin_pattern(example_r, example_data_t) => Allow dir, file link fifo and sock

tunable_policy(`example_enable_nfs',`
manage_files_pattern(example_t, nfs_t, nfs_t)
# allow example_t nfs_t:dir rw_dir_perms;
# allow example_t nfs_t:file manage_file_perms;
');

# Allow example_t read example_conf_t
allow example_t example_conf_t:file read_file_perms; # {open getattr read ioctl lock}
allow example_t example_conf_t:dir list_dir_perms;   # {getattr search open read lock ioctl}

# Allow example_t append to example_log_t
allow example_t example_log_t:file { read_file_perms append_file_perms };

# Allow example_t to write to example_logdir_t
filetrans_pattern(example_t, example_logdir_t, example_log_t, file);
# allow examplt_t example_logdir_t:dir rw_dir_perms;
# type_transition example_t example_logdir_t:file example_log_t

exmaple.fc

/usr/bin/example         system_u:object_r:example_exec_t:s0
/etc/example(/.*)?       system_u:object_r:example_conf_t:s0
/var/example(/.*)?       system_u:object_r:example_data_t:s0
/var/log/example         system_u:object_r:example_logdir_t:s0
/var/log/example(/.*)?   system_u:object_r:example_log_t:s0