setroubleshoot - SELinux 의 에러 메시지를 알기 쉽게 번역해 주고 처리 방안을 제시하는 유틸리티
개요
SELinux 를 어렵게 느끼는 원인중에 하나는 SELinux 의 error message 가 너무 이해하기 어렵다는 점이다.
setroubleshoot 는 python 으로 만들어진 유틸리티로 어려운 에러 메시지를 알기 쉽게 번역해 주고 처리 방안도 제시해 주는 유틸리티이다.
audit2why 가 익숙하지 않다면 꼭 설치해서 사용해 보자.
설치
다음 패키지를 설치하면 된다.
yum install setroubleshoot
SELinux 의 에러 메시지는 /var/log/message 에 남게 되는데 다음과 같은 에러가 난다면 message bus daemon 이 구동되지 않아서 이다.
다음 명령어로 messagebus 를 재구동하면 된다.
systemctl restart messagebus
사용
console 에서 사용하려면 sealert 명령어를 실행하면 된다. -a 옵션 뒤에는 audit 파일의 절대 경로를 전달해 준다.
sealert -a /var/log/audit/audit.log
X Windows 가 설치되어 있다면 GUI 환경에서도 구동 가능 하다.
sealert -b
Example
예제 #1
잘못된 보안 컨텍스트 설정으로 인해 웹서버가 컨텐츠를 읽지 못할 경우 처리법을 알아보기 위해 실제 상황에 기반한 예제를 실행해 보자.
파일을 /root 에 생성한 후에 mv 로 웹 서버 폴더에 이동시킨다. (참고 - cp/mv 와 SELinux security context)
$ touch /root/test.html $ mv /root/test.html/var/www/html $ service httpd restart
텍스트 브라우저로 연결하여 웹 서버가 test.html 에 연결하지 못해 403 에러가 나는 것을 확인한다.
$ links -dump http://localhost/test.html Forbidden You don't have permission to access /test.html on this server.
tail 로 /var/log/message 에 남은 SELinux 의 에러 메시지 확인한다.
$ tail /var/log/messages Jun 17 13:59:42 centos setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html. For complete SELinux messages. run sealert -l 0f03538b-feb4-4ddc-a2ba-30e97bc4b6c9
로그에 남은 대로 sealert -l event_id 명령어를 실행하면 원인과 처리 방안을 제시해 준다
권고한 대로 SELinux context 를 복구하는 명령어인 restorecon 을 실행하여 문제 해결한다.
/sbin/restorecon -v /var/www/html/test.html
예제 #2
실제 환경과 비슷한 예제를 들어서 설명해 보자. 웹서버 설정에 사용자마다 개인 홈페이지를 만들수 있기로 했다. 먼저 apache httpd 의 userdir 옵션을 켜자.
UserDir disabled 를 주석처리하고 UserDir public_html의 주석을 제거하고 service httpd restart 로 웹서버를 재구동한다.
<IfModule mod_userdir.c> # # UserDir is disabled by default since it can confirm the presence # of a username on the system (depending on home directory # permissions). # #UserDir disabled # # To enable requests to /~user/ to serve the user's public_html # directory, remove the "UserDir disabled" line above, and uncomment # the following line instead: # UserDir public_html </IfModule>
사용자로 로그인후에 홈경로에 public_html 을 만들고 index.html 을 생성하자.
mkdir ~/public_html echo "Hello World" > ~/public_html/index.html
이제 부라우저에서 http://myhost/~lesstif 로 연결해 보면 다음과 같이 에러가 발생할 것이다.
Forbidden You don't have permission to access /~lesstif/ on this server. Apache/2.2.15 (CentOS) Server at myshost Port 80
이제 웹서버의 에러 로그를 확인해 보자.
[error] [client 1.2.3.4] (13)Permission denied: access to /~lesstif/ denied
에러 메시지로 봐서는 웹서버가 ~/lesstif 를 읽지 못해서 발생한 것이다. 왜 웹서버가 읽지 못 했는지는 /var/log/audit/audit.log 를 보면 알 수 있다.
type=AVC msg=audit(1397214915.307:26244): avc: denied { getattr } for pid=15487 comm="httpd" path="/home/lesstif" dev=dm-3 ino=17 825793 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_dir_t:s0 tclass=dir
위와 같이 기본 에러 메시지는 알아보기가 너무 어렵고 원인을 알아도 처리 방법을 찾기가 힘들다.
setroubleshoot를 설치했다면 에러 발생시 /var/log/message에 다음과 같이 setroubleshoot 의 제안이 같이 표시된다.
SELinux is preventing /usr/sbin/httpd from getattr access on the directory /home/lesstif. For complete SELinux messages. run sealert -l 9596e699-f6f5-405f-a338-7ab520b8f259
이제 위에서 권고한 대로 sealert -l 9596e699-f6f5-405f-a338-7ab520b8f259 를 실행해 보면 다음과 같이 이해하기 쉽게 번역되어 표시된다.
> sealert -l 9596e699-f6f5-405f-a338-7ab520b8f259 SELinux is preventing /usr/sbin/httpd from getattr access on the directory /home/lesstif. ***** Plugin catchall_boolean (47.5 confidence) suggests ******************* If you want to allow httpd to read user content Then you must tell SELinux about this by enabling the 'httpd_read_user_content'boolean. Do setsebool -P httpd_read_user_content 1 ***** Plugin catchall_boolean (47.5 confidence) suggests ******************* If you want to allow httpd to read home directories Then you must tell SELinux about this by enabling the 'httpd_enable_homedirs'boolean. Do setsebool -P httpd_enable_homedirs 1 ***** Plugin catchall (6.38 confidence) suggests *************************** If you believe that httpd should be allowed getattr access on the lesstif directory 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: # grep httpd /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp
위에 나와 있듯 원인은 httpd 가 사용자의 home_dir 을 읽지 못해서 발생한 것이다. SELinux 가 어렵게 느껴지는 점은 분명 ls -l /home/lesstif 를 해보면 other 가 읽을수 있는 권한이 있는데 왜 apache httpd 가 못 읽는지 모르기 때문이다.
이는 전통적인 유닉스의 권한 관리 방법인 DAC 때문이다. 이제 SElinux 를 쓰기로 했다면 권한 관리는 MAC 이라는 점을 기억하자.
해결 방법은 위에서 제안했듯이 apache httpd에 home dir 을 읽을수 있는 bool 을 true 로 해주면 되고 다음 명령어를 수행하자.
setsebool -P httpd_enable_homedirs 1
이제 apache httpd 를 재구동하고 웹브라우저로 연결하면 문제가 해결될 것이다.