SELinux 를 이해하기 위해서 먼저 접근 통제란 무엇이고 주요 접근 통제 방법인 임의 접근 통제와 강제 접근 통제에 대해서 알아 봅시다.


접근 통제

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

접근 통제에서는 시스템 자원을 객체(Object)라고 하며 자원에 접근하는 사용자나 프로세스는 주체(Subject)라고 정의합니다.

즉 /etc/passwd 파일은 객체이고 이 파일에 접근해서 암호를 변경하는 passwd 라는 명령어는 주체이며 아파치 웹 서버의 설정 파일인 /etc/httpd/conf/httpd.conf 는 객체이며 웹 서버 프로그램인 /sbin/httpd 는 주체가 됩니다.

임의 접근 통제(DAC)

임의 접근 통제(DAC;Discretionary Access Control)는 시스템 객체에 대한 접근을 사용자나 또는 그룹의 신분을 기준으로 제한하는 방법입니다.

사용자나 그룹이 객체의 소유자라면 다른 주체에 대해 이 객체에 대한 접근 권한을 설정할 수 있습니다.

여기서 임의적이라는 말은 소유자는 자신의 판단에 의해서 권한을 줄 수 있다는 의미이며 구현이 용이하고 사용이 간편하기 때문에 전통적으로 유닉스나 윈도우등 대부분의 운영체제의 기본 접근 통제 모델로 사용되고 있습니다.

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

특히 root 계정은 모든 권한을 갖고 있으므로 root 권한을 탈취하면 시스템을 완벽하게 장악할 수 있으며 권한 탈취시 많이 사용되는 것은 아래에서 설명할 유닉스의 구조적인 2가지 보안 취약점입니다.


setuid/setgid 문제

사용자들의 암호는 /etc/shadow 에 저장되어 있으며 루트만 읽고 쓸수 있습니다.

하지만 사용자들은 passwd 명령어를 실행하여 자신의 암호를 변경할 수 있고 이때 /etc/shadow 파일이 수정됩니다.

상대방 호스트가 동작하는지 확인하기 위해 사용하는 ping 은 ICMP(Internet Control Message Protocol) 패킷을 사용하므로 루트 권한이 필요하지만 일반 사용자도 ping 명령어를 사용하여 상대 호스트의 이상 여부를 확인할 수 있습니다.


유닉스 계열의 운영 체제는 실행 파일의 속성에 setuid(set user ID upon execution)또는 setgid(set group ID upon execution) 비트라는 것을 설정할 수 있으며 이 비트가 설정되어 있을 경우 해당 프로그램을 실행하면 실행 시점에 설정된 사용자(setuid), 또는 그룹(setgid) 권한으로 동작합니다.


이를 확인해 보기 위해 대표적인 setuid 비트가 붙은 프로그램인 pingpasswd 의 권한을 확인해 봅시다.


파일의 사용자 퍼미션 부분의 's' 표시는 setuid 비트이며 그룹 퍼미션 부분에 's' 표시가 있을 경우 setgid 비트로 passwd 와 ping 은 setuid 비트가 설정되어 있고 소유자가 root 인 것을 알수 있습니다.

즉 passwd 나 ping 는 실행시 root 사용자로 전환되므로 root 만 가능한 동작(예: /etc/passwd 파일 수정)을 수행할 수 있습니다.

배포판의 종류와 버전에 따라 ping 에 setuid 비트가 붙지 않았을 수도 있습니다.


하지만 setuid 비트가 붙은 프로그램에 보안 취약점이 있을 경우 root 로 구동중이었으므로 공격자가 손쉽게 루트 권한을 획득할 수 있는 문제가 있습니다.

이 때문에 setuid 비트는 필요하지만 유닉스 시스템의 주요 보안 취약점이었으며 시스템 관리자의 골칫 덩어리이었습니다.


리눅스 시스템에 있는 setuid 비트(4000)와 setgid 비트(2000)이 붙은 모든 프로그램은 다음 명령어로 찾을 수 있습니다.


잘 알려진 포트 daemon 문제

잘 알려진 포트(well-known port) 는 특정한 쓰임새를 위해서 "인터넷 할당 번호 관리기관"(IANA; Internet Assigned Numbers Authority)에서 할당한 TCP 및 UDP 포트 번호들의 일부로 1024 미만의 포트 번호를 사용하고 있습니다.

예로 웹에 사용되는 http(80), 메일 전송에 사용되는 smtp(25), 파일 전송에 사용되는 ftp(20, 21) 등이 잘 알려진 포트입니다.

전통적으로 잘 알려진 포트는 루트만이 사용할 수 있으므로 데몬 서비스는 모두 루트의 권한으로 기동됩니다.

보안 문제는 여기에서 발생하며 루트로 구동되었으므로 만약 서비스 데몬이 보안 취약점이 있거나 잘못된 설정이 있을 경우 서비스 데몬을 통해서 공격자는 루트 권한을 획득하게 될 위험이 있으며 이때문에 웹 서버등은 구동한 후에 자식 프로세스를 생성(fork 시스템 콜)한 후에 쉘이 없는 사용자 계정으로 전환해서 동작하고 있습니다.


예로 아파치 웹 서버(User/Group 지시자)와 nginx(user 지시자)는 아래와 같이 구동할 사용자를 지정하고 있습니다.

위와 같이 사용자 전환을 하지만 부모 프로세스는 계속 루트로 구동되어 있으므로 1024 미만의 포트를 사용하는 데몬 프로세스에 대한 보안 대책이 필요하게 됩니다.


그러나 1024 미만의 포트를 일반 사용자가 쓸 수 있게 하거나 root 가 아닌 별도의 계정에게만 허용하는 것은 전통적인 유닉스의 동작 방식에 어긋나며 커널 수정이나 기타 유틸리티의 대폭 수정이 필요하며 운영자의 혼란을 유발하므로 좋은 방법이 아닙니다.

강제 접근 통제(MAC)

강제 접근 통제(MAC; Mandatory Access Control)는 미리 정해진 정책과 보안 등급에 의거하여 주체에게 허용된 접근 권한과 객체에게 부여된 허용 등급을 비교하여 접근을 통제하는 모델입니다.

높은 보안을 요구하는 정보는 낮은 보안 수준의 주체가 접근할 수 없으며 소유자라고 할 지라도 정책에 어긋나면 객체에 접근할 수 없으므로 강력한 보안을 제공합니다.


MAC 정책에서는 루트로 구동한 http 서버라도 접근 가능한 파일과 포트가 제한됩니다. 즉 취약점을 이용하여 httpd 의 권한을 획득했어도 /var/www/html/etc/httpd 등의 사전에 허용한 폴더에만 접근 가능하며 80, 443, 8080 등 웹 서버에 사전에 허용된 포트만 접근이 허용되므로 ssh로 다른 서버로 접근을 시도하는등 해킹으로 인한 이차 피해가 최소화 됩니다.

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