시스템 보안 · 취약점 › A. Linux 서버 보안 설정 · 18/50편 (전체 018/450)
학습 단계: 2단계 · 설정 및 점검
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
AppArmor는 Ubuntu 기본 MAC입니다. SELinux가 라벨(타입) 기반이라면 AppArmor는 경로(path) 기반으로 "이 프로그램은 이 경로를 이렇게만 접근할 수 있다"를 프로파일로 정의합니다.
/usr/sbin/tcpdump ──(프로파일: usr.sbin.tcpdump)──→ 허용된 경로만 접근
│
├─ enforce 모드 : 위반 시 차단 + apparmor="DENIED" 로그
├─ complain 모드 : 차단 없이 apparmor="ALLOWED" 로그
└─ unconfined : 프로파일 없음(제한 없음)
| 비교 | SELinux (Rocky) | AppArmor (Ubuntu) |
|---|---|---|
| 기준 | 타입 라벨 | 파일 경로 |
| 전체 해제 | setenforce 0 | systemctl stop apparmor, aa-teardown |
| 로그 | type=AVC | type=1400 apparmor="DENIED" |
DENIED 로그는 프로그램이 평소와 다른 경로에 접근하려 했다는 증거라 침해 탐지에 활용할 수 있습니다.| 명령 | 용도 |
|---|---|
sudo aa-status | 로드된 프로파일, enforce/complain 수, 보호 중 프로세스 |
ls /etc/apparmor.d/ | 프로파일 파일 |
sudo aa-enforce /etc/apparmor.d/프로파일 | enforce 전환(apparmor-utils) |
sudo aa-complain ... | complain 전환 |
sudo journalctl -k | grep apparmor | 커널 로그의 AppArmor 이벤트 |
# Ubuntu 22.04 테스트 VM
sudo aa-status | head -20
sudo aa-status | grep -A3 'complain mode'
# 프로세스별 보호 여부: unconfined 프로세스 중 네트워크 서비스 확인
sudo aa-status | sed -n '/processes are unconfined/,$p'
sudo ss -tlpnH | awk '{print $NF}'
# 로그 확인
sudo journalctl -k --since today | grep -E 'apparmor="(DENIED|STATUS)"' | tail
$ sudo aa-status
apparmor module is loaded.
34 profiles are loaded.
32 profiles are in enforce mode.
/usr/bin/man
/usr/sbin/tcpdump
...
2 profiles are in complain mode.
...
0 profiles are in kill mode.
complain 프로파일이 있다면 의도된 것인지(정책 개발 중 등) 문서로 확인 가능한 상태가 정상입니다. (출력 항목은 AppArmor 버전에 따라 조금씩 다릅니다.)
$ sudo aa-status | grep -A2 'complain mode'
3 profiles are in complain mode.
/usr/sbin/mysqld
/usr/sbin/tcpdump
mysqld, tcpdump가 complain으로 바뀜 → DB 프로세스의 파일 접근 제한 해제AppArmor 이벤트는 커널 감사 메시지(type=1400)로 기록됩니다(가상의 예시 로그).
Oct 1 10:02:11 ubuntu22-app01 kernel: audit: type=1400 audit(1759719731.402:211): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/sbin/mysqld" pid=8120 comm="apparmor_parser"
Oct 1 10:05:40 ubuntu22-app01 kernel: audit: type=1400 audit(1759719940.118:215): apparmor="ALLOWED" operation="open" profile="/usr/sbin/mysqld" name="/etc/shadow" pid=1450 comm="mysqld" requested_mask="r" denied_mask="r" fsuid=113 ouid=0
| 필드 | 의미 |
|---|---|
apparmor="STATUS" + comm="apparmor_parser" | 프로파일 로드·교체(모드 변경 포함) |
apparmor="ALLOWED" | complain 모드라 허용됐지만 정책 위반 |
profile="/usr/sbin/mysqld" name="/etc/shadow" | DB 프로세스가 shadow 파일 접근 → 매우 비정상 |
fsuid=113 | 파일 접근 시 사용한 UID(mysql) |
enforce였다면 DENIED로 막혔을 접근이 complain 전환 후 ALLOWED로 통과한 흐름입니다.
apparmor_parser, aa-complain)과 서비스 중지를 모두 수집합니다.ALLOWED 로그는 "complain이라 막지 못한 위반"이므로 DENIED보다 더 위험할 수 있습니다./etc/shadow, /root, /home에 접근하는 이벤트는 정탐 가능성이 높습니다.<group name="local,apparmor,">
<rule id="100250" level="10">
<match>apparmor="ALLOWED"</match>
<regex>name="/etc/shadow"|name="/root/</regex>
<description>AppArmor complain 상태에서 민감 경로 접근 허용</description>
</rule>
<rule id="100251" level="8">
<match>apparmor="STATUS"</match>
<regex>operation="profile_remove"|operation="profile_replace"</regex>
<description>AppArmor 프로파일 제거/교체</description>
</rule>
</group>
Wazuh 기본 룰셋에도 AppArmor DENIED 관련 룰이 있으므로, 위 룰은 고위험 조건만 상향하는 용도로 사용합니다.
aa-status 결과를 기준선과 비교해 모드가 바뀐 프로파일을 확인합니다.aa-status 출력, 커널 로그, 프로파일 파일 사본을 보존합니다.aa-enforce로 복원하고, 민감 경로 접근이 있었다면 해당 서비스를 격리 조사합니다.| 구분 | 핵심 내용 |
|---|---|
| 방식 | 경로 기반 MAC (프로파일 있는 프로그램만 보호) |
| 모드 | enforce / complain / unconfined |
| 은밀한 약화 | 개별 프로파일만 complain 전환 |
| 로그 | type=1400 apparmor="DENIED / ALLOWED / STATUS" |
| 면접 포인트 | "ALLOWED 로그 = 막지 못한 정책 위반" |
다음 편 019. Linux 서버 보안 — /tmp 보안 — 마운트 옵션 nodev·nosuid·noexec 에서는 공격 도구가 자주 놓이는 /tmp의 마운트 옵션(nodev·nosuid·noexec) 을 점검합니다.
이전 편: 017. Linux 서버 보안 — SELinux 상태 점검과 AVC 거부 분석
📚 시리즈 전체 보기: 시스템 보안 · 취약점