setroubleshoot - SELinux 의 에러 메시지를 알기 쉽게 번역해 주고 처리 방안을 제시하는 유틸리티
개요
SELinux 를 어렵게 느끼는 원인중에 하나는 SELinux 의 error message 가 너무 이해하기 어렵다는 점이다.
setroubleshoot 는 python 으로 만들어진 유틸리티로 어려운 에러 메시지를 알기 쉽게 번역해 주고 처리 방안도 제시해 주는 유틸리티이다.
audit2why 가 익숙하지 않다면 꼭 설치해서 사용해 보자.
설치
다음 패키지를 설치하면 된다.
yum install setroubleshoot
SELinux 의 에러 메시지는 /var/log/message 에 남게 되는데 다음과 같은 에러가 난다면 message bus daemon 이 구동되지 않아서 이다.
Connection Error (Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory): AVC Will be dropped"
다음 명령어로 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
BASH텍스트 브라우저로 연결하여 웹 서버가 test.html 에 연결하지 못해 403 에러가 나는 것을 확인한다.
$ links -dump http://localhost/test.html Forbidden You don't have permission to access /test.html on this server.
BASHtail 로 /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
BASH로그에 남은 대로 sealert -l event_id 명령어를 실행하면 원인과 처리 방안을 제시해 준다
sealert# sealert -l 0f03538b-feb4-4ddc-a2ba-30e97bc4b6c9
SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html.
***** Plugin restorecon (99.5 confidence) suggests *************************
If you want to fix the label. /var/www/html/test.html default label should be httpd_sys_content_t.
Then you can run restorecon. Do # /sbin/restorecon -v /var/www/html/test.html
권고한 대로 SELinux context 를 복구하는 명령어인 restorecon 을 실행하여 문제 해결한다.
/sbin/restorecon -v /var/www/html/test.html
CODE
예제 #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 를 재구동하고 웹브라우저로 연결하면 문제가 해결될 것이다.