📚 네트워크 · 패킷 분석 › 02. 포트 · 프로토콜 분석 — 78편
이전 글: 77. WinRM · 다음 글: 79. ICMP
참고(리눅스 시스템 기초): 36. 원격 Syslog와 중앙 로그 서버 — 여러 서버의 로그를 한곳에 모을 때 시간 동기화가 전제가 되는 이유
보안관제는 결국 "언제, 어디서, 무엇이" 일어났는지를 여러 장비의 로그로 재구성하는 일입니다. 방화벽 로그, 웹 서버 access log, 리눅스 인증 로그, IDS 이벤트를 하나의 타임라인으로 엮으려면 모든 장비의 시계가 같은 기준을 가리키고 있어야 합니다.
만약 웹 서버 시계가 3분 느리고 방화벽 시계는 정확하다면 어떻게 될까요?
NTP(Network Time Protocol)는 이 문제를 해결하는 프로토콜이고, 기본적으로 UDP 123 포트를 사용합니다. 이 글의 질문은 이 시리즈의 핵심 질문과 같습니다. "UDP 123에서 어떤 서비스와 프로토콜이 통신하는가, 그리고 그 결과가 로그 신뢰성에 어떤 영향을 주는가" 입니다.
| 항목 | 내용 |
|---|---|
| 전송 계층 | UDP |
| 기본 포트 | 123 (클라이언트·서버 모두) |
| 계층 구조 | Stratum(층) 개념. 기준 시계(GPS·원자시계)가 Stratum 0, 이에 직접 연결된 서버가 Stratum 1 |
| 동기화 불가 표시 | Stratum 16은 "동기화되지 않음"을 의미 |
| 주요 구현체 | chrony(chronyd), ntpd, systemd-timesyncd(SNTP 클라이언트), Windows w32time |
| 보안 확장 | NTS(Network Time Security): 키 교환에 TCP 4460 사용, 시간 교환은 기존 UDP 123 |
Stratum 숫자는 "정확도"가 아니라 기준 시계로부터 몇 단계 떨어져 있는가를 뜻합니다. 조직 내부에서는 보통 소수의 내부 NTP 서버가 외부 공용 서버와 동기화하고, 나머지 서버·장비는 내부 NTP 서버만 바라보도록 구성합니다. 그래야 외부로 나가는 UDP 123 트래픽을 최소화하고, 모든 장비가 같은 기준을 공유합니다.
| 구분 | Rocky Linux | Ubuntu |
|---|---|---|
| 기본 동기화 데몬 | chronyd (패키지 chrony) | 버전에 따라 systemd-timesyncd 또는 chrony (설치 상태를 직접 확인) |
| 설정 파일 | /etc/chrony.conf | chrony: /etc/chrony/chrony.conf / timesyncd: /etc/systemd/timesyncd.conf |
| 서비스 이름 | chronyd | chrony: chrony / timesyncd: systemd-timesyncd |
| 상태 확인 | chronyc tracking, chronyc sources | chrony는 동일, timesyncd는 timedatectl timesync-status |
| 로그 확인 | journalctl -u chronyd | journalctl -u chrony 또는 journalctl -u systemd-timesyncd |
systemd-timesyncd는 클라이언트 전용(SNTP)이라 다른 장비에 시간을 제공하지 않습니다. 반면 chrony는 설정(allow 지시어)에 따라 NTP 서버 역할도 할 수 있습니다. 즉 UDP 123을 LISTEN하는지 여부가 구성에 따라 달라집니다.
시간 동기화와 별개로, 로그에 시간대(Timezone) 정보가 있는지도 중요합니다.
| 로그 형식 | 예 | 문제점 |
|---|---|---|
| 전통적 syslog 형식 | Sep 26 14:03:11 | 연도·시간대가 없음 |
| ISO 8601 / RFC 5424 계열 | 2026-09-26T14:03:11.123+09:00 | 시간대 오프셋 포함, 비교가 쉬움 |
| journald 내부 | UTC 기준으로 저장, 출력 시 로컬 시간 변환 | 출력 옵션에 따라 표시가 달라짐 |
서버 A는 UTC, 서버 B는 KST(+09:00)로 로그를 남기면 동기화가 정확해도 9시간 차이가 보입니다. 그래서 관제에서는 "시계가 맞는가"와 "시간대가 표기되는가"를 함께 봅니다.
NTP 클라이언트는 서버와 타임스탬프 4개를 주고받아 왕복 지연(delay) 과 시계 차이(offset) 를 계산합니다.

그림 1. 시간 동기화가 무너지면 여러 로그를 결합하는 타임라인 분석이 틀어집니다
클라이언트 NTP 서버 (UDP 123)
│ │
T1 │ ── 요청 (Mode 3: client) ─────────────────→ │ T2 (수신 시각)
│ │
│ ←───────────────── 응답 (Mode 4: server) ── │ T3 (송신 시각)
T4 │ │
↓
offset = ((T2 - T1) + (T3 - T4)) / 2 → 내 시계가 얼마나 틀렸는가
delay = (T4 - T1) - (T3 - T2) → 네트워크 왕복에 걸린 시간
↓
여러 서버의 결과를 비교해 신뢰할 소스 선택
↓
작은 오차: 시계 속도를 조금씩 조정 (slew)
큰 오차 : 시계를 한 번에 이동 (step, 설정에 따라 허용)
여기서 관제 관점의 포인트는 두 가지입니다.
makestep 설정으로 부팅 직후 등 제한된 경우에만 step을 허용하는 것이 일반적입니다.monlist(Mode 7) 응답이 반사·증폭 DDoS에 악용된 사례가 대표적입니다. (패킷 필드 단위 해석은 03. Wireshark 패킷 분석 시리즈에서 다룸)실습 환경: 본인 소유 Linux VM (Rocky Linux 또는 Ubuntu). 인터페이스 이름 ens33은 예시이며 ip a로 본인 환경의 이름을 확인합니다.
timedatectl
timedatectl show --property=NTPSynchronized --value
# Rocky Linux (보통 기본 설치됨)
sudo dnf install -y chrony
sudo systemctl enable --now chronyd
# Ubuntu (chrony를 쓰려는 경우 — 설치하면 보통 systemd-timesyncd를 대체함)
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
chronyc tracking # 현재 기준 소스, offset, stratum
chronyc sources -v # 사용 중인 NTP 소스 목록과 상태 기호 설명
chronyc sourcestats # 소스별 통계(오차 추정)
systemctl status systemd-timesyncd
timedatectl timesync-status
timedatectl show-timesync --all
sudo ss -ulnp | grep -E ':(123|323)\b'
chronyd는 기본적으로 로컬 관리용 명령 포트(UDP 323, localhost)를 열고, allow 설정이 없으면 다른 장비에 시간을 제공하지 않습니다. 내부 NTP 서버로 쓸 VM에서만 설정 파일에 다음을 추가합니다.
# /etc/chrony.conf (Rocky) 또는 /etc/chrony/chrony.conf (Ubuntu)
allow 192.168.10.0/24
sudo systemctl restart chronyd # Ubuntu는 chrony
sudo firewall-cmd --permanent --add-service=ntp && sudo firewall-cmd --reload # Rocky
sudo ufw allow from 192.168.10.0/24 to any port 123 proto udp # Ubuntu
# tcpdump 설치: Rocky는 dnf install -y tcpdump, Ubuntu는 apt install -y tcpdump
sudo tcpdump -ni ens33 udp port 123
다른 터미널에서 sudo chronyc burst 2/4를 실행하면 짧은 시간 안에 여러 번 질의가 나가 관찰이 쉬워집니다.
📷 [실습 화면 삽입]
chronyc tracking과chronyc sources -v출력 화면
📷 [실습 화면 삽입]
tcpdump -ni ens33 udp port 123으로 요청·응답이 오가는 화면
chronyc sources 출력은 다음과 같은 형태입니다. 형식 예시(값은 환경마다 다름)
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 192.168.10.1 2 6 377 34 +215us[ +301us] +/- 12ms
^+ 203.0.113.10 2 6 377 35 -1021us[ -935us] +/- 25ms
^? 198.51.100.20 0 6 0 - +0ns[ +0ns] +/- 0ns
| 기호/필드 | 의미 |
|---|---|
^* | 현재 동기화 기준으로 선택된 소스 |
^+ | 선택된 소스와 함께 계산에 사용되는 양호한 소스 |
^? | 연결 불가 또는 아직 판단 불가 |
^x | 다른 소스와 크게 어긋나 신뢰하지 않는 소스(falseticker) |
Reach | 최근 8회 응답 여부를 8진수로 표시, 377이면 8회 모두 응답 |
Last sample | 측정된 offset과 오차 범위 |
timedatectl 출력의 핵심 줄 형식 예시(값은 환경마다 다름)
Local time: Sat 2026-09-26 14:03:11 KST
Universal time: Sat 2026-09-26 05:03:11 UTC
Time zone: Asia/Seoul (KST, +0900)
System clock synchronized: yes
NTP service: active
점검 체크리스트
System clock synchronized: yes인가chronyc sources에 ^* 소스가 존재하는가chrony 로그 형식 예시(값은 환경마다 다름)
chronyd[812]: Selected source 192.168.10.1
chronyd[812]: System clock wrong by 184.52 seconds
chronyd[812]: System clock was stepped by 184.52 seconds
systemd-timesyncd 로그 형식 예시(값·문구는 systemd 버전마다 다름)
systemd-timesyncd[655]: Contacted time server 192.168.10.1:123 (192.168.10.1).
systemd-timesyncd[655]: Initial clock synchronization to Sat 2026-09-26 14:03:11.482 KST.
journalctl -u chronyd --since "1 hour ago" # Rocky
journalctl -u chrony --since "1 hour ago" # Ubuntu (chrony)
journalctl -u systemd-timesyncd --since "1 hour ago" # Ubuntu (timesyncd)
journalctl --since today | grep -i "time has been changed"
| 관찰 내용 | 정상일 수 있는 경우 | 의심해야 하는 경우 |
|---|---|---|
| 부팅 직후 시계 step 발생 | VM 복원·장기간 전원 꺼짐 후 첫 동기화 | 운영 중 반복적인 step, 특히 사고 시간대 직전 |
| 외부 공용 NTP로 UDP 123 통신 | 내부 NTP 서버가 상위 서버와 동기화 | 일반 서버·PC가 임의의 외부 NTP로 직접 통신 |
| 외부에서 UDP 123 인바운드 | 공개 NTP 서비스를 운영하는 경우 | NTP 서비스가 없는 서버로 들어오는 대량 요청 |
| Mode 6·7 요청 | 내부 관리 목적의 제한된 조회 | 외부발 대량 Mode 6·7 요청(정보 수집·증폭 시도) |
| 수동 시간 변경 로그 | 승인된 유지보수 작업 | 권한 상승 직후의 date -s·timedatectl set-time 흔적 |
공격자가 시스템 시계를 바꾸면 이후 생성되는 로그와 파일 시간이 모두 틀어집니다. 그래서 로컬 로그만으로 시간을 신뢰하지 않고, 원격 Syslog 서버·SIEM이 수신한 시각과 비교하는 습관이 필요합니다. 수신 시각과 이벤트 내부 시각의 차이가 갑자기 커지는 것도 하나의 이상징후입니다.
| 흔적 위치 | 확인 내용 |
|---|---|
| 서버 journal | chronyd/timesyncd 동기화·step 기록, "Time has been changed" |
| 방화벽 로그 | UDP 123 아웃바운드 목적지(승인된 NTP 서버인가), 인바운드 123 허용 여부 |
| SIEM | 이벤트 시각과 수신 시각의 차이, 장비별 시간 편차 |
| NetFlow/세션 로그 | 특정 호스트의 UDP 123 대량 송수신(증폭 반사 의심) |
timedatectl로 먼저 확인합니다.chronyc tracking·chronyc sources로 기준 소스(^*)와 offset, Reach를 점검합니다.