ตั้งค่า Chrony NTP บน VPS ซิงค์เวลาอัตโนมัติ
หนึ่งในปัญหาที่หลายคนมองข้ามเมื่อตั้ง VPS คือ เวลาของ server ที่คลาดเคลื่อน (clock drift) ซึ่งดูเหมือนเรื่องเล็กแต่ส่งผลกระทบหลายอย่าง ตั้งแต่ใบรับรอง SSL/TLS หมดอายุก่อนกำหนด, cron job ทำงานผิดเวลา, log ที่ timestamp ไม่ตรง, ไปจนถึง authentication token ที่ถูก reject เพราะเวลาต่าง Chrony คือ NTP client/server สมัยใหม่ที่ออกแบบมาเพื่อแทนที่ ntpd เดิม โดยซิงค์เวลาได้เร็วกว่า ใช้ทรัพยากรน้อยกว่า และทนต่อการ disconnect/reconnect ได้ดีกว่า ซึ่งเหมาะมากสำหรับ VPS ที่เครือข่ายอาจไม่เสถียร 100%
ทำไมต้องใช้ Chrony แทน systemd-timesyncd?
Ubuntu ติดตั้ง systemd-timesyncd มาให้อยู่แล้ว แต่มันเป็นแค่ SNTP client ที่ sync ครั้งเดียวตอน boot และ drift correction ช้า Chrony เป็น full NTP implementation ที่:
- ปรับนาฬิกา real-time อย่างต่อเนื่อง ไม่ใช่แค่ตอน boot
- รองรับ hardware timestamping เพื่อความแม่นยำสูง
- จัดการ network jitter และ latency ได้ดีกว่า
- สามารถทำงานเป็น NTP server ให้ VPS อื่นในเครือข่ายเดียวกันได้
- รองรับ NTS (NTP over TLS) สำหรับ encrypted time sync
| Feature | systemd-timesyncd | Chrony | ntpd (เดิม) |
|---|---|---|---|
| Protocol | SNTP | NTPv4 | NTPv4 |
| Continuous adjustment | ไม่ | ใช่ | ใช่ |
| NTP Server mode | ไม่ | ใช่ | ใช่ |
| NTS (encrypted) | ไม่ | ใช่ (v4.0+) | ไม่ |
| Memory usage | ต่ำมาก | ต่ำ | ปานกลาง |
| ความเหมาะสมกับ VPS | พอใช้ | แนะนำ | ใช้ได้ |
ติดตั้ง Chrony บน Ubuntu/Debian
# อัพเดท package list
sudo apt update
# ติดตั้ง Chrony
sudo apt install -y chrony
# ตรวจสอบ version
chronyc --version
หยุด systemd-timesyncd ก่อนใช้ Chrony
ไม่ควรใช้ทั้งสองพร้อมกัน เพราะจะ conflict กันในการควบคุมนาฬิการะบบ:
# ตรวจสอบว่า timesyncd กำลังทำงานหรือไม่
systemctl status systemd-timesyncd
# หยุดและ disable timesyncd
sudo systemctl stop systemd-timesyncd
sudo systemctl disable systemd-timesyncd
# เปิดใช้ Chrony และให้ start ตอน boot
sudo systemctl enable --now chrony
ตั้งค่า /etc/chrony/chrony.conf
ไฟล์ config หลักอยู่ที่ /etc/chrony/chrony.conf ค่า default ใช้ NTP pool ของ Ubuntu ซึ่งดีอยู่แล้ว แต่ถ้าต้องการ customize สามารถแก้ไขได้ดังนี้:
sudo nano /etc/chrony/chrony.conf
ตัวอย่าง config ที่แนะนำสำหรับ VPS ทั่วไป:
# NTP servers — ใช้ pool.ntp.org หรือ server ของ datacenter
pool 0.pool.ntp.org iburst maxsources 4
pool 1.pool.ntp.org iburst maxsources 4
pool time.cloudflare.com iburst
# ที่เก็บ drift file (บันทึกการปรับเวลาล่าสุด)
driftfile /var/lib/chrony/chrony.drift
# Log ไฟล์ (ตัดออกถ้าไม่ต้องการ)
logdir /var/log/chrony
# ยอมให้ NTP clients เชื่อมต่อจาก network นี้ (ถ้าทำ NTP server)
# allow 192.168.1.0/24
# อนุญาต large step ครั้งแรก (สำหรับ server ที่เวลาเบี่ยงมาก)
makestep 1.0 3
# อ่านเวลาจาก RTC (Real-Time Clock)
rtcsync
# Leap second handling
leapsectz right/UTC
บันทึกไฟล์และ restart Chrony:
sudo systemctl restart chrony
ตั้ง Timezone ให้ถูกต้อง
NTP ซิงค์ UTC เสมอ แต่ควรตั้ง timezone ของ server ให้ถูกต้องด้วย:
# ดู timezone ปัจจุบัน
timedatectl
# ดูรายการ timezone ที่มี
timedatectl list-timezones | grep Asia
# ตั้ง timezone (ตัวอย่าง: เอเชีย/กรุงเทพ)
sudo timedatectl set-timezone Asia/Bangkok
# ยืนยัน
date
ตั้งค่า Chrony เป็น NTP Server สำหรับ LAN
ถ้ามี VPS หลายตัวในเครือข่ายเดียวกัน (เช่น private network ของ datacenter) สามารถตั้ง VPS ตัวหนึ่งเป็น NTP server ส่วนกลางได้:
# แก้ไข /etc/chrony/chrony.conf เพิ่มบรรทัดนี้
allow 10.0.0.0/8
# Restart Chrony
sudo systemctl restart chrony
# บน VPS ตัวอื่น ให้ชี้มาที่ server IP นี้
# pool 10.0.0.1 iburst
ตรวจสอบว่า Chrony ทำงานถูกต้อง
# ดูสถานะ Chrony service
systemctl status chrony
# ดู NTP sources ที่ใช้อยู่
chronyc sources -v
# ดูค่า offset และความแม่นยำ
chronyc tracking
# ดู activity ของ Chrony
chronyc activity
# ดู statistics แต่ละ source
chronyc sourcestats -v
chronyc sources สัญลักษณ์ * หน้า server หมายถึง source ที่ Chrony เลือกใช้อยู่ตอนนี้ ถ้าเห็น ^* หมายถึง synchronized และกำลังใช้งาน source นั้นแก้ปัญหาที่พบบ่อย
Error: "No sources online"
Chrony ไม่สามารถเชื่อมต่อ NTP server ได้ ตรวจสอบ firewall และ DNS:
# ทดสอบ connectivity ไปยัง NTP server
nc -uzv pool.ntp.org 123
# ตรวจสอบ firewall — ต้องอนุญาต UDP port 123 ขาออก
sudo ufw status
sudo iptables -L OUTPUT -n | grep 123
# ทดสอบ DNS resolution
dig pool.ntp.org
# ดู Chrony log เพิ่มเติม
sudo journalctl -u chrony -n 50
Error: "System clock wrong by more than 1000 seconds"
เวลา server เบี่ยงเกิน Chrony limit ต้องบังคับ step ครั้งเดียว:
# บังคับ sync เวลาทันที (step ทันที ไม่รอ slew)
sudo chronyc makestep
# หรือหยุด Chrony แล้ว sync ด้วย ntpdate
sudo systemctl stop chrony
sudo ntpdate -s pool.ntp.org
sudo systemctl start chrony
Error: "chronyd: Could not open /var/run/chrony/chronyd.pid"
ปัญหา permission ของ directory runtime:
# สร้าง directory และกำหนดสิทธิ์
sudo mkdir -p /var/run/chrony
sudo chown _chrony:_chrony /var/run/chrony
# Restart service
sudo systemctl restart chrony
Error: systemd-timesyncd conflict — "Can't synchronize: NTP client conflict"
ยังมี service อื่นควบคุมนาฬิกาอยู่ด้วย:
# ตรวจสอบ services ที่ทำงานอยู่
systemctl is-active systemd-timesyncd
systemctl is-active ntp
# หยุด services ที่ conflict
sudo systemctl disable --now systemd-timesyncd
sudo systemctl disable --now ntp # ถ้ามี ntpd ติดตั้งอยู่
sudo systemctl restart chrony
chronyc tracking
Clock drift กลับมาหลังจาก reboot
ตรวจสอบว่า driftfile เขียนได้และ RTC sync เปิดอยู่:
# ตรวจสอบ driftfile
ls -la /var/lib/chrony/
cat /var/lib/chrony/chrony.drift
# ตรวจสอบ rtcsync ใน config
grep rtcsync /etc/chrony/chrony.conf
# บังคับ sync RTC ปัจจุบัน
sudo hwclock --systohc
คำถามที่พบบ่อย
Chrony กับ ntpd ต่างกันอย่างไร?
Chrony ออกแบบมาสำหรับระบบที่ไม่ได้เชื่อมต่อเน็ตตลอดเวลาและ VPS virtualization environment — มันปรับนาฬิกาแบบค่อยๆ slew (ไม่กระโดด) เร็วกว่า ntpd และรองรับ NTS encryption ในขณะที่ ntpd เป็น implementation เก่าที่ใช้ทรัพยากรมากกว่า Linux distros ใหม่ๆ เช่น Fedora, RHEL 8+ และ Ubuntu 20.04+ ต่างเปลี่ยนมาใช้ Chrony เป็น default แล้ว
ต้องเปิด firewall port อะไรให้ Chrony?
สำหรับ NTP client (รับเวลาจาก internet): ต้องอนุญาต UDP port 123 ขาออก เท่านั้น ส่วนใหญ่ firewall ไม่บล็อก outgoing UDP ถ้าต้องทำเป็น NTP server ด้วย ต้องเปิด UDP port 123 ขาเข้า เพิ่มด้วย sudo ufw allow 123/udp
ใช้ NTS (encrypted NTP) ได้ไหม?
ได้ ถ้าใช้ Chrony 4.0 ขึ้นไป เพิ่ม server ที่รองรับ NTS ใน config:
# ตัวอย่างใน /etc/chrony/chrony.conf
server time.cloudflare.com iburst nts
server nts.ntp.se iburst nts
# ตรวจสอบ NTS status
chronyc -n authdata