시스템 보안 · 취약점 › A. Linux 서버 보안 설정 · 25/50편 (전체 025/450)
학습 단계: 2단계 · 설정 및 점검
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
패키지 관리자는 설치 시점의 각 파일 정보(크기, 해시, 권한, 소유자, 수정 시각)를 데이터베이스에 저장합니다. 검증 명령은 현재 파일과 이 기록을 비교합니다.
rpm -Va 출력: S.5....T. c /etc/ssh/sshd_config
│ │ │ │
│ │ │ └ c = 설정 파일(config) → 변경이 흔함
│ │ └ T = 수정 시각(mTime) 다름
│ └ 5 = 해시(digest) 다름
└ S = 크기(Size) 다름
전체 코드: S(크기) M(권한/타입) 5(해시) D(장치) L(링크) U(소유자) G(그룹) T(시각) P(capabilities)
'.' = 일치, '?' = 확인 불가
설정 파일(c)의 변경은 대부분 정상 운영 결과지만, /usr/bin, /usr/sbin, /usr/lib 아래 실행 파일·라이브러리의 해시 변경은 매우 드물어 변조 신호가 됩니다.
ps, ss, ls, sshd 같은 시스템 바이너리를 교체해 자신을 숨기거나 인증을 우회하는 경우가 있습니다.| 명령 | 용도 |
|---|---|
rpm -Va | 전체 패키지 검증 (Rocky) |
rpm -Vf /usr/bin/ps | 특정 파일이 속한 패키지만 검증 |
rpm -qf --dump 파일 / rpm -qlv 패키지 | DB에 기록된 파일 정보 |
debsums -s / debsums -c | 변경 파일만 출력 (Ubuntu, debsums 패키지) |
dpkg --verify 패키지 | dpkg 내장 검증(출력 형식은 rpm과 유사) |
rpm -K 패키지.rpm | 패키지 파일 서명 확인 |
# Rocky: 설정 파일 제외, 바이너리·라이브러리 변경만 보기
sudo rpm -Va 2>/dev/null | awk '$2!="c"' | grep -E ' /(usr/)?(s?bin|lib|lib64)/'
# 특정 바이너리 집중 확인
for f in /usr/bin/ps /usr/bin/ss /usr/bin/ls /usr/sbin/sshd /usr/bin/sudo; do
echo "== $f"; rpm -Vf "$f" | grep -F "$f"
done
# Ubuntu
sudo apt install -y debsums
sudo debsums -s 2>&1 | head # 변경된 파일만
sudo dpkg --verify openssh-server
rpm -Va는 전체 파일을 읽어 수 분이 걸리고 디스크 부하가 있으므로 운영 서버에서는 업무 외 시간 또는 대상 한정으로 실행합니다.
$ sudo rpm -Va 2>/dev/null | head
S.5....T. c /etc/ssh/sshd_config
.M....... c /etc/sudoers
S.5....T. c /etc/httpd/conf/httpd.conf
$ for f in /usr/bin/ps ...; do ... done
== /usr/bin/ps
== /usr/bin/ss
출력이 설정 파일(c) 위주이고 변경관리 기록으로 설명되며, 시스템 바이너리는 출력이 없는(=일치) 상태가 정상입니다.
$ sudo rpm -Va 2>/dev/null | awk '$2!="c"' | grep -E ' /(usr/)?(s?bin|lib|lib64)/'
S.5....T. /usr/bin/ps
S.5....T. /usr/bin/ss
..5....T. /usr/lib64/libkeyutils.so.1.6.3
$ stat -c '%y %n' /usr/bin/ps
2026-10-01 02:52:11.000000000 +0900 /usr/bin/ps
ps, ss) 동시 변조 → 특정 프로세스·포트를 숨기기 위한 교체 패턴ps·ss의 출력은 신뢰할 수 없으므로, 이후 분석은 /proc 직접 조회나 신뢰할 수 있는 정적 바이너리로 진행합니다.바이너리 교체 흔적을 audit 로그로 추적합니다(가상의 예시 로그).
type=SYSCALL msg=audit(1759731131.002:2101): arch=c000003e syscall=82 success=yes auid=1002 uid=0 comm="mv" exe="/usr/bin/mv" key="bin_change"
type=PATH msg=audit(1759731131.002:2101): item=2 name="/tmp/.x/ps" inode=262801 nametype=DELETE
type=PATH msg=audit(1759731131.002:2101): item=3 name="/usr/bin/ps" inode=262801 nametype=CREATE
| 필드 | 해석 |
|---|---|
syscall=82 | rename(이동) |
/tmp/.x/ps → /usr/bin/ps | 임시 경로의 파일로 시스템 바이너리 교체 |
같은 inode=262801 | 동일 파일이 이름만 바뀜(이동) |
auid=1002 | 교체를 수행한 로그인 사용자 |
rpm -Va의 결과(무엇이)와 audit의 기록(누가·언제·어디서 가져왔나)을 묶어야 사고 보고서를 쓸 수 있습니다.
/usr/bin, /usr/sbin, /usr/lib*)의 변경은 패키지 업데이트 외에는 거의 없으므로, 패키지 로그와 시간이 맞지 않으면 즉시 확인합니다.ps, ss, netstat, ls, find, lsof, sshd, sudo는 우선 검증 목록으로 둡니다.rpm -Va/debsums 결과를 SIEM에 적재해 이전 결과와 비교합니다.# auditd: 시스템 바이너리 디렉터리 쓰기 감시
-w /usr/bin/ -p wa -k bin_change
-w /usr/sbin/ -p wa -k bin_change
<!-- Wazuh FIM 기본 감시 경로(/bin, /sbin, /usr/bin, /usr/sbin)의 변경을 상향 -->
<rule id="100310" level="12">
<if_sid>550</if_sid>
<field name="file">^/usr/bin/ps$|^/usr/bin/ss$|^/usr/bin/ls$|^/usr/sbin/sshd$|^/usr/bin/sudo$</field>
<description>핵심 시스템 바이너리 해시 변경: $(file)</description>
</rule>
패키지 업데이트 직후에는 같은 변경이 대량으로 발생하므로 dnf/apt 실행 시각과 비교해 정탐 여부를 판단합니다(048편).
rpm -Va 전체 출력을 보존합니다(변조 도구 출력은 신뢰 금지).dnf reinstall, apt install --reinstall) 또는 서버 재구축을 결정합니다.| 구분 | 핵심 내용 |
|---|---|
| 출력 코드 | S 크기 · M 권한 · 5 해시 · U/G 소유 · T 시각 · c 설정파일 |
| 정상 패턴 | c(설정 파일) 변경 + 변경관리 기록 |
| 위험 패턴 | /usr/bin/ps·ss 등 바이너리 해시 변경 |
| 한계 | 패키지 DB도 변조 가능 → 외부 기준·오프라인 분석 |
| 면접 포인트 | "변조된 ps의 출력은 증거로 쓰지 않는다 → /proc 직접 확인" |
다음 편 026. Linux 서버 보안 — cron·at 접근 제어 점검 에서는 예약 작업 기능의 오남용을 막는 cron·at 접근 제어를 점검합니다.
이전 편: 024. Linux 서버 보안 — 보안 패치·업데이트 상태 점검
📚 시리즈 전체 보기: 시스템 보안 · 취약점