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
Links
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