1. 개요 

AppArmor는 리눅스에서 특정 프로그램이 어떤 파일이나 기능에 접근할 수 있는지를 제어할 수 있는 MAC(강제 접근 통제) 기반 보안 모듈이다. 리눅스는 윈도우와 달리 실시간 백신이 기본 탑재되어 있지 않기 때문에, 시스템 파일이 변조되거나 악성코드에 침투당해도 명확한 경고 없이 조용히 동작하는 경우가 많다.

이로 인해 사용자가 침해 사실을 알아채지 못한 채 넘기는 일이 잦은데, AppArmor를 사용하면 관리자가 설정한 정책에 따라 root 권한을 가진 프로세스조차 제어할 수 있어 시스템을 보다 안전하게 운영할 수 있다.
이번 글에선 우분투에서 AppArmor 정책을 간단히 설정해보며, 그 동작 방식을 이해해보려고 작성했다.

2. AppArmor 특징

2-1. 경로 기반 프로파일 구조 (/etc/apparmor.d/)

  • AppArmor는 “AppArmor는 ‘프로세스 자체’가 아니라, 실행 파일의 경로를 기준으로 접근 권한을 제어하며, 동일한 실행 파일이라도 위치가 다르면 별도의 정책이 필요하다.
  • 예시로, /usr/bin/man 이라는 실행 파일에 정책을 걸면 이걸 실행하는 모든 프로세스가 제약을 받으나, 경로가 다르면 다른 프로그램으로 인식하여 완전히 방어하기엔 어려운 특징을 보인다.
  • /etc/apparmor.d/ : AppArmor가 자동으로 불러오는 디렉터리로, 프로파일이 이 곳에 저장된다.
  • /etc/apparmor.d/에 실행 파일 경로 기준의 프로파일을 저장하는데, 이때 경로를 / 대신 . 으로 바꾼 형식으로 저장한다.
    예를 들면, usr/sbin/apache2에 대한 정책 => usr.sbin.apache2 

2-2. 프로파일 구성 (r, w, x, deny 등)

#include <tunables/global>

profile /usr/bin/man {
# 이 파일은 읽기 허용
  /usr/bin/man r, 
  /etc/manpath.config r,
 # /tmp는 읽고 쓰기 허용
  /tmp/ rw,
 # /etc/shadow는 읽지 못하게 막는다
  deny /etc/shadow r,

  capability net_bind_service,
}

2-2-1. 프로파일 구성요소 설명

프로파일이란 특정 프로그램이 어떤 파일이나 디렉터리에 대해 읽기(r), 쓰기(w), 실행(x) 등의 권한을 가지는지 정의하는 설정 파일이다. 예를 들어, /usr/bin/man 프로그램에 대한 프로파일은 해당 프로그램이 접근할 수 있는 자원과 그 권한을 지정한다. 주요 구성 요소는 다음과 같다:

  • profile /경로 { ... } : 어떤 파일에 대한 정책인지 명시하는데, 여기선  /usr/bin/man 파일에 대한 정책을 알려준다
  • r, w, x : 읽기, 쓰기, 실행 권한
  • deny : 명시적으로 막는 것
  • capability : 시스템 기능 권한 부여 (예: 포트 바인딩)

2-2-2. 프로파일 작성 방법

먼저 수동 방법으로, 사용자가 직접 /etc/apparmor.d/ 폴더에 .profile 파일을 만든다. 자유도 높고 원하는 대로 세팅할 수 있다.

# 수동으로 작성 시
sudo nano /etc/apparmor.d/usr.bin.man

다음으로, aa-genprof 도구를 사용하여 프로파일을 자동으로 생성하는 방법이다. AppArmor가 실행 로그를 보면서 자동으로 프로파일을 만들어주는 도구로, 지정 프로그램을 감시하면서 허용할 지 말 지를 물어본 후 프로파일을 만들어준다. 전부 끝나면 /etc/apparmor.d/에 자동으로 저장된다.

sudo aa-genprof /usr/bin/man

다음으로 기본 프로파일 템플릿을 복사하는 방법이다. 우분투에는 일부 프로그램의 미리 준비된 기본 프로파일이 존재하는데, /etc/apparmor.d/disable/ 에 있으며, 여기 있는 걸 복사해서 쓸 수도 있다. 기본적으로 비활성화 상태인 프로파일들이 이 경로에 있으며, 필요할 경우 복사해서 활성화할 수 있다.

sudo cp /etc/apparmor.d/disable/usr.bin.man /etc/apparmor.d/usr.bin.man

2-2-2. 정책 적용 명령어

# usr/bin/man 파일에 정책을 강제 적용
sudo aa-enforce /etc/apparmor.d/usr.bin.man
# 정책을 위반했으나 차단은 안하고 로그만 남김
sudo aa-complain /etc/apparmor.d/usr.bin.man
# 정책 적용 안 함
sudo aa-disable /etc/apparmor.d/usr.bin.man
모드 설명
enforce 정책을 강제 적용함 (위반 시 차단)
complain 위반해도 차단 안 하고 로그만 남김
disable 정책 적용 안 함

3. 적용 대상 프로세스

모든 프로세스에 정책을 적용하면 시스템 사용에 불편이 생길 수 있으므로, 중요한 서비스에 우선적으로 적용하는 것이 좋다.

대상 이유
apache2/nginx (웹서버) 파일 업로드나 웹쉘 같은 공격이 들어와도, 웹서버가 접근할 수 있는 파일/디렉토리만 제한해두면, 공격자가 서버 내부 전체를 뒤지지 못하게 막을 수 있음
mysqld (MySQL DB) 루트 권한 없이도 DB 프로세스를 통해 민감한 데이터 추출을 시도할 수 있으므로 AppArmor로 DB가 접근 가능한 경로를 제한하면, 예를 들어 백업 파일 유출이나 비정상 파일 접근을 차단할 수 있음
sshd (원격 접속 데몬) ssh는 루트 권한과 연결된 핵심 통로로, 해커가 로그인에 성공하거나 ssh 취약점이 생기면 바로 시스템 뚫릴 수 있다. AppArmor로 sshd가 실행할 수 있는 범위를 제한하면, 루트쉘 획득 후에도 추가 행동을 제한할 수 있음
cron/at (예약 실행 서비스) 해커가 백도어나 자동 실행 스크립트를 심기 위해 cron을 악용하는 경우가 많음. AppArmor로 cron이 실행 가능한 스크립트 경로나 바이너리를 제한하면, 이상한 명령어가 자동 실행되는 걸 막을 수 있음
docker (컨테이너 엔진) 컨테이너가 호스트 시스템까지 침투하는 경우가 있어, AppArmor로 컨테이너마다 프로파일을 따로 적용하면, 호스트 파일 시스템이나 프로세스를 보호할 수 있음.
cupsd (프린터 데몬) 기업 환경에서는 네트워크 프린터가 내부 시스템 권한과 연결되어 공격 루트가 되기도 함. AppArmor로 이상한 프린터 접근이나 공유 파일 읽기 제한 가능.
bash / python / perl (스크립트 인터프리터) 해커들이 웹쉘이나 루트쉘로 들어올 때, 주로 bash나 python을 실행함. 여기에 AppArmor를 적용하면 쉘 획득 후에도 특정 경로나 명령 실행을 막을 수 있음

 

4. 실습 1 : 간단한 정책 만들어보기

  1. sudo aa-status로 현재 상태 확인
  2. /etc/apparmor.d/ 에 정책 파일 작성
  3. deny 룰로 제한 추가
  4. sudo apparmor_parser 으로 정책 반영
  5. sudo aa-enforce 로 강제 적용
  6. dmesg 나 /var/log/syslog 에서 차단 로그 확인
  7. 필요 시 aa-complain 으로 모드 전환

4-1. sudo aa-status로 현재 상태 확인

sudo aa-status

AppArmor가 지금 어떤 상태인지 출력하는 명령어로, 다음의 사항들을 확인할 수 있다.

  • AppArmor가 켜져 있는지
  • 몇 개의 프로세스에 정책을 적용 중인지
  • 적용된 정책과 모드 (enforce/complain)

4-2. /etc/apparmor.d/ 에 정책 파일 작성

sudo nano /etc/apparmor.d/usr.bin.man
#include <tunables/global>

profile /usr/bin/man {
  /usr/bin/man r,
  /etc/hostname r,
  deny /etc/shadow r,
}

AppArmor 가 이 프로그램은 어디까지 허용해줄지 정의하는 정책 파일을 작성하는 부분이다.
보통은 /etc/apparmor.d/ 경로에 저장하여 자동으로 실행되게끔 한다.

4-3. deny 룰로 제한 추가

deny /etc/shadow r,

AppArmor은 어디까지 허용할지를 중심으로 정책을 작성하게 되지만, 명시적으로 deny를 앞에 적을 경우, 절대 이건 하지 말라는 강한 의미의 설정이 된다. 예를 들어 위의 코드는 /etc/shadow을 절대 읽지 못하게 명시적으로 막아버린단 의미가 된다,

4-4. sudo apparmor_parser 으로 정책 반영

sudo apparmor_parser -r /etc/apparmor.d/usr.bin.man

정책 파일을 작성한 후에는 해당 정책을 커널에 로드하여야 실제로 적용된다. 이를 위해 apparmor_parser 명령어를 사용한다.

4-5. sudo aa-enforce 로 강제 적용

sudo aa-enforce /etc/apparmor.d/usr.bin.man

정책 파일은 작성한 것만으로는 적용되지 않으며, 커널에 반영되도록 명령어를 통해 로드해야 한다. 이를 위해 apparmor_parser 명령어를 사용한다.

 

4-6. dmesg 나 /var/log/syslog 에서 차단 로그 확인

/usr/bin/man의 정책을 실행해서 AppArmor가 진짜 차단했는지 확인하는 단계이다.

# 정책 위반을 위해 실행 시도
man ls
# 만약 오류가 나거나, 내부적으로 shadow 접근이 있었을 경우 확인
# AppArmor DENIED 메시지가 실제로 찍히면 정책이 적용돼서 차단되었다는 뜻임
dmesg | grep DENIED
sudo journalctl | grep apparmor

4-7. 필요 시 aa-complain 으로 모드 전환

sudo aa-comlplain /etc/apparmor.d/usr.bin.man

enforce 모드가 부담될 경우 일단 로그만 남기는 모드로 바꿀 수 있다. complain 모드는 enforce모드와 달리 정책 위반 시 차단하지 않고, 로그만 출력한다.

5. 마무리

AppArmor는 모든 걸 완벽하게 막아주는 방패는 아니지만, 기초적인 보호막이 되어줄 수 있다. 웹서버나 DB처럼 외부에 노출되는 주요 서비스부터 하나씩 적용해보는 것만으로도 실질적인 보안 효과를 얻을 수 있다고 생각한다.

+ Recent posts