운영 체제에서 접근 통제(Access Control)란 디렉터리나 파일, 네트워크 소켓같은 시스템 자원을 적절한 권한을 가진 사용자나 그룹이 접근하고 사용할수 있도록 통제하는 것을 의미하며 보안의 중요한 요소중 하나이다.

시스템 자원을 객체(Object) 라고 하며 자원에 접근하는 사용자나 프로세스는 주체(Subject) 라고 호칭하며 SELinux 에 대해 알아 보기 전에 객체와 주체를 통제하는 접근 통제 모델에 대해서 간략하게 알아 보도록 하자.

접근 통제 모델

임의적 접근 통제(DAC - Discretionary Access Control)

임의적 접근 통제는 시스템 객체에 대한 접근을 사용자나 또는 그룹의 신분을 기준으로 제한하는 방법이다. 사용자나 그룹이 객체의 소유자라면 다른 주체에 대해 이 객체에 대한 접근 권한을 설정할 수 있다. 여기서 임의적이라는 말은 소유자는 자신의 판단에 의해서 권한을 줄 수 있다는 의미이다.

구현이 용이하고 사용이 간편하기 때문에 전통적으로 유닉스나 윈도우등 대부분의 운영체제의 기본 접근 통제 모델로 사용되고 있다.

임의적 접근 통제는 사용자가 임의로 접근 권한을 지정하므로 사용자의 권한을 탈취당하면 사용자가 소유하고 있는 모든 객체의 접근 권한을 가질 수 있게 된다.


임의적 접근 통제 방식의 보안 취약점에 대해 설명하기 위해 유닉스의 setuid 비트와 에 대해서 알아 보자.

사용자들은 자신의 암호를 passwd 명령어를 실행하여 변경할 수 있는데 사용자의 암호는  /etc/shadow 에 저장되며 이 파일은 루트만 접근 가능하다.

상대방 호스트가 동작하는지 확인하기 위해 ping 명령어를 사용할 경우 ICMP 패킷을 송신하려면 루트 권한이 필요하지만 일반 사용자도 ping 명령어를 사용하여 상대 호스트의 이상 여부를 확인할 수 있으며 passwd 명령어로 자신의 암호를 변경할 수 있다.

 이는 passwd 나 ping 같이 실행시 루트 권한이 필요한 프로그램에는 setuid 비트라는 것을 설정하여 실행한 사용자가 누구든지 setuid 비트가 설정된 프로그램은 루트로 동작하도록 설계하였으므로 가능한 일이다.

"ls -l /bin/ping/ /usr/bin/passwd" 명령어를 실행하면 파일의 퍼미션 부분에 's' 표시가 보일 것이다. 이 's' 가 있는 프로그램들은 setuid 비트가 켜졌다고 하며 이런 프로그램들은 실행시 루트 권한을 갖고 구동되므로 만약 프로그램에 보안 취약점이 있을 경우 사용자는 손쉽게 루트 권한을 획득할 수 있는 문제가 있다. 이때문에 setuid 비트는 필요는 하지만 유닉스 시스템의 주요 보안 취약점이었으며 시스템 관리자의 골칫 덩어리이기도 했다.

setuid 비트가 설정된 프로그램

setuid 비트는 숫자로 4000 으로 표시되며 find 명령어에 -perm 옵션을 주어서 비트가 설정된 파일을 찾을 수 있다. 독자들도 다음 명령어로 리눅스에 어떤 프로그램들이 setuid 비트를 갖고 있는지 확인해 보자.

find /bin /usr/bin /sbin -perm -4000 -exec ls -ldb {} \;

또 하나의 주요 보안 취약점은 바로 네트워크 데몬 서비스로 유닉스는 네트워크 포트 번호 1024 이하는 루트만 사용 가능하며 http, smtp, ftp, telnet 등 잘 알려진 서비스들은 모두 1024 이하의 포트 번호를 사용하므로 이런 주요 서비스 데몬 프로그램들은 모두 루트 사용자가 구동해야 하며 프로세스들도 루트 권한을 갖고 실행되어야 한다.


이런 서비스 데몬 프로그램들이 잘못된 설정을 갖고 있거나 보안 버그가 있거나 또는 제로 데이 공격등으로 해킹을 당할 경우 임의적 접근 통제를 사용하는 시스템은 공격자가 루트 권한을 획득할 수 있게 되므로 심각한 결과를 가져올 수 있다.

이로 인해 보안에 민감한 시스템이나 인터넷에 연결하여 임의의 클라이언트들에게 서비스를 제공하는 서버라면 임의적 접근 통제 방식은 적합하지 않은 접근 통제 방식이다.

제로 데이 공격

제로 데이 공격은 소프트웨어의 보안 취약점을 공격하는 공격 방식의 하나로  해당 취약점에 대해 아직 안 알려졌거나 알려졌어도 패치가 아직 발표되지 않은 시점에 이루어 지는 공격을 말한다.

취약점에 대한 대책이 없기 때문에 공격을 막을수가 없어서 심각한 피해로 이루어 질 수 있다.

 

강제 접근 통제(MAC - Mandatory Access Control)

강제 접근 통제는 미리 정해진 정책과 보안 등급에 의거하여 주체에게 허용된 접근 권한과 객체에게 부여된 허용 등급을 비교하여 접근을 통제하는 모델이다. 높은 보안을 요하는 정보는 낮은 보안 수준의 주체가 접근할 수 없으며 소유자라고 할 지라도 정책에 어긋나면 객체에 접근할 수 없으므로 강력한 보안을 제공한다.

단점으로는 구현이 복잡하고 어려우며 모든 주체와 객체에 대해서 보안 등급과 허용 등급을 부여하여야 하므로 설정이 복잡하고 시스템 관리자가 접근 통제 모델에 대해 잘 이해하고 있어야 한다.

여기까지 읽은 독자들은 그래도 임의 접근 통제와 강제 접근 통제에 대해 정확히 이해가 되지 않을 수 있다. 현실적인 사례와 비교해서 설명하면 다음과 같다.

회사마다 이름과 역할이 약간씩 다를수 있겠지만 대개의 회사는 보통 경영지원팀 이라는 이름의 조직을 갖고 있다. 이 조직안에는 "기획, 인사/노무, 교육, 총무, 재무/회계, 구매, 홍보, 법무"  같이 다양한 직무와 담당자가 있을 수 있다. 

임의 접근 통제는 모든 기획 자료는 기획 담당자의 소유가 되며 열람과 수정에 대한 권한도 모두 갖게 된다. 다른 팀에서 새로 작성한 기획 자료도 기획자 소유가 되어 버리므로 기획 담당자 권한만 있다면  모든 자료가 유출될 수 있다.

강제 접근 통제는 모든 기획 자료에 대해 열람 가능자와 허용 권한을 모두 설정하고 이에 따라 권한 통제를 한다고 보면 된다.

높은 보안이 필요한 기획 자료는 기획 업무 담당자라도 접근할 수 없으며 설사 소유자라도 열람할 수 없다.

SELinux 소개

SELinux 는 미국 국가안보국(NSA - National Security Agency)이 개발한 Flask 라는 보안 커널을 리눅스에 이식한 커널 레벨의 보안 모듈이다. NSA는 리눅스에 강제 접근 통제를 구현하기 위해 리눅스 커널의 많은 부분을 수정했으며 그 결과물을 리눅스 커뮤니티에 기증하여 2003년부터 2.6 버전의 커널에 공식 포함되게 되었다. 

RHEL 기반의 배포판에는 버전 4부터 공식적으로 포함되었으며 ls, cp, mv, ps 등의 많은 유틸리티등도 SELinux를 지원하게 수정이 되었다.

현재는 많은 제품들이 SELinux 를 지원하므로 기본적인 개념과 설정 방법을 익힌다면 큰 어려움 없이 사용할 수 있을 정도가 되었다.


SELinux의 장점

  • 사전 정의된 접근 통제 정책 탑재
    사용자, 역할, 타입, 레벨등의 다양한 정보를 조합하여 어떤 프로세스가 어떤 파일, 디렉터리, 포트등에 접근 가능한지에 대해 잘 정의된 접근 통제가 제공되므로 강제 접근 통제 적용을 위해 시스템 관리자가 할 일이 대폭 줄었다.
  • "Deny All, Permit Some" 정책으로 잘못된 설정 최소화
    "모든 걸 차단하고 필요한 것만 허용"하는 정책은 단순하면서 강력한 정보 보호를 위한 최선의 정책이다. 네트워크 방화벽등이 이런 접근 방식을 취하고 있으며 SELinux 의 보안 정책도 이 방식으로 사전에 설정되어 있으므로 잘못된 설정이 기본 포함되어 있을 여지가 적다.
  • 권한 상승 공격에 의한 취약점  감소
    setuid 비트가 켜져 있거나 루트로 실행되는 프로세스처럼 위험한 프로그램들은 샌드박스안에서 별도의 도메인으로 격리되어 실행되므로 루트 권한을 탈취해도 해당 도메인에만 영향을 미치고 전체 시스템에 미치는 영향을 최소화 한다. 예로 아파치 httpd 서버의 보안 취약점을 통해 권한을 획득했어도 아파치같은 서버 데몬은 낮은 등급의 권한을 부여 받으므로 공격자는 일반 사용자의 홈 디렉터리를 읽을 수 없고 /tmp 임시 디렉터리에 파일을 쓸 수가 없다.
    또 다른 예로 파일 공유 서비스인 삼바와 mysql DBMS 가 같이 구동되는 서버에서 삼바를 공격하여 권한을 탈취한 후에 삼바를 통해 mysql 데이타베이스 파일을 가져가려고 시도할 수 있다. SELinux 하에서는 삼바와 mysql 은 별도의 도메인으로 격리되어 동작하므로 공격자가 삼바 프로세스의 권한을 획득했더라도 mysql 의 데이타 파일에는 접근할 수 없다.
  • 잘못된 설정과 버그로부터 시스템 보호
    데이타와 기밀성과 무결성을 적용할 수 있으며 신뢰할 수 없는 입력에서 프로세스를 보호할 수 있다. 예로 버퍼의 입력 길이등을 제대로 체크하지 않아서 발생하는 버퍼 오버 플로 공격(buffer overflow attack)의 경우 SELinux 는 어플리케이션이 메모리에 있는 코드를 실행할 수 없게 통제하므로 데몬 프로그램에 버퍼 오버 플로 버그가 있어도 쉘을 얻을 수가 없다.


메신저를 쏘지 마시오. (Don't Shoot the messenger)

안좋은 소식에 대응하는 가장 나쁜 방법은 아예 소식을 전하지 못하게 하는 것이다. 

인터넷에서 SELinux 를 검색해 보면 대개의 문서들이 리눅스 설치후 첫 번째로 할 일로 SELinux 작동을 중지 시키라고 권하고 있다. 

SELinux 를 끄는 것은 운전중에 차량에 경고등이 들어 왔다고 경고등 램프를 빼는 것과 마찬가지이다. 경고등이 켜졌다는것은 어딘가에 문제가 생겼을 수도 있고 아니면 경고등이 고장났을 수도 있지만 가장 최선은의 대응은 경고등이 켜진 원인을 찾고 그에 따라 행동하는 것이다.

하지만 대다수의 웹 문서가 리눅스 설치후 가장 먼저 하는 일이 SELinux 작동 중지일 정도로 사용자들이 불편해 하는 이유는 무엇일까?

필자의 경험에 의거한 주요 이유는 다음과 같았다.

  • SELinux에 대한 자료 부실
    현실적인 이유이며 사실 그렇기도 하다. 인터넷을 찾아봐도 자료가 많지 않으며 그중 대다수는 SElinux 를 끄는 방법에 대한 자료이다.
    다행히 레드햇과 리눅스 커뮤니티의 노력으로 기본 설정만으로 쉽게 사용 가능할 정도로 SELinux 정책이 잘 정리되어 있으며 정책을 관리하고 모니터링하기 위한 관리 유틸리티가 많아지고 사용이 편리해 졌다.
  • 에러 발생시 원인을 알기 어렵다.
    SELinux 하에서 프로그램이 차단되었을 경우 제대로 에러 메시지가 나오지 않으므로 원인을 알기 어려운 경우가 있다. 예로 아파치 httpd 가 읽으려는 파일이 분명히 있지만 파일을 읽지 못해 "File not Found" 에러가 발생하여 원인을 찾지 못하고 SELinux 를 끄고 사용하는 경우가 있다. 이는 SELinux 의 의도한 설계로 정확한 에러 메시지를 보안 정책을 위해해서 차단한 application 에 전달하는 것은 보안 측면에서 바람직하지 않은 일이고 공격자가 필요한 정보를 제공하는 일이 될 수도 있다. SELinux 가 발생시키는 에러는 별도의 로그 파일에 기록되며 알아 보기 어려우므로 기반 지식이 없다면 해결이 어려울 수 있지만 이런 문제 해결을 위해  여러 가지 유틸리티가 있으므로 뒷 절에서 이런 유틸리티를 사용하여 문제를 해결해 보자.
  • 보안에 대해서 그리 심각하게 생각하지 않고 문제가 발생하면 대처하면 된다고 믿는다.
    인터넷에 연결되고 외부에 서비스를 제공하기 위해 DMZ 에 위치하는 서버라면 일단 보안에 취약해 졌다고 생각해야 한다. 모두가 보안 전문가가 될 필요는 없지만 이제는 보안에 대한 지식은 관리자나 개발자도 일정 수준 이상은 필수로 갖춰야 하며 보안 사고가 발생할 경우의 후폭풍을 생각하면 사전에 미리 여러 가지 보안 강화 조치를 취해야 한다.


위와 같은 이유때문에 SELinux 를 꺼 놓고 사용했던 독자라면 본 장을 읽고 SELinux 에 대한 이해도를 높이고 이를 리눅스 시스템의 강력한 보초병으로 활용하게 되기를 기대한다.

이제 다음 절부터 SELinux 를 사용하는 데 필요한 기본 지식을 익혀 보자.


SELinux 의 한계

SELinux 의 주요 목표는 잘못된 설정이나 프로그램의 보안 버그로 인해 시스템이 공격 당해도 시스템과 데이타를 보호하고 2차 피해를 막는 것이다. SELinux 는 여러 가지 보안 요소중에 하나이며 SELinux 로 모든 보안 요건이 충족되지는 않는다. SELinux 는 침입 탐지 시스템(Intrusion Detection System) 이 아니며 방화벽(Firewall)이나 바이러스 백신이 아니다. SELinux 를 사용하더라도 방화벽이나 백신, 침입 탐지가 필요하다면 혼용하여 사용해야 한다.