시스템 환경 및 보안 설정
1. 네트워크 인터페이스 구성
내부 네트워크의 포트 스캔 시도를 유도하고 탐지 확률을 높이기 위해 단일 네트워크 인터페이스에 여러 개의 IP 주소를 할당합니다. 예를 들어 eth0 인터페이스에 192.168.10.101, 192.168.10.102, 192.168.10.103, 192.168.10.104 등 4개의 IP를 추가 설정하여 허니팟(Honeypot)과 유사한 환경을 구성합니다.
2. SSH 서비스 강화
모니터링 서버가 역으로 공격당하는 것을 방지하기 위해 SSH 보안을 강화합니다. root 계정 직접 로그인을 차단하고, SSH 키 인증만 허용합니다. 또한, 기본 포트를 변경하여 무차별 대입 공격(Brute-force)을 방어합니다. 여기서는 포트를 22889로 변경하고 키 인증만 활성화합니다.
3. 불필요한 서비스 및 방화벽 비활성화
외부에서 스캔할 수 있는 불필요한 포트를 최소화하기 위해 방화벽과 RPC 관련 서비스를 중단합니다. 오직 SSH 포트만 개방된 상태로 유지하여 서버 탈취 위험을 낮춥니다.
[root@scan-detector ~]# systemctl stop firewalld iptables rpcbind
[root@scan-detector ~]# systemctl disable firewalld iptables rpcbind
[root@scan-detector ~]# ss -tunl | grep '^tcp' | awk '{print $5}' | grep '\*'
*:22889
패킷 캡처 자동화 구성
1. 캡처 파일 디렉터리 생성
패킷 캡처 파일을 저장할 전용 디렉터리를 생성합니다.
[root@scan-detector ~]# mkdir -p /var/log/netcap
2. 부팅 시 자동 캡처 스크립트 등록
tcpdump를 사용하여 대상 IP로 들어오는 TCP SYN 패킷만 캡처하도록 설정합니다. 60초마다 파일을 분할 저장하며, 부팅 시 자동으로 실행되도록 rc.local에 등록합니다.
[root@scan-detector ~]# echo 'nohup tcpdump -i any \(tcp[tcpflags] = tcp-syn\) and dst host \(192.168.10.101 or 192.168.10.102 or 192.168.10.103 or 192.168.10.104\) -s 0 -U -G 60 -w /var/log/netcap/capture_%Y_%m%d_%H%M.pcap &>/dev/null &' >> /etc/rc.d/rc.local
[root@scan-detector ~]# chmod +x /etc/rc.d/rc.local
3. 수동 실행 및 파라미터 설명
시스템 재부팅 없이 즉시 캡처를 시작하기 위해 백그라운드에서 명령어를 실행합니다.
[root@scan-detector ~]# nohup tcpdump -i any \(tcp[tcpflags] = tcp-syn\) and dst host \(192.168.10.101 or 192.168.10.102 or 192.168.10.103 or 192.168.10.104\) -s 0 -U -G 60 -w /var/log/netcap/capture_%Y_%m%d_%H%M.pcap &>/dev/null &
-i any: 루프백(lo)을 제외한 모든 네트워크 인터페이스에서 패킷을 캡처합니다.(tcp[tcpflags] = tcp-syn): TCP 연결 요청을 의미하는 SYN 플래그가 설정된 패킷만 필터링합니다.dst host (...): 할당된 4개의 가상 IP로 향하는 패킷만 대상으로 합니다.-s 0: 패킷의 전체 길이를 캡처합니다 (기본값 68바이트 제한 해제).-U: 패킷을 버퍼링하지 않고 즉시 파일에 기록합니다.-G 60: 60초마다 새로운 캡처 파일을 생성합니다.-w ...: 파일 이름에 시간 포맷 변수를 사용하여 분 단위 파일 분할을 지원합니다.
이상 탐지 및 알림 스크립트 작성
캡처된 패킷 파일을 주기적으로 분석하여 임계치 이상의 스캔 시도를 탐지하고, 관리자에게 이메일로 알림을 전송하는 Bash 스크립트를 작성합니다.
1. 스크립트 디렉터리 생성 및 편집
[root@scan-detector ~]# mkdir -p /usr/local/bin/scandetect
[root@scan-detector ~]# vi /usr/local/bin/scandetect/detect_scan.sh
2. 분석 및 알림 스크립트 코드
#!/bin/bash
# 허용된 IP 목록 (파이프 '|'로 구분)
ALLOWED_IPS="192.168.10.250|10.0.0.50"
# 알림 발생 임계치 (분당 스캔 횟수)
ALERT_THRESHOLD=5
# 캡처 파일 경로 및 타겟 시간 설정 (2분 전 파일 분석)
CAP_DIR="/var/log/netcap"
TARGET_TIME=$(date -d '2 minutes ago' "+%Y_%m%d_%H%M")
CAP_FILE="${CAP_DIR}/capture_${TARGET_TIME}.pcap"
# 캡처 파일이 존재하지 않으면 스크립트 종료
if [[ ! -f "$CAP_FILE" ]]; then
exit 0
fi
# 패킷 분석: 소스 IP 추출, 포트 제거, 화이트리스트 필터링 및 빈도수 집계
tcpdump -r "$CAP_FILE" -nn 2>/dev/null \
| awk '{print $3}' | cut -d'.' -f1-4 \
| grep -Ev "$ALLOWED_IPS" \
| sort | uniq -c | sort -rn \
| while read -r hit_count src_ip; do
# 내림차순 정렬되어 있으므로 임계치 미만이면 반복문 탈출
if (( hit_count < ALERT_THRESHOLD )); then
break
fi
# 이상 징후 포착 시 증거 데이터 추출 (상위 10개 패킷)
evidence=$(tcpdump -r "$CAP_FILE" -nn 2>/dev/null | grep "$src_ip" | head -n 10)
# 이메일 알림 전송 (캡처 파일 첨부)
echo -e "Suspicious port scanning detected from $src_ip ($hit_count hits in 1 min).\n\nLog Evidence:\n$evidence" \
| mailx -r "alert@internal.net" \
-s "[Security Alert] Port Scan Detected: $src_ip" \
-a "$CAP_FILE" \
"admin@internal.net"
done
위 스크립트는 2분 전의 캡처 파일을 분석합니다. 1분 전 파일을 분석하지 않는 이유는 tcpdump의 -G 옵션과 파일 시스템의 쓰기 버퍼링으로 인해 현재 분의 파일이 아직 완전히 닫히지 않았거나 데이터가 누락될 수 있기 때문입니다.
주기적 실행 및 수동 분석
1. 크론(Cron) 작업 등록
스크립트를 매분 실행하도록 crontab에 등록합니다.
[root@scan-detector ~]# crontab -e
* * * * * /bin/bash /usr/local/bin/scandetect/detect_scan.sh
2. 실시간 패킷 모니터링
터미널에서 실시간으로 들어오는 SYN 패킷을 확인하려면 다음 명령어를 사용합니다.
[root@scan-detector ~]# tcpdump -i any \(tcp[tcpflags] = tcp-syn\) and dst host \(192.168.10.101 or 192.168.10.102 or 192.168.10.103 or 192.168.10.104\) -nn
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
14:22:15.110287 IP 192.168.10.88.54321 > 192.168.10.101.22: Flags [S], seq 1889993435, win 14600, options [mss 1460,sackOK,TS val 4251068229 ecr 0,nop,wscale 7], length 0
3. 히스토리 캡처 파일 수동 분석
저장된 과거 캡처 파일들을 순회하며 IP별 접속 빈도를 수동으로 집계할 수 있습니다.
[root@scan-detector ~]# for file in /var/log/netcap/*.pcap; do
echo "=== Analyzing: $file ==="
tcpdump -r "$file" -nn 2>/dev/null | awk '{print $3}' | cut -d'.' -f1-4 | sort | uniq -c | sort -n
done
=== Analyzing: /var/log/netcap/capture_2023_1024_1410.pcap ===
=== Analyzing: /var/log/netcap/capture_2023_1024_1415.pcap ===
2 192.168.10.250
=== Analyzing: /var/log/netcap/capture_2023_1024_1422.pcap ===
45 192.168.10.88