====== SELinux - soluzioni ====== ==== Esercitazione 1 ==== - Visualizzazione dello stato di SELinux - Visualizzazione dello stato di SELinux [root@statichostname ~]# sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 31 [root@statichostname ~]# getenforce Enforcing - Visualizzazione del context dei processi di systemd e cron [root@statichostname ~]# ps -e -Z | grep -e systemd -e cron system_u:system_r:init_t:s0 1 ? 00:00:01 systemd system_u:system_r:udev_t:s0-s0:c0.c1023 496 ? 00:00:00 systemd-udevd system_u:system_r:systemd_logind_t:s0 768 ? 00:00:00 systemd-logind system_u:system_r:crond_t:s0-s0:c0.c1023 1285 ? 00:00:00 atd system_u:system_r:crond_t:s0-s0:c0.c1023 1287 ? 00:00:00 crond system_u:system_r:syslogd_t:s0 1928 ? 00:00:00 systemd-journal - Visualizzazione del context dei file /etc/passwd, /etc/shadow, /etc/cron.d (verificare la presenza degli extended attributes corrispondenti) [root@statichostname ~]# ls -Z -d /etc/passwd /etc/shadow /etc/cron.d /etc/cron.d/sysstat drwxr-xr-x. root root system_u:object_r:system_cron_spool_t:s0 /etc/cron.d -rw-------. root root system_u:object_r:system_cron_spool_t:s0 /etc/cron.d/sysstat -rw-r--r--. root root system_u:object_r:passwd_file_t:s0 /etc/passwd ----------. root root system_u:object_r:shadow_t:s0 /etc/shadow [root@statichostname ~]# getfattr -d -m ".*" /etc/passwd /etc/shadow getfattr: Removing leading '/' from absolute path names # file: etc/passwd security.selinux="system_u:object_r:passwd_file_t:s0" # file: etc/shadow security.selinux="system_u:object_r:shadow_t:s0" - Visualizzazione degli SELinux user e associazione con role e level [root@statichostname ~]# semanage user -l Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles guest_u user s0 s0 guest_r root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r sysadm_u user s0 s0-s0:c0.c1023 sysadm_r system_u user s0 s0-s0:c0.c1023 system_r unconfined_r unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r user_u user s0 s0 user_r xguest_u user s0 s0 xguest_r - Visualizzazione della associazione degli user agli SELinux user [root@statichostname ~]# semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 * - Visualizzare i context di httpd e della sua DocumentRoot ed identificare la rule che permette l'accesso\\ Utilizzare sesearch (man sesearch) per trovare la rule) # Far partire httpd e visualizzare il context del processo [root@statichostname ~]# systemctl start httpd [root@statichostname ~]# ps -e -Z | grep httpd system_u:system_r:httpd_t:s0 4021 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 4022 ? 00:00:00 httpd ... # visualizzare il context della attuale document root (creare anche una index.html vuota) [root@statichostname ~]# ls -lZd /var/www/html/ drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/ [root@statichostname ~]# touch /var/www/html/index.html [root@statichostname ~]# ls -lZd /var/www/html/index.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html # cercare con sesearch la regola che permette a httpd di leggere i file della DocumentRoot [root@statichostname ~]# sesearch --allow --source httpd_t --target httpd_sys_content_t --class file Found 5 semantic av rules: allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ; -> allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ; allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename open } ; allow httpd_t httpdcontent : file { read getattr execute open } ; allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ; - Verificare che cambiando il context type di /var/www/html/index.html in var_t l'accesso a httpd e' negato, quindi restorare il context del file e verificare che l'accesso e' consentito [root@statichostname ~]# chcon -t var_t /var/www/html/index.html [root@statichostname ~]# ls -Z /var/www/html/index.html -rw-r--r--. root root unconfined_u:object_r:var_t:s0 /var/www/html/index.html [root@statichostname ~]# wget http://127.0.0.1:80/index.html --2018-11-28 05:49:52-- http://127.0.0.1/index.html Connecting to 127.0.0.1:80... connected. HTTP request sent, awaiting response... 403 Forbidden 2018-11-28 05:49:52 ERROR 403: Forbidden. [root@statichostname ~]# restorecon /var/www/html/index.html [root@statichostname ~]# ls -Z /var/www/html/index.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html [root@statichostname ~]# wget http://127.0.0.1:80/index.html --2018-11-28 06:00:52-- http://127.0.0.1/index.html Connecting to 127.0.0.1:80... connected. HTTP request sent, awaiting response... 200 OK Length: 0 [text/html] Saving to: ‘index.html’ [ <=> ] 0 --.-K/s in 0s 2018-11-28 06:00:52 (0.00 B/s) - ‘index.html’ saved [0/0] - Spostare la DocumentRoot di httpd in /www/html\\ Per fare questo si deve: modificare la configurazione di httpd, creare la nuova document root, verificare che non funziona, assegnare il default context (semanage fcontext), e modificare il context (restorecon) # creare le directory [root@statichostname ~]# mkdir -p /www/html [root@statichostname ~]# ls -lZd /www/html/ drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /www/html/ # default_t e' il default type se non ci sono configurazioni apposite [root@statichostname ~]# cp /var/www/html/index.html /www/html/ [root@statichostname ~]# ls -Z /www/html/index.html -rw-r--r--. root root unconfined_u:object_r:default_t:s0 /www/html/index.html # modificare la configurazione di httpd [root@statichostname ~]# vi /etc/httpd/conf/httpd.conf [root@statichostname ~]# grep ^DocumentRoot -A15 /etc/httpd/conf/httpd.conf DocumentRoot "/www/html" # # Relax access to content within /var/www. # # # AllowOverride None # # Allow open access: # Require all granted # AllowOverride None # Allow open access: Require all granted [root@statichostname ~]# systemctl reload httpd # verificare che l'accesso e' negato [root@statichostname ~]# wget http://127.0.0.1:80/index.html --2018-11-28 06:14:37-- http://127.0.0.1/index.html Connecting to 127.0.0.1:80... connected. HTTP request sent, awaiting response... 403 Forbidden 2018-11-28 06:14:37 ERROR 403: Forbidden. # identificare tramite matchpathconf quale type devono avere i file della DocumentRoot [root@statichostname ~]# matchpathcon -m file /var/www/html/x.html /var/www/html/x.html system_u:object_r:httpd_sys_content_t:s0 # utilizzare semanage per modificare il context di configurazione della nuova document root [root@statichostname ~]# semanage fcontext --add --type httpd_sys_content_t "/www(/.*)?" [root@statichostname ~]# semanage fcontext --add --type httpd_sys_content_t "/www/html(/.*)?" # verificare che le entry aggiunte compaiono nel file di configuraizone (locale) file_context.local [root@statichostname ~]# cat /etc/selinux/targeted/contexts/files/file_contexts.local # This file is auto-generated by libsemanage # Do not edit directly. /www(/.*)? system_u:object_r:httpd_sys_content_t:s0 /www/html(/.*)? system_u:object_r:httpd_sys_content_t:s0 # restorare il context della nuova documento root al type della configurazione [root@statichostname ~]# restorecon -Rv /www restorecon reset /www context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0 restorecon reset /www/html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0 restorecon reset /www/html/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0 [root@statichostname ~]# ls -Z /www/html/index.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /www/html/index.html # verificare che l'accesso e' garantito [root@statichostname ~]# wget http://127.0.0.1:80/index.html --2018-11-28 06:42:31-- http://127.0.0.1/index.html Connecting to 127.0.0.1:80... connected. HTTP request sent, awaiting response... 200 OK Length: 0 [text/html] Saving to: ‘index.html.1’ [ <=> ] 0 --.-K/s in 0s 2018-11-28 06:42:31 (0.00 B/s) - ‘index.html.1’ saved [0/0] ==== Esercitazione 2 ==== - Utilizzare seinfo per visualizzare l'esistenza di un type init_t, l'elenco degli attributi associati a questo type e verificare che domain sia tra questi [root@statichostname ~]# seinfo -t | grep init_t cloud_init_tmp_t run_init_t cloud_init_t init_tmp_t -> init_t namespace_init_t [root@statichostname ~]# seinfo -tinit_t -x init_t ... domain ... - Utilizzare seinfo per visualizzare l'esistenza dell'attribute domain, l'elenco di type che hanno domain tra i loro attributi e verificare che init_t sia tra questi [root@statichostname ~]# seinfo -adomain domain [root@statichostname ~]# seinfo -adomain -x | grep init_t cloud_init_t -> init_t namespace_init_t run_init_t - Domain transition: identificare le policy che permettono la domain transition da systemd a httpd - Visualizzare domain e type di systemd, httpd, /usr/sbin/httpd root@statichostname ~]# ps -eZ | grep systemd$ system_u:system_r:init_t:s0 1 ? 00:00:03 systemd [root@statichostname ~]# ls -Z /usr/sbin/httpd -rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd [root@statichostname ~]# ps -eZ | grep httpd | head -n 1 system_u:system_r:httpd_t:s0 4021 ? 00:00:01 httpd - Verificare l'esistenza di una rule che permetta a systemd di eseguire /usr/sbin/httpd [root@statichostname ~]# sesearch -s init_t -t httpd_exec_t -c file -A Found 3 semantic av rules: ... allow initrc_domain direct_init_entry : file { read getattr execute open } ; ... # La regola e' permessa perche' init_t ha l'attributo initrc_domain: [root@statichostname ~]# seinfo -ainitrc_domain -x | grep init_t init_t e perche' httpd_exec_t ha l'attributo direct_init_entry [root@statichostname ~]# seinfo -adirect_init_entry -x | grep http httpd_exec_t httpd_rotatelogs_exec_t - Verificare che esista una rule che definisca che il type dell'eseguibile sia entrypoint del dominio di destinazione [root@statichostname ~]# sesearch -s httpd_t -p entrypoint -A Found 3 semantic av rules: allow sepgsql_client_type sepgsql_temp_object_t : db_procedure { create drop getattr setattr execute entrypoint install } ; allow sepgsql_client_type sepgsql_trusted_procedure_type : db_procedure { getattr execute entrypoint } ; -> allow httpd_t httpd_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ; - Verificare che esista una rule che permette al parent domain (init_t) una transizione verso il destination domain (httpd_t) [root@statichostname ~]# sesearch -s init_t -t httpd_t -p transition -A Found 1 semantic av rules: allow initrc_domain daemon : process transition ; # initrc_domain e' attributo di init_t (gia' visto), e daemon e' attributo di httpd_t. [root@statichostname ~]# seinfo -adaemon -x | grep httpd_t httpd_t - Verificare l'esistenza di una transition rule che definisca il default destination domain conseguente alla esecuzione di un eseguibile di type httpd_exec_t da parte di un processo di domain init_t [root@statichostname ~]# sesearch -T -s init_t -t httpd_exec_t Found 1 semantic te rules: type_transition init_t httpd_exec_t : process httpd_t; ==== Esercitazione 3 ==== - Confinamento di un utente: confinare user1 a user_u (verifica impossibilita' di fare su) - Visualizzazione context del processo di login dell'utente user1 e verifica che l'utente user1 possa eseguire su e diventare user2 [user1@statichostname ~]$ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 [user1@statichostname ~]$ su - user2 Password: Attempting to create directory /home/user2/perl5 [user2@statichostname ~]$ logout [user1@statichostname ~]$ logout Connection to 192.168.56.102 closed. - Confinare il linux user user1 associandolo all'SELinux user user_u [root@statichostname ~]# semanage login -a -s user_u user1 [root@statichostname ~]# semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 * user1 user_u s0 * - Verificare che user1, il cui dominio attuale e' user_t, non puo' fare su e diventare user2 # ssh user1@192.168.56.102 user1@192.168.56.102's password: Warning: No xauth data; using fake authentication data for X11 forwarding. Last login: Wed Nov 28 18:45:06 2018 from 192.168.56.1 [user1@statichostname ~]$ id -Z user_u:user_r:user_t:s0 [user1@statichostname ~]$ su - user2 Password: su: Authentication failure - Visualizzazione del policy module apache [root@statichostname ~]# semodule -l | grep apache apache 2.7.2 [root@statichostname ~]# semodule -lfull | grep apache 100 apache pp [root@statichostname ~]# ls /etc/selinux/targeted/active/modules/100/apache/ cil hll lang_ext [root@statichostname ~]# cat /etc/selinux/targeted/active/modules/100/apache/cil | bunzip2 > /tmp/apache.txt [root@statichostname ~]# wc -l /tmp/apache.txt 4116 /tmp/apache.txt - Abilitare tramite boolean httpd a leggere le home directory degli utenti [root@statichostname ~]# semanage boolean -l | grep http | grep user httpd_read_user_content (off , off) Allow httpd to read user content [root@statichostname ~]# sesearch -b httpd_read_user_content -AC Found 40 semantic av rules: DT allow httpd_user_script_t user_home_type : dir { getattr search open } ; [ httpd_read_user_content ] DT allow httpd_user_script_t user_home_type : dir { ioctl read getattr lock search open } ; [ httpd_read_user_content ] ... [root@statichostname ~]# semanage boolean --modify --on httpd_read_user_content [root@statichostname ~]# semanage boolean -l httpd_read_user_content list option can not be used with --boolean [root@statichostname ~]# semanage boolean -l | grep httpd_read_user_content httpd_read_user_content (on , on) Allow httpd to read user content o alternativamente tramite **getsebool** e **setsebool** [root@statichostname ~]# getsebool httpd_read_user_content httpd_read_user_content --> off [root@statichostname ~]# setsebool -P httpd_read_user_content on [root@statichostname ~]# getsebool httpd_read_user_content httpd_read_user_content --> on [root@statichostname ~]# semanage boolean -l | grep httpd_read_user_content httpd_read_user_content (on , on) Allow httpd to read user content [root@statichostname ~]# ==== Esercitazione 4 ==== - Generare un messaggio di errore eseguendo il comando **su** come user **user1** [root@statichostname ~]# semanage login -lC Login Name SELinux User MLS/MCS Range Service user1 user_u s0 * [user1@statichostname ~]$ su - user2 Password: su: Authentication failure - Analizzare l'errore e generare un modulo che contenga le rule per rendere lecita l'operazione [root@statichostname ~]# ausearch -m avc --start recent ---- time->Thu Nov 29 14:38:06 2018 type=PROCTITLE msg=audit(1543498686.922:223): proctitle=7375002D007573657232 type=SYSCALL msg=audit(1543498686.922:223): arch=c000003e syscall=105 success=yes exit=0 a0=0 a1=0 a2=800020 a3=7f0bc56d9300 items=0 ppid=2459 pid=2460 auid=1000 uid=1000 gid=1000 euid=0 suid=0 fsuid=0 egid=1000 sgid=1000 fsgid=1000 tty=pts1 ses=6 comm="su" exe="/usr/bin/su" subj=user_u:user_r:user_t:s0 key=(null) type=AVC msg=audit(1543498686.922:223): avc: denied { setuid } for pid=2460 comm="su" capability=7 scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=capability ---- time->Thu Nov 29 14:38:11 2018 type=PROCTITLE msg=audit(1543498691.746:226): proctitle=7375002D007573657232 type=SYSCALL msg=audit(1543498691.746:226): arch=c000003e syscall=2 success=no exit=-13 a0=55763c0f20d0 a1=1 a2=99b a3=5bffebc3 items=0 ppid=2305 pid=2459 auid=1000 uid=1000 gid=1000 euid=0 suid=0 fsuid=0 egid=1000 sgid=1000 fsgid=1000 tty=pts1 ses=6 comm="su" exe="/usr/bin/su" subj=user_u:user_r:user_t:s0 key=(null) type=AVC msg=audit(1543498691.746:226): avc: denied { write } for pid=2459 comm="su" name="btmp" dev="dm-0" ino=33860287 scontext=user_u:user_r:user_t:s0 tcontext=system_u:object_r:faillog_t:s0 tclass=file ---- time->Thu Nov 29 14:38:09 2018 type=PROCTITLE msg=audit(1543498689.416:224): proctitle=7375002D007573657232 type=SYSCALL msg=audit(1543498689.416:224): arch=c000003e syscall=105 success=yes exit=0 a0=0 a1=55763dbd8840 a2=800020 a3=7f0bc56d9300 items=0 ppid=2459 pid=2461 auid=1000 uid=1000 gid=1000 euid=0 suid=0 fsuid=0 egid=1000 sgid=1000 fsgid=1000 tty=pts1 ses=6 comm="su" exe="/usr/bin/su" subj=user_u:user_r:user_t:s0 key=(null) type=AVC msg=audit(1543498689.416:224): avc: denied { setuid } for pid=2461 comm="su" capability=7 scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=capability [root@statichostname ~]# ausearch -m avc --start recent | audit2allow #============= user_t ============== allow user_t faillog_t:file write; #!!!! This avc can be allowed using the boolean 'selinuxuser_use_ssh_chroot' allow user_t self:capability setuid; [root@statichostname ~]# ausearch -m avc --start recent | audit2allow -M mylocalmodule ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i mylocalmodule.pp [root@statichostname ~]# ls -l mylocalmodule.* -rw-r--r--. 1 root root 1120 Nov 29 14:47 mylocalmodule.pp -rw-r--r--. 1 root root 304 Nov 29 14:47 mylocalmodule.te [root@statichostname ~]# - Caricare il modulo generato e verificare che l'operazione ora e' permessa [root@statichostname ~]# semodule -i mylocalmodule.pp [root@statichostname ~]# semodule -lfull | grep mylocalmodule 400 mylocalmodule pp [root@statichostname ~]# ls /etc/selinux/targeted/active/modules/ 100/ 400/ disabled/ [root@statichostname ~]# ls /etc/selinux/targeted/active/modules/400/ mylocalmodule [root@statichostname ~]# ls /etc/selinux/targeted/active/modules/400/mylocalmodule/ cil hll lang_ext [root@statichostname ~]# [user1@statichostname ~]$ su - user2 Password: [user2@statichostname ~]$ - Disabilitare e rimuovere il modulo, verificando che l'operazione e' nuovamente proibita [root@statichostname ~]# semodule -d mylocalmodule [root@statichostname ~]# semodule -lfull | grep mylocalmodule 400 mylocalmodule pp disabled [root@statichostname ~]# semodule -r mylocalmodule libsemanage.semanage_direct_remove_key: Removing last mylocalmodule module (no other mylocalmodule module exists at another priority). [root@statichostname ~]# semodule -lfull | grep mylocalmodule [user1@statichostname ~]$ su - user2 Password: su: Authentication failure