개요

SELinux 를 어렵게 느끼는 원인중에 하나는 SELinux 의  error message 가 너무 이해하기 어렵다는 점이다.

setroubleshoot 는 python 으로 만들어진 유틸리티로 어려운 에러 메시지를 알기 쉽게 번역해 주고 처리 방안도 제시해 주는 유틸리티이다.

audit2why 가 익숙하지 않다면 꼭 설치해서 사용해 보자.


설치

다음 패키지를 설치하면 된다.

yum install setroubleshoot


SELinux 의 에러 메시지는 /var/log/message 에 남게 되는데 다음과 같은 에러가 난다면 message bus daemon 이 구동되지 않아서 이다. 

Error Message

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

잘못된 보안 컨텍스트 설정으로 인해 웹서버가 컨텐츠를 읽지 못할 경우 처리법을 알아보기 위해 실제 상황에 기반한 예제를 실행해 보자.

  1. 파일을 /root 에 생성한 후에 mv 로 웹 서버 폴더에 이동시킨다. (참고 - cp/mv 와 SELinux security context)

    $ touch /root/test.html
    $ mv /root/test.html/var/www/html
    $ service httpd restart
  2. 텍스트 브라우저로 연결하여 웹 서버가 test.html 에 연결하지 못해 403 에러가 나는 것을 확인한다.

    $ links -dump http://localhost/test.html
     
      Forbidden
       You don't have permission to access /test.html on this server.
  3. 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
  4. 로그에 남은 대로 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

  5. 권고한 대로 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 를 재구동하고 웹브라우저로 연결하면 문제가 해결될 것이다.





blog comments powered by Disqus