În acest articol voi exemplifica cum pot ajunge unele fișiere să aibă un context SELinux greșit și ce s-ar putea face pentru a remedia sau chiar a evita astfel de probleme. Fișierele capătă un context SELinux eronat (își păstrează contextul din momentul creării) atunci când sunt mutate în loc să fie copiate în locul dorit. Așadar, SELinux - copiere versus mutare fișiere este tema acestui articol.
Să presupunem cazul clasic al unui website. Instalăm apache și activăm serviciul:
# yum install httpd # systemctl enable --now httpd
Apache își ține fișierele în directorul /var/www/html. Listăm și vedem că nu există niciun fișier în acest loc:
# ll -Z /var/www/html #
Nu uităm să verificăm dacă avem portul 80 deschis (în cazul în care folosim firewalld):
# firewall-cmd --list-all # firewall-cmd --zone=public --permanent --add-service=http # firewall-cmd --reload
Într-un browser web ni se confirmă faptul că nu avem niciun fișier index.html:
Creăm acest fișier și adăugăm conținut (vă rog să remarcați și valoarea atributului SELinux type):
# echo "Aceasta este o pagină web simplă" > /var/www/html/index.html
# ll -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
Dacă facem refresh în browser avem:
Acum să facem acest fișier într-un alt director (în directorul home al superutilizatorului root) - remarcați valoarea atributului de securitate type:
Acum mutăm acest fișier din directorul /root în directorul /var/www/html:
# mv index.html /var/www/html/
mv: overwrite ‘/var/www/html/index.html’? y
# ll -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /var/www/html/index.html
Observăm că atributul type și-a păstrat valoarea din momentul în care a fost creat - admin_home_t. Fișierul index.html există, deci nu ne reține nimic să încercăm să-l vizualizăm. Facem refresh în browser la pagina http://IP_server/index.html:
Ni se spune clar că NU avem acces să vizualizăm acest fișier. Acest lucru se întâmplă din cauză că fișierul are un context de securitate greșit: atributul type are valoarea admin_home_t în loc de httpd_sys_content_t, ceea ce înseamnă că serviciul httpd.service nu are dreptul să acceseze acest fișier.
Avem două posibilități de remediere a acestei erori: verificăm conținutul fișierului /var/log/audit/audit.log (cum am învățat în articolul precedent) și aplicăm recomandările de acolo sau, în loc să mutăm fișierul din /root, îl vom copia în /var/www/html. Voi exemplifica ambele situații:
Varianta 1 - Verificăm logurile să vedem eroarea:
# sealert -a /var/log/audit/audit.log
100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------
SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/index.html.
***** Plugin restorecon (99.5 confidence) suggests ************************
If you want to fix the label.
/var/www/html/index.html default label should be httpd_sys_content_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /var/www/html/index.html
***** Plugin catchall (1.49 confidence) suggests **************************
If you believe that httpd should be allowed getattr access on the index.html file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -i my-httpd.pp
Additional Information:
Source Context system_u:system_r:httpd_t:s0
Target Context unconfined_u:object_r:admin_home_t:s0
Target Objects /var/www/html/index.html [ file ]
Source httpd
Source Path /usr/sbin/httpd
Port <Unknown>
Host <Unknown>
Source RPM Packages httpd-2.4.6-80.el7.centos.1.x86_64
Target RPM Packages
Policy RPM selinux-policy-3.13.1-192.el7_5.6.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name testserver.example.ro
Platform Linux testserver.example.ro
3.10.0-862.11.6.el7.x86_64 #1 SMP Tue Aug 14
21:49:04 UTC 2018 x86_64 x86_64
Alert Count 1
First Seen 2018-09-23 11:17:17 EEST
Last Seen 2018-09-23 11:17:17 EEST
Local ID f1190e57-8b38-46e3-8d67-af4eca1dcde1
Raw Audit Messages
type=AVC msg=audit(1537690637.570:18261): avc: denied { getattr } for pid=32963 comm="httpd" path="/var/www/html/index.html" dev="dm-0" ino=147537 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=SYSCALL msg=audit(1537690637.570:18261): arch=x86_64 syscall=stat success=no exit=EACCES a0=563048fa96d8 a1=7ffd2704cf20 a2=7ffd2704cf20 a3=7fe7dc062712 items=0 ppid=1042 pid=32963 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null)
Hash: httpd,httpd_t,admin_home_t,file,getattr
Rulăm comanda restorecon
, așa cum ni se sugerează:
/sbin/restorecon -v /var/www/html/index.html
Observăm că atributul de securitate type se schimbă din admin_home_t în loc de httpd_sys_content_t; la final, vizualizăm atributulete de securitate și avem confirmarea că acesta a fost schimbat:
În browser, reîncărcăm pagina http://IP_server/index.html, rezultatul fiind cel așteptat (putem vedea conținutul fișierului index.html):
Varianta a 2-a - copierea
Pentru început, ștergem fișierul index.html din /var/www/html:
# cd /var/www/html/ # rm -rf index.html # ll -Z #
Navigăm în directorul home al superutilizatorului root, recreăm fișierul index.html, îi revedem atributele de securitate, îl copiem în directorul /var/www/html și-i relistăm atributele de securitate:
Din imaginea de mai sus, observăm că fișierul index.html a fost creat în directorul /root cu atributul type având valoarea admin_home_t, iar după copierea sa în directorul /var/www/html valoarea atributului type s-a schimbat în httpd_sys_content_t, adică exact valoarea necesară pentru a fi accesat din exterior, putând fi accesat și vizualizat în browser la adresa http://IP_server/index.html
Reamintesc (am scris în acest articol) modalitatea de a vedea toate regulile politicii targeted referitoare la un anumit obiect Linux (în cazul de față httpd):
# semanage fcontex -l | grep httpd
Sau doar regulile httpd care se aplica directorului /var/www/html:
# semanage fcontext -l | grep httpd | grep /var/www/html
/var/www/html(/.*)?/uploads(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/wp-content(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/wp_backups(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/sites/default/files(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/sites/default/settings\.php regular file system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0 /var/www/html/owncloud/data(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/nextcloud/data(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/configuration\.php all files system_u:object_r:httpd_sys_rw_content_t:s0 [...]
Cauza
Probabil vă întrebați de ce se întâmplă asta: de ce atributele SELinux se păstrează la mutare și se schimbă la copiere?
Cea mai simplă explicație este aceea că, la mutarea unui fișier, inode-ul său se păstrează (toate valorile din inode referitoare la fișier rămân neschimbate) - se schimbă doar calea (path-ul) fișierului; la copiere, apare un nou fișier, cu un alt inode, fișierul copiat moștenind/primind contextele SELinux ale directorului unde a fost copiat.
Concluzionând, putem spune că este preferabil să copiați fișierele și directoarele în loc să le mutați, la copiere acestea primind contextele de securitate SELinux corecte, moștenindu-le pe cele ale directorului unde au fost copiate.
Lasă un răspuns