728x90
목표와 범위
- 실시간 위협 가시성: 파일/프로세스/네트워크/사용자 이벤트 수집 및 이상 탐지
- 즉각 대응 자동화: 프로세스 차단, 파일 격리, IP 봉쇄, 알림 발송
- 증거 보존: 포렌식 로그·해시·타임라인 확보
- 운영 편의: 단일 스크립트(또는 소규모 서비스)·시스템 서비스·대시보드/API 제공
- 연동성: SIEM/메시징/티켓 시스템으로 표준 JSON 전송
개념 아키텍처
- 데이터 수집
- 커널 이벤트: eBPF/bpftrace 또는 Auditd
- 파일 변경: inotify/fanotify
- 네트워크: ss/nftables conntrack, 간이 허니팟
- 사용자/권한: sudo/lastlog/wtmp, 그룹 변경
- 탐지 엔진
- 룰 기반(YARA/정규식/화이트리스트) + 행위 기반(빈도·패턴·상태머신)
- 대응(Containment)
- 프로세스 종료/격리, 파일 격리, IP 차단(ipset/nft), 서비스 재기동
- 로깅·저장
- JSON Lines(로컬), 회전/압축, 무결성 해시
- API·대시보드
- 읽기 전용 REST, 요약/검색/다운로드
- 연동
- SIEM 수집기(Filebeat/Vector), Slack/Webhook, 티켓 시스템
- 운영 제어
- 설정파일(.conf), allow/deny 목록, 모듈 on/off, 성능 튜닝
기술 스택 선택 가이드
- 필수: Bash 4+, jq, inotify-tools, coreutils, openssl
- 선택: bcc/bpftrace(커널≥4.9 권장), yara, python3(경량 API), nftables/ipset
- 대안: 커널 제약 시 Auditd 중심 설계 → 행위 탐지는 범위 축소, 파일·프로세스 상관분석 강화
300x250
디렉터리 구조(예시)
/opt/hostsec/
├─ bin/ # 실행 스크립트
├─ rules/ # yara / regex / 정책
├─ conf/ # 설정(환경, 허용목록, 성능튜닝)
├─ quarantine/ # 격리 파일(해시, 메타)
├─ logs/ # jsonl, rotate 대상
├─ tmp/
└─ api/ # (선택) 간이 REST
설정 파일 예시(conf/agent.conf)
MONITOR_NETWORK=true
MONITOR_PROCESSES=true
MONITOR_FILES=true
ENABLE_EBPF=true ; 또는 ENABLE_AUDITD=true
ENABLE_YARA=true
ENABLE_HONEYPOT=true
API_ENABLE=true
API_BIND=127.0.0.1
API_PORT=8080
LOG_DIR=/opt/hostsec/logs
QUARANTINE_DIR=/opt/hostsec/quarantine
EXCLUDE_PATHS=("/var/lib/docker" "/snap")
WHITELIST_PROCESSES=("sshd" "systemd" "dockerd")
HONEYPOT_PORTS=("2222" "8080" "23")
WEBHOOK_URL=""
SIEM_SHIP=udp://log-collector.local:514
PERFORMANCE_MODE=false
PARALLEL_JOBS=2
MAX_FIND_DEPTH=3
SCAN_TIMEOUT=180
최소 동작 MVP 스크립트 조각
1) 공통 로거/알림
log() { printf '%s %s\n' "$(date -Is)" "$*" >> "$LOG_DIR/agent.log"; }
alert() { # ALERT JSON 한 줄 출력
jq -nc --arg sev "$1" --arg msg "$2" --arg host "$(hostname)" '
{ts: now|todateiso8601, host:$host, severity:$sev, message:$msg}' \
| tee -a "$LOG_DIR/alerts.jsonl"
}
notify_webhook() {
[ -z "$WEBHOOK_URL" ] && return 0
curl -s -X POST -H 'Content-Type: application/json' \
--data @- "$WEBHOOK_URL" <<<'{"text":"['"$(hostname)"'] '"$1"'"}' >/dev/null
}
2) 파일 변경 감시 + YARA 스캔(간이)
watch_and_scan() {
local WATCH_DIR="/var/www/html"
inotifywait -m -e create,modify --format '%w%f' "$WATCH_DIR" \
| while read -r f; do
[[ "$f" =~ \.php$|\.jsp$|\.sh$ ]] || continue
yara -r rules/webshell.yar "$f" >/tmp/yara.out 2>/dev/null
if [ ${PIPESTATUS[0]} -eq 0 ]; then
alert "high" "YARA hit on $f"
quarantine_file "$f"
notify_webhook "YARA hit on $f (quarantined)"
fi
done
}
3) 격리/차단
quarantine_file() {
local f="$1" base sha dst
base="$(basename "$f")"
sha="$(sha256sum "$f" | awk '{print $1}')"
dst="$QUARANTINE_DIR/$base.$sha"
mkdir -p "$QUARANTINE_DIR"
mv -f "$f" "$dst"
printf '%s\t%s\t%s\n' "$(date -Is)" "$f" "$sha" >> "$QUARANTINE_DIR/index.tsv"
}
block_ip_nft() { # nftables 사전 준비: set 생성
local ip="$1"
nft add element inet filter bad_ips { $ip } 2>/dev/null \
&& alert "medium" "Blocked $ip via nft set"
}
4) 프로세스/실행 추적(eBPF → 대안 Auditd)
- eBPF(bpftrace) 예 (커널≥4.9, root):
bpftrace -e 'tracepoint:sched:sched_process_exec { printf("%s|%d|%s\n", comm, pid, args->filename); }' \
| awk -F'|' '{print strftime("%FT%TZ"),$1,$2,$3}' \
>> "$LOG_DIR/exec_events.log"
- Auditd 대안:
-w /usr/bin -p x -k execmon
규칙 + ausearch/auparse로 후처리
5) 간이 허니팟(파이썬, 2222/TCP)
# /opt/hostsec/bin/honeypot.py
import socket, json, time
HOST, PORT = "0.0.0.0", 2222
with socket.socket() as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT)); s.listen(50)
while True:
c, a = s.accept()
with c:
c.sendall(b"SSH-2.0-OpenSSH_8.2p1\r\n")
payload = c.recv(128, socket.MSG_DONTWAIT).decode("utf-8","ignore")
evt = {"ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"src": a[0], "dst_port": PORT, "banner":"ssh-like", "data": payload}
with open("/opt/hostsec/logs/honeypot.jsonl","a") as f: f.write(json.dumps(evt)+"\n")
6) 경량 REST API(읽기 전용)
# /opt/hostsec/api/app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.get("/alerts")
def alerts():
return jsonify([line for line in open("/opt/hostsec/logs/alerts.jsonl")][-200:])
룰 설계와 오탐( FP ) 관리
- 레이어 설계
- 파일 패턴(YARA) → 프로세스/네트워크 행위 → 상관분석(시간·경로·UID)
- 화이트리스트 우선
- 프로세스명, 경로, 서명/해시, 내부 IP/도메인
- 버저닝·리뷰
rules/
디렉터리 Git 관리(리뷰+테스트), 변경시 파일럿 5% → 점진 확대
- 측정지표
- FP율, 규칙 커버리지(자산군/업무군), 룰 업데이트 성공률
YARA 예시(단순 패턴)
rule Php_Webshell_Eval_Base64 {
meta: severity = "high"
strings: $a = /eval\s*\(\s*base64_decode\s*\(/ nocase
condition: 1 of ($a)
}
위협 인텔(TI)·IP 차단 자동화(개념)
- 시간별(예: 6h) 공개 TI 피드 받아 CSV/IP 목록 갱신
ipset/nft set
에 추가 후input
체인에서 참조- 신뢰등급·첫 탐지 시각·만료시각 메타데이터로 자동 만료
nft add set inet filter bad_ips { type ipv4_addr; timeout 1d; }
nft add rule inet filter input ip saddr @bad_ips drop
# 갱신 스크립트에서: nft add element inet filter bad_ips { 198.51.100.10 timeout 6h }
대응 자동화 Runbook(요약)
- 심각도 매핑: high(즉시 격리/차단) · medium(감시+승인 후 차단) · low(관찰)
- 즉시 조치
- 파일:
quarantine_file
, 해시/메타 기록 - 프로세스:
kill -9 <pid>
, 서비스 안전 재기동 - 네트워크:
block_ip_nft <ip>
- 파일:
- 사후 처리
- 패치/비밀번호 초기화/키 교체, 로그 타임라인 정리, 재발 방지 룰 보강
- 예외 승인
- Change Ticket 기반 허용(만료시각 포함), 룰·화이트리스트 동기화
보안·신뢰성 설계 포인트
- 최소권한: root 필요한 모듈만 분리 실행, 나머지는 비루트
- Capability/격리:
AmbientCapabilities=
최소화, API는localhost
바인드 + mTLS/토큰 - 서플라이체인: 해시 검증, 내부 미러,
shellcheck
·정적분석, 서명 배포 - 무결성: 로그 JSONL에 체인 해시 추가(이전 라인 해시 포함)
- 설정 보호:
chmod 600 conf/*
, 민감 키 분리(.env.d/)
배포·서비스화
1) systemd 유닛(예시)
# /etc/systemd/system/hostsec.service
[Unit]
Description=Host Security Agent
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/hostsec
ExecStart=/opt/hostsec/bin/agent.sh run
Restart=always
RestartSec=5
# 경량 보호
NoNewPrivileges=true
ProtectSystem=full
PrivateTmp=true
ReadWritePaths=/opt/hostsec /var/log
AmbientCapabilities=CAP_SYS_ADMIN CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target
2) 로그 수집기(Filebeat 예시)
filebeat.inputs:
- type: log
paths:
- /opt/hostsec/logs/alerts.jsonl
- /opt/hostsec/logs/honeypot.jsonl
json.add_error_key: true
processors:
- decode_json_fields:
fields: ["message"]
process_array: true
max_depth: 2
output.logstash:
hosts: ["siem-collector.local:5044"]
관측성·대시보드·지표
- 탐지: alerts.count, high/medium/low, MTTD, 재발율
- 행위: exec 이벤트, 허니팟 히트, 차단 건수
- 품질: FP율, 룰 커버리지, 업데이트 성공률
- 성능: CPU/메모리/로그 증가량, 스캔 소요시간 p90
성능·안정화 팁
- 경로 제외(
EXCLUDE_PATHS
)·깊이 제한(MAX_FIND_DEPTH
)·동시성(PARALLEL_JOBS
) 조정 - 스캔/알림 레이트리밋(초당 N건)·백오프 재시도
- 고부하 시간대(배치/백업)에는 감시 민감도 하향 또는 휴지시간 설정
멀티테넌시·호스팅 환경 운영(서비스 프로바이더용)
- 고객 격리: 계정·그룹·cgroup·네임스페이스·chroot/컨테이너 분리
- 정책 템플릿: 웹/DB/배치/도구서버 등 프로파일별 룰팩
- 감사 체계: 고객 데이터 접근 로그 별도 보관, 대시보드 고객 단위 필터
- 헌팅/수사: 허니팟을 고객망과 분리된 보안 세그먼트에 배치
PoC 체크리스트
- 커널/권한/네트워크 요구조건 충족(eBPF 또는 Auditd)
- 파일·프로세스·네트워크 3대 축 이벤트 수집 정상
- 웹셸·리버스셸·코인마이너 샘플에 대한 탐지≥95%, FP≤2%
- 고부하 시 CPU≤10%, RSS≤80MB, 로그 회전 정상
- 알림→티켓 연계, 롤백/비상중지 스크립트 검증
실무에 바로 쓰는 스니펫 모음
1) 메인 실행기(요약형)
#!/usr/bin/env bash
set -Eeuo pipefail
. conf/agent.conf
init() {
mkdir -p "$LOG_DIR" "$QUARANTINE_DIR"
log "agent start on $(hostname)"
# nft set 사전 준비
nft list set inet filter bad_ips >/dev/null 2>&1 || {
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0; }
nft add set inet filter bad_ips { type ipv4_addr; }
nft add rule inet filter input ip saddr @bad_ips drop
}
}
main() {
init
$MONITOR_FILES && watch_and_scan &
$ENABLE_HONEYPOT && /usr/bin/python3 bin/honeypot.py &
$MONITOR_PROCESSES && bpftrace_exec & # 또는 auditd 파서
$API_ENABLE && python3 api/app.py &
wait -n # 한 워커 종료 시 전체 재시작
}
main "$@"
2) exec 이벤트(bpftrace) 워커
bpftrace_exec() {
command -v bpftrace >/dev/null || { log "bpftrace missing"; return; }
bpftrace -e 'tracepoint:sched:sched_process_exec { printf("%s|%d|%s\n", comm, pid, args->filename); }' \
| while IFS='|' read -r comm pid file; do
case "$file" in
*/curl|*/wget) alert "medium" "Net tool exec: $comm($pid) -> $file";;
esac
done >> "$LOG_DIR/exec_events.log"
}
운영 수칙
- 테스트→파일럿(5~10%)→전면 단계적 롤아웃
- 룰 변경은 티켓 필수, 만료일·소유자 지정
- API 외부 노출 금지, 원격 필요 시 mTLS·IP 제한
- 정기 점검: FP 리뷰, 성능 리포트, TI 품질 평가
- 비상절차:
systemctl stop hostsec
+ 차단규칙 롤백 스크립트
마무리
- 위 구조는 작고 단단한 구성으로 시작해 환경에 맞게 확장(ML기반 스코어링, 중앙 정책 서버, 고급 대시보드)하기 좋습니다.
- 핵심은 레이어드 수집→룰·행위 상관분석→신속 대응→증거 보존의 사이클을 자동화하고, FP 관리와 운영지표로 지속 개선하는 것입니다.
- 필요하시면 통합 설치 스크립트, Auditd 전환 설계, 프로메테우스 지표 노출까지 이어지는 확장안도 바로 정리해드리겠습니다.
728x90
그리드형(광고전용)
댓글