보안 강화 리눅스(SELinux) 분석

출처 : http://www.dbguide.net/know/know102001.jsp?mode=view&pg=1&idx=3555

보안 강화 리눅스(SELinux) 분석

 

리눅스(Linux??)는 가장 안전한 운영체제라고 합니다. 하지만 NSA(National Security Agency)는 SELinux 등장 이후 리눅스를 한 등급 높였습니다. SELinux는 물샐틈없이 보안을 강화하도록 커널과 사용자 영역을 변경해서 확장하는 토대로 GNU/리눅스 운영체제를 채택했습니다. 커널 2.6 배포판을 설치했다면, SELinux를 사용하고 있다는 사실에 놀랄지도 모르겠습니다. 이 기사는 SELinux 이면에 숨은 아이디어와 구현 방법을 설명합니다.

 

소개

 

인터넷과 같은 공중망은 위험한 장소다. (심지어 일시적이라고 할지라도) 인터넷에 붙은 컴퓨터를 소유한 어느 누구라도 이런 위험을 이해한다. 공격자들은 시스템 접근 권한을 얻거나 불법적으로 정보에 접근하거나, 스팸을 뿌리기 위해 다른 컴퓨터의 용도를 변경하거나, (분산 서비스 거부 공격의 일부로 SYN 넘침 공격을 사용하려고) 고성능 시스템 공격에 참여하기 위해 보안 취약성을 악용한다.

DDoS 공격은 인터넷에 연결된 (좀비 컴퓨터라 불리는) 여러 시스템이 연합해 목표 시스템의 자원을 고갈시켜, (TCP/IP 3단계 이중 확인을 악용하는 방법으로) 선의의 사용자들이 접속을 못하도록 방해한다. 쿠키와 4단계 이중 확인(SCTP: Stream Control Transmission Protocol)을 사용해 이런 문제점을 해결하는 프로토콜에 대한 설명이 필요하면, 참고자료 절을 읽어보기 바란다.

SELinux의 기원
SELinux는 정부와 업계가 만든 제품으로 NSA, Network Associates, Tresys가 설계하고 개발했다. 비록 NSA가 패치 집합을 공개했지만, 2.6부터 리눅스 커널 주류로 편입되었다.

GNU/리눅스는 아주 안전하지만 또한 아주 변화무쌍하기도 하다. 변경 과정에서 운영체제에 구멍이 나는 바람에 보안 침해 요소가 생길 수 있다. 물론 불법적인 접근을 막아내기 위해 상당한 주의를 기울이고 있지만, 사건이 터지고 난 다음에는 무슨 소용이 있으랴?

이 기사는 SELinux와 기본 아키텍처 이면에 숨겨진 아이디어를 설명한다. SELinux라는 주제를 완벽하게 개괄하려면 책 한 권이 필요하다. 따라서 이 기사에서는 SELinux가 중요한 이유와 구현 방법에 대한 아이디어를 주도록 기본에 충실하겠다.

 

접근 통제 기법

 

대다수 운영체제는 엔티티(사용자 또는 프로그램)가 특정 자원에 접근할 수 있는지를 판단하려고 접근 통제 기법을 사용한다. 유닉스(UNIX??) 기반 시스템은 DAC(Discretionary Access Control)를 사용한다. 이런 방법은 소속 그룹에 기반을 두고 객체 접근을 제약한다. 예를 들어, GNU/리눅스에서 파일에는 소유자, 그룹, 접근 허가 집합이 있다. 접근 허가는 특정 파일에 접근하는 사용자를 정의해 누가 읽고, 쓰고, 실행하는지를 결정한다. 이런 접근 허가는 사용자를 사용자(파일 소유자), 그룹(그룹에 속한 모든 사용자), 다른 사람(그룹에도 속하지 않고 사용자도 아닌 다른 모든 사용자)이라는 세 부류로 나눈다.

이와 같은 어색한 접근 통제 기법이 문제를 일으키는 이유는 보안 침해에 걸린 프로그램이 해당 사용자의 접근 통제 권한을 상속받기 때문이다. 따라서 프로그램은 사용자에게 부여된 접근 권한 수준에서 작업이 가능하므로, 바람직하지 못한 결과를 초래한다. 이런 방식으로 제약을 정의하는 대신에, 최소 권한 원칙을 사용하는 편이 좀 더 안전하다. 프로그램은 작업을 수행하기 위해 필요한 만큼만 권한을 얻으며, 더 이상은 권한을 얻지 않는 방법 말이다. 예를 들어, 소켓 요청에 응답해야 하지만 파일 시스템에 접근할 필요가 없는 프로그램이 있다면, 이 프로그램은 소켓에 귀를 기울이지만 파일 시스템에는 접근 권한이 없어야 한다. 이런 방식을 따르면, 프로그램이 어떤 식으로 보안 침해에 걸리더라도 접근이 명시적으로 최소화된다. 이런 통제 기법을 MAC(Mandatory Access Control)라 부른다.

또 다른 통제 기법으로 RBAC(Role-Based Access Control)가 있다. RBAC에서, 접근 허가는 보안 시스템이 허용한 역할에 기반을 두고 접근 허가를 제공한다. 이런 역할 개념은 한 명 이상의 사용자를 표현하는 그룹이라는 측면에서 전통적인 그룹과 차이를 보인다. 역할은 여러 사용자를 대표하지만, 사용자 집합이 수행할 수 있는 접근 허가 역시 표현한다.

SELinux에서는 MAC와 RBAC를 둘 다 GNU/리눅스 운영체제에 추가했다. 다음 절은 SELinux 구현과 보안 요소를 리눅스 커널에 투명하게 추가한 방법을 설명한다.

 


 

리눅스 보안 구현

 

초창기 SELinux 시절에는, 패치 집합이 있었음에도 불구하고, 독자적인 보안 프레임워크를 제공했다. 이런 정책이 문제가 된 이유는 GNU/리눅스를 단일 접근 통제 아키텍처로 묶어버렸기 때문이다. 단일 접근 방식을 채택하는 대신, 리눅스 커널은 정책을 강제하지 않도록 일반화된 프레임워크를 상속받았다. 이런 해법이 바로 LSM(Linux Security Module) 프레임워크다. LSM은 적재 가능한 커널 모듈로 구현된 보안용 범용 프레임워크를 제공한다(그림 1 참조).


그림 1. 보안 정책과 강제는 SELinux와 독립적이다.

커널 코드를 수정해 내부 객체에 접근하기 앞서 보안 정책을 구현한 강제 함수라는 훅을 호출하도록 만든다. 이 함수는 미리 정해진 정책을 기반으로 연산을 계속할지 검증한다. 보안 함수는 반드시 보호되어야 하는 기본적인 연산을 다루는 보안 연산 구조체 내부에 저장되어 있다. 예를 들어, security_socket_create 훅( security_ops->socket_create )은 새로운 소켓을 생성하기 앞서 접근 허가를 검사하며 프로토콜 가족, 유형, 프로토콜, 소켓이 커널 내부에서 만들어지는지 사용자 영역에서 만들어지는지를 고려한다. Listing 1은 소켓 생성을 위한 socket.c에서 가져온 코드 예제다(./linux/net/socket.c 참조).


 

Listing 1. 소켓 생성을 위한 커널 코드

static int __sock_create(int family, int type, int protocol,
struct socket **res, int kern)
{
int err;
struct socket *sock;

/*
* 프로토콜이 범위 내에 있는지 점검한다.
*/
if (family < 0 || family >= NPROTO)
return -EAFNOSUPPORT;
if (type < 0 || type >= SOCK_MAX)
return -EINVAL;

err = security_socket_create(family, type, protocol, kern);
if (err)
return err;

...


 

security_socket_create 함수는 ./linux/include/linux/security.h에 정의되어 있다. 여기서 security_socket_create 함수 호출은 security_ops 구조체에 동적으로 설치된 함수를 간접 호출하는 방식으로 동작한다(Listing 2 참조).


 

Listing 2. 소켓 생성 점검을 위한 간접 호출

static inline int security_socket_create (int family, int type,
int protocol, int kern)
{
return security_ops->socket_create(family, type, protocol, kern);
}

security_ops 구조체에 저장된 함수는 보안 모듈이 설치한다. 이 경우 훅은 SELinux용 적재 가능한 커널 모듈에 정의되어 있다. 각 SELinux 호출은 커널 함수에서 특정 보안 모듈을 위한 동적 호출로 간접 수행을 완료하는 훅 파일 내부에 정의된다(Listing 3에서 /linux/security/selinux/hooks.c를 살펴보라).


 

Listing 3. SELinux 소켓 생성 점검

static int selinux_socket_create(int family, int type,
int protocol, int kern)
{
int err = 0;
struct task_security_struct *tsec;

if (kern)
goto out;

tsec = current->security;
err = avc_has_perm(tsec->sid, tsec->sid,
socket_type_to_security_class(family, type,
protocol), SOCKET__CREATE, NULL);

out:
return err;
}


 

Listing 3의 핵심은 현재 태스크에 허용된( current->security , 여기서 current 는 현재 수행중인 태스크를 나타낸다) 현재 연산을 점검하는 호출이다. AVC(Access Vector Cache)는 (프로세스 성능을 높이기 위해) 직전 SELinux 결정을 담고 있는 캐시다. 호출은 sid(source security identifier), 보안 클래스(요청된 연산의 세부 사항으로 만들어지는), 특정 소켓 호출, 추가 보조 감사 자료를 포함한다. 캐시 내부에서 결정을 찾지 못하면, 보안 서버를 호출해 결정을 내린다(그림 2에 이런 과정이 나타나 있다).


그림 2. 계층적인 리눅스 보안 결정 과정

security-ops 내에 초기화된 콜백 훅은 ( register_security() 를 통해) 적재 가능한 커널 모듈로 동적으로 정의되지만 그렇지 않다면 보안 모듈을 올리지 않은(./linux/security/dummy.c 참조) 상태에서 더미 스텁 함수를 포함한다. 이런 스텁 함수는 표준 리눅스 DAC 정책을 구현한다. 콜백 훅은 보안을 위한 중재가 필요한 모든 지점에 존재하며, 태스크 관리(생성, 시그널, 대기), 프로그램을 메모리에 올리기(execv), 파일 시스템 관리(슈퍼 블록, 아이노드, 파일훅), IPC(메시지 큐, 공유 메모리, 세마포어 연산), 모듈 훅(모듈 적재와 제거), 네트워크 훅(소켓, 넷링크, 네트워크 디바이스, 기타 프로토콜 인터페이스)을 포함한다. 참고자료 절을 보거나 security.h 파일을 살펴보는 방법으로 훅에 대한 다양한 정보를 얻을 수 있다.

SELinux에서 정책 관리 방법은 이 기사 범위를 넘어가므로, 참고자료 절에서 SELinux 환경 설정에 대한 더 많은 정보를 찾아보기 바란다.


 

다른 접근 방법

 

SELinux는 현존하는 가장 포괄적인 보안 프레임워크 중 하나지만 유일한 해법은 아니다. 이 절에서는 사용 가능한 몇 가지 다른 접근 방법을 검토한다.

 

AppArmor

원래 immunix가 개발했으며 노벨(Novell)이 관리하는 AppArmor는 LSM(Linux Security Module)을 사용해 만든 SELinux 대안 프레임워크다. SELinux와 AppArmor는 동일한 프레임워크를 사용하므로 상호 교환이 가능하다. AppArmor를 처음 개발한 이유는 SELinux가 일반 사용자가 관리하기에는 너무 복잡하게 보였기 때문이다. AppArmor는 프로그램의 전형적인 행동 양식을 프로파일로 바꾸는 학습 모드와 더불어 완벽하게 설정 가능한 MAC 모델을 포함한다.

SELinux와 관련한 쟁점 하나는 SELinux는 확장 속성을 지원하는 파일 시스템을 요구한다는 사실이다. 하지만 AppArmor는 파일 시스템에 중립적이다. SuSE, OpenSuSE, Ubuntu Gutsy Gibbon에서 AppArmor를 찾을 수 있다.

 

Solaris 10(기존 Trusted Solaris)

Solaris 10 운영체제는 보안 강화 신뢰 확장 구성 요소를 통해 위임 접근 통제 기능을 제공한다. Solaris 10은 MAC은 물론이고 RBAC도 제공한다. Solaris는 모든 객체에 민감도 라벨을 추가하는 방법으로 보안을 달성한다. 이렇게 하면 디바이스, 파일, 네트워크 접근, 심지어 윈도우 관리 서비스에 대한 통제가 가능하다. Solaris 10에서 RBAC를 사용해 얻는 장점은 할당될 수 있는 관리 작업을 세밀하게 분류함으로써 루트 접근 요청을 최소로 줄이는 데 있다.

 

TrustedBSD

TrustedBSD는 FreeBSD 운영체제를 위한 궁극적인 목표인 신뢰할 수 있는 운영체제 확장을 개발하려는 프로젝트다. TrustedBSD는 Flask(Flux Advanced Security Kernel) 보안 아키텍처 위에 만든 위임 접근 통제 기능을 포함한다. Flask는 타입 강제, MLS(MultiLevel Security), 플러그인 모듈을 포함한다. TrustedBSD는 또한 애플 다윈 운영체제에서 따온 오픈 소스 BSM(Basic Security Module) 감사 구현 기능을 편입했다(BSM은 원래 썬이 만들었다). BSM은 일반화된 감사 추적 과정을 지원하는 감사 API와 파일 형식이다. TrustedBSD는 또한 SEDarwin(Security Enhanced Darwin)이 사용하는 프레임워크를 구성한다.

 

운영체제 가상화

운영체제 내부에서 보안을 강화하는 기술로 마지막으로 소개할 내용은 (가상 전용 서버라 부르는) 운영체제 가상화다. 단일 운영체제가 기능을 분리하기 위한 수단으로 격리된 사용자 영역 인스턴스 여러 개를 돌린다. 운영체제 가상화는 또한 격리된 사용자 영역에서 동작하는 응용 프로그램 기능을 제한한다. 예를 들어, 사용자 영역 인스턴스는 (커널 모듈을 올리고 내리는 방식으로) 커널을 변경하거나 파일 시스템을 마운트/언마운트하지 못한다. (proc 파일 시스템을 통한) 커널 매개변수 조정 역시 허용되지 않는다. 다른 사용자 인스턴스 환경을 변경하는 작업도 허용되지 않는다.

운영체제 가상화는 여러 운영체제에서 사용 가능하다. GNU/리눅스는 VServer, Paralles Viruozzo Containers, OpenVZ를 지원한다. 다른 운영체제에서는 containers(Solaris), jails(BSD)를 지원한다. 리눅스 VServer에서는 개별 사용자 영역 인스턴스를 보안 문맥으로 부른다. 각 보안 문맥 내부에서, 전용 서버 인스턴스에 대해 새로운 init을 시작한다. 운영체제 가상화와 다른 가상화 기법은 참고자료 절을 참조하기 바란다.

 



 

한걸음 더 나가면

리눅스 커널 관점에서 MAC와 규칙 기반 접근 통제는 상대적으로 새롭다. LSM 프레임워크 도입 이후에 새로운 보안 모듈이 등장했다. 프레임워크 개선에 덧붙여, 보안 모듈을 층층이 쌓아 리눅스 보안 요구를 최대한 충족하도록 여러 보안 모듈을 공존하게 만들었다. 또한 운영체제 보안 연구 결과 새로운 접근 통제 기법이 계속해서 등장할 것이다. LSM과 SELinux가 현재 제공하는 세부 내역이 궁금하다면 참고자료 절에 실린 기사와 논문을 읽어보기 바란다.

 

참고자료

교육

 

필자소개

M. Tim Jones는 임베디드 소프트웨어 아키텍트이자 GNU/Linux Application Programming, AI Application Programming, BSD Sockets Programming from a Multilanguage Perspective의 저자이기도 한다. Jones의 공학 배경은 정지 위성을 위한 커널 개발에서 시작해 임베디드 시스템 아키텍처와 네트워크 프로토콜 개발에 이르기까지 다양한 분야를 아우른다. Jones는 콜로라도 주, 롱몬트 소재 Emulex 사에서 컨설턴트 엔지니어로 활약한다

by amplengine | 2008/09/26 15:41 | Linux/Unix | 트랙백 | 덧글(1)

트랙백 주소 : http://amplengin2.egloos.com/tb/876528
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 그리움 at 2014/03/18 14:04
리눅스 사용이 늘어나면서 리눅스에 대한 공격도 증가하고 있다고 하지요.eScan은 파일의 데이터 스트림을 읽어
숨겨진 바이러스를 감지하고, 휴리스틱 검색 엔진은 1,200,000여개의 바이러스를 잡아낼 수 있다고 합니다.
실시간 감시기능이 있는 [리눅스 백신 이스캔] 을 사용하면, 감염된 파일을 찾아주기도 하지만, 파일이 실행되거나,
수정될 때에도 검사하여 저장되기 전에 차단하기 때문에 큰 도움이 될 수 있을 듯 합니다

:         :

:

비공개 덧글

◀ 이전 페이지다음 페이지 ▶