
서비스 · 프로세스 관리 42 / 50 · Part 5. 보안과 SOC
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (systemd로 부팅한 Docker 격리 컨테이너, 테스트 계정analyst)
41편의 판단 기준표는 "무엇이 이상해 보이는가"를 묻는다. 그런데 관제에서 더 강력한 질문은 "어제와 무엇이 달라졌는가" 다. 정상 상태를 미리 알고 있으면, 수백 개의 프로세스와 포트 중에서 새로 생긴 몇 줄만 보면 된다.
이번 글에서는 프로세스·대기 포트·활성 unit의 기준선(baseline) 을 파일로 만들고 해시로 보호한 뒤, 새 서비스와 포트를 추가해 diff로 찾아낸다. 그리고 기준선 방식이 잘 잡는 것과 놓치는 것 을 실측 결과로 정리한다.
| 항목 | 내용 |
|---|---|
| 정의 | 정상 운영 상태에서 수집한 시스템 상태의 스냅숏 |
| 목적 | 이후 상태와 비교해 변화 를 찾는다 |
| 전제 | 수집 시점이 정상이어야 한다 (침해 후 수집한 기준선은 무의미) |
| 보호 | 기준선 파일이 바뀌면 비교가 무의미 → 해시 저장, 가능하면 서버 밖 보관 |
| 갱신 | 승인된 변경(배포·설치) 후 다시 수집하고 변경 기록을 남긴다 |
| 원칙 | 이유 |
|---|---|
| 변하지 않는 속성만 저장 | PID·시각·CPU 사용률은 매번 달라 diff가 잡음으로 가득 찬다 |
| 정렬·중복 제거 | 순서 차이로 인한 오탐 방지 (sort -u) |
| 같은 명령으로 재수집 | 비교는 동일한 명령의 결과끼리 |
| 여러 관점으로 | 프로세스·포트·unit·예약 작업(45편)·unit 파일(46편) |

[평소] ps -eo user=,comm= | sort -u > procs.txt
ss -tlnH | awk '{print $4}' | sort -u > listen.txt
systemctl list-unit-files --state=enabled ... | sort > enabled.txt
sha256sum *.txt > SHA256SUMS
[점검] sha256sum -c SHA256SUMS ← 기준선 파일이 변조되지 않았는가
diff <(같은 명령) 기준선 | grep '^<' ← '<' = 지금만 있는 항목(새로 생김)
diff A B에서 <는 A에만, >는 B에만 있는 줄이다. 현재 결과를 A 자리에 두면 <가 새로 생긴 항목, >가 사라진 항목 이 된다. 사라진 항목(예: 보안 에이전트 프로세스)도 중요한 신호다.
# 1) (root) 기준선 수집과 보호
mkdir -p /var/lib/soc-baseline && cd /var/lib/soc-baseline
ps -eo user=,comm= | sort -u > procs.txt
ss -tlnH | awk '{print $4}' | sort -u > listen.txt
systemctl list-unit-files --state=enabled --no-legend --no-pager | awk '{print $1}' | sort > enabled.txt
sha256sum procs.txt listen.txt enabled.txt > SHA256SUMS
# 2) 변화 발생: (analyst) 수동 웹 서버, (root) 새 서비스 enable
cd /tmp; nohup python3 -m http.server 9090 --bind 127.0.0.1 > /dev/null 2>&1 &
printf '[Unit]\nDescription=Lab report sync\n[Service]\nExecStart=/bin/sleep infinity\n[Install]\nWantedBy=multi-user.target\n' > /etc/systemd/system/lab-report.service
systemctl daemon-reload; systemctl enable --now lab-report
# 3) 비교
sha256sum -c SHA256SUMS --quiet && echo "기준선 파일 무결성 OK"
diff <(ps -eo user=,comm= | sort -u) procs.txt | grep '^<'
diff <(ss -tlnH | awk '{print $4}' | sort -u) listen.txt | grep '^<'
diff <(systemctl list-unit-files --state=enabled --no-legend --no-pager | awk '{print $1}' | sort) enabled.txt | grep '^<'
ss -tlnpH 'sport = :9090'
실습 서버에는
diff가 기본 설치되어 있지 않아diffutils패키지를 추가했다. 최소 설치 서버에서는 점검 도구의 존재부터 확인해야 한다.



텍스트 원본(실제 출력):
[root@rocky9-lab ~]# mkdir -p /var/lib/soc-baseline && cd /var/lib/soc-baseline
[root@rocky9-lab soc-baseline]# ps -eo user=,comm= | sort -u > procs.txt
[root@rocky9-lab soc-baseline]# ss -tlnH | awk '{print $4}' | sort -u > listen.txt
[root@rocky9-lab soc-baseline]# systemctl list-unit-files --state=enabled --no-legend --no-pager | awk '{print $1}' | sort > enabled.txt
[root@rocky9-lab soc-baseline]# sha256sum procs.txt listen.txt enabled.txt > SHA256SUMS; wc -l procs.txt listen.txt enabled.txt; cat listen.txt
17 procs.txt
2 listen.txt
12 enabled.txt
31 total
0.0.0.0:22
127.0.0.1:8082
[analyst@rocky9-lab ~]$ cd /tmp; nohup python3 -m http.server 9090 --bind 127.0.0.1 > /dev/null 2>&1 &
[analyst@rocky9-lab tmp]$ sleep 1; ss -tlnH 'sport = :9090' | wc -l
1
[root@rocky9-lab ~]# printf '[Unit]\nDescription=Lab report sync\n[Service]\nExecStart=/bin/sleep infinity\n[Install]\nWantedBy=multi-user.target\n' > /etc/systemd/system/lab-report.service; systemctl daemon-reload; systemctl enable --now lab-report -q
[root@rocky9-lab ~]# cd /var/lib/soc-baseline; sha256sum -c SHA256SUMS --quiet && echo "기준선 파일 무결성 OK"
기준선 파일 무결성 OK
[root@rocky9-lab soc-baseline]# diff <(ps -eo user=,comm= | sort -u) procs.txt | grep '^<'
< root diff
< root grep
< root sleep
[root@rocky9-lab soc-baseline]# diff <(ss -tlnH | awk '{print $4}' | sort -u) listen.txt | grep '^<'
< 127.0.0.1:9090
[root@rocky9-lab soc-baseline]# diff <(systemctl list-unit-files --state=enabled --no-legend --no-pager | awk '{print $1}' | sort) enabled.txt | grep '^<'
< lab-report.service
[root@rocky9-lab soc-baseline]# ss -tlnpH 'sport = :9090'
LISTEN 0 5 127.0.0.1:9090 0.0.0.0:* users:(("python3",pid=1183,fd=3))
| 관찰 | 의미 |
|---|---|
기준선 17 / 2 / 12줄, 포트 0.0.0.0:22, 127.0.0.1:8082 | 이 서버의 정상 상태: SSH와 labapp 두 포트만 대기 |
기준선 파일 무결성 OK | 비교하기 전에 기준선 자체를 먼저 검증했다 |
포트 diff < 127.0.0.1:9090 | 새로 열린 포트를 정확히 한 줄로 찾았다 |
unit diff < lab-report.service | 새로 enable된 서비스를 찾았다 |
프로세스 diff < root diff, root grep, root sleep | diff·grep은 점검 명령 자신, sleep은 lab-report 서비스의 프로세스다. 프로세스 기준선은 잡음이 많다 |
| analyst의 python 웹 서버는 프로세스 diff에 없음 | 기준선에 이미 analyst python3(labapp)가 있어 같은 이름의 새 인스턴스를 구분하지 못했다 |
ss -p → python3 pid=1183 | 포트 기준선이 잡은 항목을 프로세스로 연결해 확인했다 |
하나의 기준선만으로는 부족하다는 것을 실측이 보여 준다. 프로세스 이름은 놓치고, 포트는 잡았다. 여러 관점의 기준선을 함께 쓰는 이유다.
| 주제 | 내용 |
|---|---|
| 알려지지 않은 위협 | 시그니처(알려진 악성 이름·해시)는 새로운 도구를 못 잡지만, 기준선은 "처음 보는 것" 자체를 잡는다 |
| 기준선 보호 | 서버 안의 기준선은 root 권한 공격자가 함께 수정할 수 있다. 해시와 사본을 서버 밖(관제 시스템) 에 둔다 |
| 사라진 항목 | >(기준선에만 있음)도 확인한다. 보안 에이전트·로그 전송기가 사라졌다면 방어 회피 신호다 |
| 갱신 관리 | 변경 후 기준선을 갱신하지 않으면 경보가 계속 울려 경보 피로 가 생기고, 무분별하게 갱신하면 이상을 흡수해 버린다. 갱신은 변경 승인과 연결한다 |
[구축] 서버 투입 · 정기 배포 완료 시점에 기준선 수집 → 해시 → 관제 시스템에 사본 저장
↓
[운영] 하루 1회(또는 cron/timer) 재수집 → diff → 새 항목만 티켓으로
↓
[분류] 새 항목 ∩ 변경 관리 기록 → 승인된 변경이면 기준선 갱신
승인 기록 없음 → 41편 기준으로 확인 → 43편 증거 수집
↓
[지표] 서버별 "일일 신규 항목 수" 추이 — 갑자기 늘면 우선 점검
| 기준선 항목 | 권장 수집 명령 |
|---|---|
| 대기 포트 + 프로그램 | ss -tlnpH \| awk '{print $4, $6}' (PID 제거 후 정렬) |
| 실행 파일 경로 | ls -l /proc/*/exe 2>/dev/null \| awk '{print $NF}' \| sort -u |
| 활성 unit / timer | systemctl list-unit-files --state=enabled, list-timers --all |
| 예약 작업 파일 해시 | 45편 |
| unit 파일·drop-in 해시 | 46편 |
| 실수 | 결과 | 예방 |
|---|---|---|
| PID·시각 포함한 결과를 기준선으로 | 매번 전부 다름 | 불변 속성만 저장 |
| 침해 이후에 기준선 수집 | 악성 항목이 "정상"으로 고정 | 설치 직후·검증된 시점 |
| 기준선을 서버에만 보관 | 함께 변조 가능 | 해시·사본 외부 보관 |
| 프로세스 이름만 비교 | 같은 이름 새 인스턴스 누락 (실측) | exe 경로·포트·unit 병행 |
| 점검 명령 자신을 제외하지 않음 | 매번 같은 잡음 | 점검 도구 이름 제외 필터 |
[ ] 프로세스·대기 포트·활성 unit 기준선을 수집했다
[ ] sha256sum 으로 기준선 파일을 보호하고 검증했다
[ ] diff 의 < 와 > 의미를 설명할 수 있다
[ ] 새 포트와 새 enabled unit 을 diff 로 찾았다
[ ] 프로세스 이름 기준선이 같은 이름의 새 인스턴스를 놓친 것을 확인했다
[ ] 기준선 갱신을 변경 관리와 연결하는 이유를 설명할 수 있다
다음 글 「43. /proc 기반 휘발성 증거 수집 절차」 에서는 확인이 필요한 프로세스를 조치하기 전에 무엇을, 어떤 순서로, 어떻게 보존할지 를 스크립트로 만든다. 실행 파일이 삭제된 테스트 프로세스에서 exe·환경변수·메모리 매핑·fd를 수집하고 해시로 무결성을 확인한다.