시스템 보안 · 취약점 › A. Linux 서버 보안 설정 · 2/50편 (전체 002/450)
학습 단계: 1단계 · 기본 개념
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
기준선(Baseline) 은 "이 서버의 정상 상태는 이것이다"라고 합의해 둔 스냅샷입니다. 계정 목록, 활성 서비스, 리스닝 포트, 중요 설정 파일의 해시, 커널 파라미터 등을 같은 형식으로 반복 수집해 두면 이후 상태와 비교(diff)할 수 있습니다.
[ 최초 점검 ] → [ 검토·승인 ] → [ 기준선 저장(읽기 전용 + 해시) ]
↓
[ 정기 재수집 ] ──────── diff ────────→ [ 차이 발생 ]
↓
변경관리 티켓 있음? ── 예 → 기준선 갱신
└─ 아니오 → 이상 징후로 분석
| 수집 항목 | 명령어 | 비교 시 주의 |
|---|---|---|
| 계정 | getent passwd | cut -d: -f1,3,7 | 서비스 계정 추가는 패키지 설치와 연결 |
| 활성 유닛 | systemctl list-unit-files --state=enabled --no-legend | 업데이트 후 이름 변경 가능 |
| 리스닝 포트 | ss -tulpnH | awk '{print $1,$5}' | 임시 포트(ephemeral) 제외 |
| 설정 해시 | sha256sum /etc/ssh/sshd_config /etc/sudoers | 정상 변경 시 갱신 |
| 커널 파라미터 | sysctl -a 2>/dev/null | sort | 값이 자주 변하는 항목 제외 |
# 기준선 수집 (날짜별 디렉터리)
D=/root/baseline/$(date +%F)
sudo install -d -m 700 "$D"
sudo sh -c "getent passwd | cut -d: -f1,3,7 | sort > $D/accounts.txt"
sudo sh -c "systemctl list-unit-files --state=enabled --no-legend | awk '{print \$1}' | sort > $D/units.txt"
sudo sh -c "ss -tulpnH | awk '{print \$1, \$5}' | sort -u > $D/listen.txt"
sudo sh -c "sha256sum /etc/passwd /etc/group /etc/sudoers /etc/ssh/sshd_config > $D/conf.sha256"
# 기준선 자체의 무결성 기록
sudo sh -c "cd $D && sha256sum *.txt conf.sha256 > MANIFEST.sha256 && chmod 400 *"
# 일주일 뒤 재수집한 결과와 비교
sudo diff /root/baseline/2026-10-01/listen.txt /root/baseline/2026-10-08/listen.txt
$ sudo diff 2026-10-01/listen.txt 2026-10-08/listen.txt
$ echo $?
0
$ sudo sha256sum -c 2026-10-01/conf.sha256
/etc/passwd: OK
/etc/group: OK
/etc/sudoers: OK
/etc/ssh/sshd_config: OK
차이가 없거나, 차이가 있더라도 변경관리 티켓으로 설명 가능한 상태가 정상입니다.
$ sudo diff 2026-10-01/listen.txt 2026-10-08/listen.txt
> tcp 0.0.0.0:8081
$ sudo sha256sum -c 2026-10-01/conf.sha256
/etc/passwd: FAILED
/etc/ssh/sshd_config: FAILED
8081 리스너가 추가됨 → 비인가 서비스 가능성/etc/passwd와 sshd_config가 같은 기간에 변경됨 → 계정 추가 + 접속 정책 완화를 함께 의심MANIFEST.sha256 검증이 실패하면 기준선 자체가 변조된 것이므로 서버 외부 사본으로 비교해야 합니다.기준선 diff는 "무엇이 바뀌었는지"만 알려줍니다. "누가 언제" 바꿨는지는 로그로 확인합니다(가상의 예시 로그).
type=SYSCALL msg=audit(1759712400.112:812): arch=c000003e syscall=257 success=yes exit=3 ppid=2420 pid=2433 auid=1001 uid=0 comm="vi" exe="/usr/bin/vi" key="sshd_config"
type=PATH msg=audit(1759712400.112:812): item=0 name="/etc/ssh/sshd_config" inode=67144821 nametype=NORMAL
| 필드 | 의미 |
|---|---|
auid=1001 | 최초 로그인 사용자(sudo 후에도 유지) |
uid=0 | 실행 시점 권한(root) |
comm/exe | 수정에 사용된 프로그램 |
key | auditd 규칙에 붙인 태그 |
audit(1759712400.112:812)의 앞부분은 Unix epoch 시간이며 ausearch -i로 사람이 읽는 시간으로 변환됩니다.
Wazuh의 command 모니터링으로 리스닝 포트 목록을 주기적으로 수집하고, 출력이 바뀌면 Alert를 받을 수 있습니다.
<!-- agent ossec.conf (예시): 6분마다 리스닝 포트 수집 -->
<localfile>
<log_format>full_command</log_format>
<command>ss -tulpnH | awk '{print $1, $5}' | sort -u</command>
<alias>listen-baseline</alias>
<frequency>360</frequency>
</localfile>
Wazuh 기본 룰셋의 533(netstat listening ports changed)은 같은 원리로 netstat 출력 변화를 탐지합니다. 명령 출력 비교 룰은 출력 형식이 동일해야 하므로 정렬(sort)·필드 고정이 중요합니다.
| 구분 | 핵심 내용 |
|---|---|
| 기준선 | 합의된 정상 상태의 스냅샷 |
| 수집 원칙 | 같은 명령·같은 형식·정렬된 출력 |
| 보호 | 읽기 전용 + MANIFEST 해시 + 외부 사본 |
| 분석 | diff로 "무엇", 로그로 "누가·언제" |
| 면접 포인트 | "정상을 정의해야 비정상을 탐지할 수 있다" |
다음 편 003. Linux 서버 보안 — 사용자·그룹 설정 점검 — UID 0과 빈 패스워드 에서는 기준선의 첫 축인 계정 설정을 점검하며 UID 0 중복과 빈 패스워드 계정을 찾는 방법을 다룹니다.
이전 편: 001. Linux 서버 보안 — 기본 보안 점검 항목과 하드닝 로드맵
📚 시리즈 전체 보기: 시스템 보안 · 취약점