La foret rouge

Linux/Windows 시간 동기화

Published on
Published on

최근에 NTP 관련해서 이것 저것 테스트했던 내용을 정리합니다.

시간 동기화 서비스

Linux: chrony

Red Hat 기준으로 6 이하에서는 ntpd가 사용되었고, 7부터는 chrony가 지원되며 8 이상은 chrony가 기본적으로 설치되어 있습니다. 이 글에서는 Rocky Linux 9 버전에서 chrony를 기준으로 사용법을 설명합니다.

서비스 확인

> dnf list --installed | grep chrony
chrony.x86_64   4.6.1-1.el9     @baseos
# 설치 안 되어 있으면 `dnf install chrony` 실행

> systemctl status chronyd
● chronyd.service - NTP client/server
     Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; preset: enabled)
     Active: active (running) since Thu 2025-08-28 20:57:45 KST; 2 days ago
       Docs: man:chronyd(8)
             man:chrony.conf(5)
   Main PID: 819 (chronyd)
      Tasks: 1 (limit: 100412)
     Memory: 1.1M
        CPU: 272ms
     CGroup: /system.slice/chronyd.service
             └─819 /usr/sbin/chronyd -F 2
# active, enabled 상태가 아니면 `systemctl enable chronyd`, `systemctl start chronyd` 실행
# ⚠️ 여기에서는 명령어가 chrony가 아니라 chronyd (daemon)

시간 서버 지정하여 동기화

클라이언트로 사용할 때는 시간 동기화 서버를 지정하는 것 외에 특별히 설정을 바꿔줄 것이 없는 것 같습니다.

시간 동기화 서버 지정은 pool 또는 server 설정으로 가능합니다. 사용가능한 서버는 다음과 같습니다. (2025.08.31 확인)

  • Rocky 9.6 버전 기본: pool 2.rocky.pool.ntp.org iburst
  • NTP Pool Project에 등록된 서버 사용
  • server time.bora.net iburst
  • server ntp2.kornet.net iburst
> vi /etc/chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (https://www.pool.ntp.org/join.html).
#pool 2.rocky.pool.ntp.org iburst
server time.bora.net iburst
server ntp2.kornet.net iburst

# ...

> systemctl restart chronyd
> chronyc sources -v

  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current best, '+' = combined, '-' = not combined,
| /             'x' = may be in error, '~' = too variable, '?' = unusable.
||                                                 .- xxxx [ yyyy ] +/- zzzz
||      Reachability register (octal) -.           |  xxxx = adjusted offset,
||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
||                                \     |          |  zzzz = estimated error.
||                                 |    |           \
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^+ time.bora.net                 2   6     7     1   +390us[  +40us] +/-   46ms
^* 220.73.142.66                 2   6     7     1    -53us[ -403us] +/- 8061us

설정 파일에 원하는 시간 동기화 서버를 추가하고 서비스 재시작을 하면 지정한 시간 서버와 동기화를 시도합니다. chronyc sources만 해도 동기화 상태를 볼 수 있고, -v 옵션을 붙이면 위 예시와 같이 설명까지 볼 수 있습니다. 예시에서는 ntp2.kornet.net과 동기화가 더 잘 되어 이 서버가 최선의 동기화 상대로 선택된 것을 볼 수 있습니다.

위에서 시간 서버를 지정할 때 iburst를 붙였는데, 이 옵션은 서비스가 시작할 때 짧은 시간에 4개 이상의 요청을 보내 첫 시간 동기화를 빠르게 하기 위한 옵션입니다1. 이 옵션을 설정하지 않았다면 첫 동기화도 주기에 맞춰 진행되므로 오래 기다려야 합니다.

burst를 첫 시간 동기화 뿐만 아니라 일회성으로도 실행할 수 있습니다. 이 때는 chronyc burst 2/10 처럼 사용합니다. 2번 이상 응답 성공이 오지 않으면 10번까지 요청을 보내보는 것입니다.

그리고 만약 시간 동기화를 즉시 하고싶다면 chronyc makestep 명령어를 사용합니다. 현재 시간 오차를 기준으로 다시 오차 줄이기를 시작합니다. 다만, chrony의 동작 알고리즘상 오차를 조금씩 점진적으로 줄이는 방식으로 맞춰나가기 때문에 시간이 조금 걸립니다.

Windows: W32Time

Windows Server에서는 W32Time이라는 서비스가 있습니다. 이 서비스는 도메인에 속한 서버들이 도메인 컨트롤러와 시간을 동기화할 때 사용되는 서비스입니다. 도메인에 join되지 않은 윈도우 서버는 기본적으로 time.windows.com과 동기화 하도록 되어 있습니다2.

서비스 확인

w32time 서비스 시간 동기화 확인은 w32tm /query /status 명령어를 사용합니다. 이 예시에서는 서비스가 시작되어 있지 않은 상태입니다. 서비스를 실행하고 시간 동기화를 확인해봅시다.

서비스 실행은 서비스(services.msc)에서 GUI로 해도 되고, 명령어로 해도 됩니다. 저는 명령어로 시스템 실행 시 자동 시작 옵션을 추가하고 서비스를 시작했습니다.

시간 서버 지정하여 동기화

윈도우 서버는 기본적으로 time.windows.com과 동기화 하도록 되어 있습니다. 이를 명령어로 리눅스 예시처럼 time.bora.net, ntp2.kornet.net과 시간 동기화를 하도록 만들 수 있습니다.

이제 새 시간 동기화 서버와 동기화가 되도록 해봅시다. W32Time 서비스를 재시작해도 되고, 단순히 resync만 해도 됩니다.

내부망 NTP 서버 구축

외부 서버와의 통신은 길게는 수백ms에서 나쁘게는 초 단위까지 걸릴 수도 있지만, 내부 네트워크 간 통신은 수 ms이면 충분합니다. 때문에 이렇게 구성하면 내부 서버들 간의 시간 오차를 조금 더 줄일 수 있을 것입니다.

이 그림과 같이 내 Homelab 환경의 VM 또는 사내망 서버들을 위에서 소개한 외부 시간 서버가 아닌 내부망 시간 서버와 동기화하도록 설정해봅시다. 테스트 환경에서 내부 시간 서버는 Rocky Linux 9 버전과 chrony를 사용합니다.

내부 시간 서버 셋업

기본적으로는 이 글 상단의 Linux: chrony 내용을 바탕으로 설치 및 실행 확인을 합니다.

그리고 설정을 조금 다르게 해줍니다.

> vi /etc/chrony.conf
server time.bora.net iburst
server ntp2.kornet.net iburst
# ...
allow 192.168.100.0/24
# ...

다른 설정은 기본값으로 두고, server는 위에서 했던 것처럼 time.bora.netntp2.kornet.net을 사용했습니다. 추가로, allow 192.168.100.0/24 설정을 해줍니다. 해당 IP 대역에서는 이 서버로 시간 동기화를 허용합니다. (IP 대역은 현재 사용 중인 공유기의 내부망 대역을 사용하면 됩니다. 제 내부망 IP와는 다를 수 있습니다.)

그리고 방화벽을 사용한다면 다른 서버들이 이 시간 서버와 ntp 프로토콜로 시간 동기화를 할 수 있도록 포트를 허용해줍니다.

> firewall-cmd --add-port=123/udp --permanent
> firewall-cmd --reload

내부망 클라이언트 서버 설정 변경

이제 내부망 서버들은 외부 시간 서버가 아니라 방금 설정한 내부 시간 서버를 보도록 설정을 변경해줍니다. 그리고 chrony를 재시작해주어야 적용됩니다.

> vi /etc/chrony.conf
server 192.168.100.XXX iburst

> systemctl restart chrony

> chronyc sources

Footnotes

  1. Richard Curnow, et al. "chrony.conf(5) Manual Page." chrony-project. https://chrony-project.org/doc/3.4/chrony.conf.html (accessed Aug. 31, 2025).

  2. "How the Windows Time Service works." Microsoft Learn. https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/how-the-windows-time-service-works (accessed Sep. 1, 2025).