نصب و راه‌اندازی NTP و تنظیم TimeZone سرور لینوکس

نصب و راه‌اندازی NTP و تنظیم TimeZone سرور لینوکس

سرور بالا آمده و همه چیز درست کار می‌کند، اما ساعتش چند دقیقه — گاهی چند ساعت — با واقعیت فرق دارد. نتیجه‌اش را دیر یا زود می‌بینید: هندشیک SSL با خطای certificate is not yet valid رد می‌شود، کران‌جاب‌ها در ساعت اشتباه اجرا می‌شوند، لاگ دو سرور را نمی‌شود کنار هم گذاشت و رپلیکیشن دیتابیس خطا می‌دهد.

حل این مشکل دو بخش دارد که خیلی‌ها آن‌ها را با هم اشتباه می‌گیرند:

  • TimeZone تعیین می‌کند زمان چطور نمایش داده شود؛ یعنی سیستم لحظه فعلی را با چه اختلافی نسبت به UTC به شما نشان بدهد.
  • NTP تعیین می‌کند آن لحظه واقعی چقدر دقیق باشد؛ یعنی ساعت سیستم را با ساعت مرجع جهانی همگام نگه می‌دارد.

اگر فقط TimeZone را درست کنید، ساعت با فرمت درست ولی عدد غلط نمایش داده می‌شود. اگر فقط NTP را راه‌اندازی کنید، لحظه دقیق است ولی ممکن است تاریخ لاگ‌ها با انتظار شما جور نباشد. در ادامه هر دو را انجام می‌دهیم.

NTP چیست؟

NTP یا Network Time Protocol یک پروتکل استاندارد اینترنتی است که برای سینک کردن ساعت سیستم‌ها با ساعت مرجع جهانی (UTC) استفاده می‌شود. این پروتکل با دریافت زمان از سرورهای NTP معتبر، اختلاف زمانی سیستم شما را تا حد میلی‌ثانیه کاهش می‌دهد و هماهنگی بین سیستم‌ها را برقرار می‌کند. ارتباط NTP روی پورت UDP 123 انجام می‌شود؛ اگر فایروال شبکه یا فایروال سرور این پورت را در جهت خروجی ببندد، هیچ‌کدام از روش‌های زیر کار نخواهد کرد.

پروتکل NTP و همگام‌سازی زمان سرورها با ساعت مرجع جهانی

مفاهیم کلیدی NTP

  • Offset: اختلاف زمانی بین سیستم شما و سرور مرجع (معمولاً بر حسب میلی‌ثانیه).
  • Drift: نرخ تغییر ساعت داخلی سیستم که به دلیل نوسانات سخت‌افزاری رخ می‌دهد. سرویس NTP این نرخ را در فایل drift ذخیره می‌کند تا بعد از ری‌استارت، از صفر شروع نکند.
  • Stratum: سطح سلسله‌مراتبی سرور NTP؛ سرور Stratum 1 مستقیماً به یک ساعت مرجع (GPS یا اتمی) متصل است و سرورهای Stratum 2 از Stratum 1 همگام می‌شوند. عدد ۱۶ یعنی آن سرور هنوز همگام نشده و قابل استفاده نیست.
  • Jitter: میزان نوسان اندازه‌گیری‌ها؛ هرچه کمتر باشد، مسیر شبکه تا آن سرور پایدارتر است.

چرا زمان دقیق روی سرور حیاتی است

  • ثبت دقیق لاگ‌ها: بدون زمان دقیق و هماهنگ، بررسی رخدادها و عیب‌یابی بین چند سرور تقریباً غیرممکن می‌شود.
  • هماهنگی سرویس‌های توزیع‌شده: دیتابیس‌های رپلیکیت‌شده، صف‌ها و کلاسترها بدون زمان هماهنگ دچار خطا می‌شوند.
  • امنیت و SSL: گواهی‌های TLS، توکن‌های JWT، رمزهای یک‌بارمصرف (OTP/2FA) و Kerberos همگی به زمان درست وابسته‌اند. ساعت اشتباه سرور یکی از رایج‌ترین دلایل خطاهای عجیب SSL است.
  • تراکنش‌های مالی: زمان نادرست می‌تواند به خطای ثبت تراکنش، مغایرت گزارش‌ها یا رد شدن کال‌بک درگاه پرداخت منجر شود.
  • قابلیت اعتماد کلی: یک منبع زمانی مشترک بین چند سرور، هم خطاهای لاگ و دیتابیس را کم می‌کند و هم سرویس‌های حساس به زمان را قابل اتکا نگه می‌دارد.

قدم اول: وضعیت فعلی را ببینید

قبل از هر تغییری، ببینید سیستم الان در چه وضعیتی است. روی هر توزیع مدرن لینوکس (با systemd) این دستور همه چیز را یکجا نشان می‌دهد:

timedatectl

خروجی چیزی شبیه این است:

               Local time: Thu 2026-08-06 14:22:31 +0330
           Universal time: Thu 2026-08-06 10:52:31 UTC
                 RTC time: Thu 2026-08-06 10:52:31
                Time zone: Asia/Tehran (+0330, +0330)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

سه خط مهم است: Time zone که منطقه زمانی فعلی را نشان می‌دهد، System clock synchronized که می‌گوید ساعت واقعاً سینک شده یا نه، و NTP service که مشخص می‌کند سرویسی برای همگام‌سازی فعال است یا خیر. اگر دوتای آخر no و inactive باشند، سرور شما هیچ منبع زمانی ندارد و ساعتش به‌مرور دور می‌شود.

تنظیم TimeZone سرور لینوکس

روش درست و امروزی

اول فهرست منطقه‌های زمانی را جست‌وجو کنید تا نام دقیق را بردارید:

timedatectl list-timezones | grep -i tehran

سپس منطقه زمانی را تنظیم کنید:

sudo timedatectl set-timezone Asia/Tehran

و نتیجه را با date یا دوباره با timedatectl بررسی کنید. نام منطقه زمانی حساس به حروف بزرگ و کوچک است و باید دقیقاً به شکل قاره/شهر و با حرف اول بزرگ نوشته شود؛ asia/tehran پذیرفته نمی‌شود.

یک نکته مهم: تغییر TimeZone روی پروسه‌هایی که همان لحظه در حال اجرا هستند اثر نمی‌کند. سرویس‌هایی مثل وب‌سرور، php-fpm، MySQL و کران را بعد از تغییر ری‌استارت کنید تا زمان جدید را بخوانند.

اگر سرور به اینترنت دسترسی ندارد

تنظیم TimeZone به اینترنت نیازی ندارد و آفلاین هم کار می‌کند؛ چیزی که به اینترنت نیاز دارد، همگام‌سازی ثانیه‌به‌ثانیه با NTP است. اگر سرور شما اصلاً به هیچ منبع زمانی دسترسی ندارد، می‌توانید ساعت را دستی بگذارید، ولی توقع دقت در حد ثانیه نداشته باشید و بدانید که به‌مرور دوباره دور می‌شود:

# اول همگام‌سازی خودکار را خاموش کنید، وگرنه set-time خطا می‌دهد
sudo timedatectl set-ntp false
sudo timedatectl set-time "2026-08-06 14:22:31"

هشدار: این دستور ساعت را همان لحظه و به‌صورت پرشی عوض می‌کند. اگر روی سرور دیتابیس یا سرویس حساس به ترتیب زمان دارید، اول آن‌ها را متوقف کنید. به محض اینکه دسترسی به اینترنت برقرار شد، دوباره set-ntp true بزنید تا سرور به منبع واقعی برگردد.

روش قدیمی با symlink (منسوخ است، اما ممکن است ببینید)

در آموزش‌های قدیمی‌تر برای تنظیم ساعت سرور به وقت ایران این دستورها را می‌بینید:

# روش قدیمی — روی سیستم‌های امروزی از timedatectl استفاده کنید
mv /etc/localtime /etc/localtime.bak
rm -f /etc/adjtime
ln -s /usr/share/zoneinfo/Asia/Tehran /etc/localtime
ntpdate 0.asia.pool.ntp.org

این روش هنوز از نظر فنی کار می‌کند (چون timedatectl هم در نهایت همین symlink را می‌سازد)، اما ایراد دارد: اگر بین mv و ln اتفاقی بیفتد سیستم بدون منطقه زمانی می‌ماند و به UTC برمی‌گردد، systemd از این تغییر دستی مطلع نمی‌شود، و خط آخر هم به ابزار منسوخ ntpdate تکیه می‌کند که در بخش «سینک فوری» جایگزین‌های امروزی‌اش را می‌بینید. روی هر سیستمی که systemd دارد — اوبونتو ۱۶.۰۴ به بعد، دبیان ۸ به بعد، CentOS 7 به بعد و AlmaLinux/Rocky — از timedatectl set-timezone استفاده کنید. حذف /etc/adjtime هم دیگر لازم نیست؛ این فایل توسط hwclock و systemd مدیریت می‌شود.

فایل /etc/sysconfig/clock دیگر کاربرد ندارد

در راهنماهای قدیمی گفته می‌شود برای یکسان‌سازی hardware clock و system clock فایل /etc/sysconfig/clock را با محتوای زیر ویرایش کنید:

# منسوخ — فقط در CentOS/RHEL نسخه 6 و قبل‌تر معنا داشت
UTC=false
ZONE="Asia/Tehran"

این فایل از CentOS/RHEL 7 به بعد کنار گذاشته شده و در اوبونتو هم هیچ‌وقت نقشی نداشته است؛ ویرایش آن روی سرورهای امروزی هیچ اثری ندارد. معادل امروزی‌اش این است:

# ساعت سخت‌افزاری روی UTC نگه داشته شود (توصیه‌شده برای سرور)
sudo timedatectl set-local-rtc 0

# نوشتن ساعت فعلی سیستم روی ساعت سخت‌افزاری (فقط روی سرور فیزیکی؛ در کانتینر کار نمی‌کند)
sudo hwclock --systohc

دقت کنید که UTC=false در آن نسخه قدیمی در واقع توصیه بدی بود: روی سرور، ساعت سخت‌افزاری (RTC) باید همیشه روی UTC بماند و فقط نمایش با TimeZone تنظیم شود. RTC روی وقت محلی مخصوص سیستم‌های دوبوته با ویندوز است و روی سرور فقط دردسر و لاگ‌های ناهماهنگ می‌سازد.

tzdata را به‌روز نگه دارید

قوانین منطقه زمانی کشورها تغییر می‌کند و لینوکس این قوانین را از بسته tzdata می‌خواند. مهم‌ترین نمونه برای ما: ایران از شهریور ۱۴۰۱ (سپتامبر ۲۰۲۲) دیگر ساعت تابستانی را اجرا نمی‌کند و اختلاف ثابت UTC+3:30 دارد. سروری که tzdata قدیمی داشته باشد، در فروردین و شهریور یک ساعت جابه‌جا می‌شود بدون اینکه شما کاری کرده باشید:

# اوبونتو / دبیان
sudo apt update && sudo apt install --only-upgrade tzdata

# AlmaLinux / Rocky / CentOS Stream
sudo dnf update tzdata

TimeZone در لایه اپلیکیشن: PHP و MySQL

حتی وقتی ساعت سیستم‌عامل درست است، PHP و MySQL می‌توانند زمان دیگری گزارش کنند، چون منطقه زمانی خودشان را جداگانه دارند.

برای PHP، مقدار زیر را در php.ini تنظیم کنید:

date.timezone = "Asia/Tehran"

این تنظیم در PHP 8 هم معتبر است و حذف نشده. اگر تنظیم نشود، PHP به‌طور پیش‌فرض UTC را در نظر می‌گیرد و برخلاف PHP 5، دیگر هیچ اخطاری هم نمایش نمی‌دهد — یعنی اشتباه بی‌سروصدا رخ می‌دهد. برای پیدا کردن فایل درست (چون CLI و FPM معمولاً php.ini جدا دارند):

php --ini
php -i | grep date.timezone

بعد از ویرایش، حتماً سرویس php-fpm مربوط به نسخه خودتان را ری‌استارت کنید؛ صرفاً ذخیره فایل کافی نیست:

sudo systemctl restart php8.3-fpm   # نام سرویس بسته به نسخه PHP شما فرق می‌کند

برای MySQL/MariaDB هم مقدار پیش‌فرض time_zone برابر SYSTEM است، یعنی از سیستم‌عامل ارث می‌برد. اگر می‌خواهید مستقل از سیستم تنظیمش کنید، در بخش [mysqld] فایل کانفیگ سرور دیتابیس اختلاف عددی را بدهید:

[mysqld]
default-time-zone = '+03:30'

نام‌هایی مثل 'Asia/Tehran' فقط وقتی پذیرفته می‌شوند که جدول‌های زمانی MySQL از قبل بارگذاری شده باشند:

mysql_tzinfo_to_sql /usr/share/zoneinfo | sudo mysql mysql

و برای بررسی وضعیت فعلی:

SELECT @@global.time_zone, @@session.time_zone, NOW();

کدام سرویس همگام‌سازی؟ timesyncd، chrony یا ntpd

امروز سه گزینه رایج وجود دارد. مهم است فقط یکی را فعال نگه دارید، چون دو سرویس همگام‌سازی که همزمان روی یک سیستم کار کنند هر کدام ساعت را به سمت خودش می‌کشد و نتیجه یک ساعت نوسانی و غیرقابل اعتماد است:

  • systemd-timesyncd: روی اوبونتو به‌صورت پیش‌فرض نصب و فعال است. یک کلاینت ساده SNTP است؛ برای اکثر سرورهای معمولی کاملاً کافی است، اما نمی‌تواند به دیگران سرویس زمان بدهد و ابزار عیب‌یابی محدودی دارد.
  • chrony: سرویس پیش‌فرض خانواده RHEL (AlmaLinux، Rocky، CentOS Stream) از نسخه ۷ به بعد. با قطعی‌های شبکه و ساعت‌های ناپایدار سرورهای مجازی بهتر کنار می‌آید و سریع‌تر همگام می‌شود. اگر تازه شروع می‌کنید، این گزینه پیشنهاد ما است.
  • ntpd (پیاده‌سازی کلاسیک) یا ntpsec: کامل‌ترین گزینه و مناسب زمانی که می‌خواهید سرور شما خودش نقش سرور NTP شبکه داخلی را بازی کند.

نکته تکمیلی: ntpd و chronyd در حالت سرور، پورت UDP 123 را برای خودشان باز می‌کنند. بنابراین اگر یکی از این دو در حال اجرا باشد، دومی هنگام بالا آمدن نمی‌تواند پورت را بگیرد و با خطا متوقف می‌شود. (systemd-timesyncd چون فقط کلاینت است روی ۱۲۳ گوش نمی‌دهد، ولی همچنان ساعت را می‌کشد و باید خاموش شود.)

نصب و راه‌اندازی سرویس NTP در سیستم‌عامل اوبونتو

نصب و راه‌اندازی NTP در اوبونتو

۱. اگر فقط سینک ساده می‌خواهید، چیزی نصب نکنید

روی اوبونتو سرویس systemd-timesyncd از قبل هست. یک دستور کافی است:

sudo timedatectl set-ntp true
timedatectl timesync-status

۲. به‌روزرسانی سیستم

sudo apt update && sudo apt upgrade -y

۳. غیرفعال کردن timesyncd پیش از نصب ntp

این مرحله را نادیده نگیرید؛ دو سرویس همزمان یعنی دو مدعی برای یک ساعت:

sudo systemctl disable --now systemd-timesyncd

۴. نصب بسته NTP

اینجا باید حواستان به نسخه اوبونتو باشد:

# اوبونتو 22.04 و قدیمی‌تر: بسته ntp همان ntpd کلاسیک است
sudo apt install ntp -y

# اوبونتو 24.04 به بعد (و دبیان 12 به بعد): بسته واقعی ntpsec است
sudo apt install ntpsec -y

توجه به تغییر نام: در اوبونتو ۲۴.۰۴ و دبیان ۱۲، بسته ntp فقط یک بسته انتقالی (transitional) است و در عمل ntpsec نصب می‌شود. در آن حالت نام سرویس ntpsec است، فایل پیکربندی در /etc/ntpsec/ntp.conf و فایل drift در /var/lib/ntpsec/ntp.drift قرار می‌گیرد — یعنی /etc/ntp.conf اصلاً وجود نخواهد داشت. پس از نصب، نام واقعی سرویس را چک کنید و در دستورهای بعدی همان را به کار ببرید:

systemctl list-units --type=service | grep -Ei 'ntp|chrony'

۵. بررسی وضعیت و فعال‌سازی سرویس

# نام سرویس را با چیزی که در مرحله قبل دیدید جایگزین کنید: ntp یا ntpsec
systemctl status ntp
sudo systemctl enable --now ntp

دستور enable --now سرویس را همین حالا اجرا می‌کند و مطمئن می‌شود که با بوت سیستم هم بالا بیاید. در توزیع‌های قدیمی ممکن است با دستورهایی مثل service ntp restart یا /etc/init.d/ntp restart روبه‌رو شوید؛ این‌ها منسوخ‌اند و معادل امروزی‌شان systemctl restart ntp است.

نمونه فایل پیکربندی ntp.conf

فایل /etc/ntp.conf (روی ntpsec: /etc/ntpsec/ntp.conf) را باز کنید. قبل از هر تغییری یک نسخه پشتیبان بگیرید:

sudo cp /etc/ntp.conf /etc/ntp.conf.bak
sudo nano /etc/ntp.conf

یک پیکربندی امن و کاربردی:

# سیاست پیش‌فرض: کسی از بیرون اجازه پرس‌وجوی مدیریتی یا تغییر تنظیمات ندارد
restrict default kod nomodify noquery limited
restrict -6 default kod nomodify noquery limited

# لوکال‌هاست دسترسی کامل دارد
restrict 127.0.0.1
restrict ::1

# سرورهای NTP مرجع
pool 0.ubuntu.pool.ntp.org iburst
pool 1.ubuntu.pool.ntp.org iburst
pool 2.ubuntu.pool.ntp.org iburst
pool 3.ubuntu.pool.ntp.org iburst

# فقط اگر می‌خواهید به شبکه داخلی سرویس زمان بدهید این خط را اضافه کنید
restrict 192.168.0.0 mask 255.255.255.0 nomodify noquery

# فایل drift و لاگ (مسیر drift را با پیاده‌سازی نصب‌شده هماهنگ کنید)
driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log

اگر در فایل پیش‌فرض سیستم خود گزینه‌های notrap یا nopeer را دیدید نگران نباشید؛ این‌ها بازمانده ntpd کلاسیک‌اند و ntpsec آن‌ها را نادیده می‌گیرد و فقط یک پیام در لاگ می‌گذارد.

توضیح خطوط مهم

  • pool / server: منابع مرجع برای سینک. دستور pool نسبت به server بهتر است چون از همه IPهایی که آن نام دامنه برمی‌گرداند استفاده می‌کند و اگر یکی از کار افتاد خودش جایگزین می‌گیرد. اگر فایل شما هنوز خطوط server 0.ubuntu.pool.ntp.org iburst دارد، ایرادی ندارد و کار می‌کند.
  • iburst: در اولین تماس چند بسته پشت سر هم می‌فرستد تا سینک اولیه به‌جای چند دقیقه، چند ثانیه طول بکشد.
  • restrict: محدودیت‌های امنیتی و شبکه. خطوط restrict default از همه مهم‌ترند و نباید حذف شوند (توضیح در بخش امنیت).
  • driftfile: نگهداری نرخ تغییر ساعت سیستم. مسیر آن باید با پیاده‌سازی نصب‌شده بخواند؛ /var/lib/ntp/ntp.drift برای ntpd کلاسیک و /var/lib/ntpsec/ntp.drift برای ntpsec.
  • logfile: مسیر لاگ سرویس. اگر این خط را نگذارید، لاگ‌ها در journald ثبت می‌شوند و با journalctl -u ntp قابل مشاهده‌اند.

بعد از هر تغییر، سرویس را ری‌استارت کنید:

sudo systemctl restart ntp

راه‌اندازی chrony در AlmaLinux، Rocky و CentOS Stream

روی خانواده RHEL معمولاً chrony از قبل نصب است و بسته‌ای به نام ntp در مخازن نسخه‌های جدید (RHEL 8 به بعد) وجود ندارد:

sudo dnf install -y chrony
sudo systemctl enable --now chronyd

فایل پیکربندی در این توزیع‌ها /etc/chrony.conf است (در اوبونتو و دبیان: /etc/chrony/chrony.conf). یک نمونه ساده:

pool 0.asia.pool.ntp.org iburst
driftfile /var/lib/chrony/drift

# اگر اختلاف در سه سینک اول بیشتر از 1 ثانیه بود، یکباره اصلاح کن
makestep 1.0 3

# همگام نگه داشتن ساعت سخت‌افزاری
rtcsync

# فقط اگر می‌خواهید به شبکه داخلی سرویس بدهید
allow 192.168.0.0/24

سپس:

sudo systemctl restart chronyd

تست و عیب‌یابی

با ntpq

ntpq -pn

سوئیچ -p فهرست منابع را نشان می‌دهد و -n از تبدیل IP به نام جلوگیری می‌کند تا اگر DNS سرور مشکل داشته باشد، دستور معطل نماند. نمونه خروجی:

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.0.2.11      .GPS.            1 u   25   64  377  12.345    0.123   0.456
+192.0.2.12      192.0.2.11       2 u   30   64  377  14.567   -0.045   0.321
 192.0.2.13      .INIT.          16 u    -   64    0   0.000    0.000   0.000

خواندن این جدول:

  • کاراکتر اول هر خط: * یعنی همین سرور به‌عنوان منبع اصلی انتخاب شده، + یعنی کاندیدای معتبر، - یا x یعنی کنار گذاشته شده، و فاصله خالی یعنی هنوز قابل استفاده نیست. اگر هیچ خطی * نداشت، سرور شما هنوز سینک نشده است.
  • st: همان Stratum. عدد ۱۶ یعنی آن منبع بی‌فایده است.
  • when / poll: چند ثانیه از آخرین پاسخ گذشته و فاصله فعلی بین پرس‌وجوها.
  • reach: عددی در مبنای هشت که وضعیت هشت تماس آخر را نشان می‌دهد. 377 یعنی هر هشت تماس موفق بوده (بهترین حالت) و 0 یعنی هیچ پاسخی نیامده — معمولاً نشانه بسته بودن UDP 123.
  • delay / offset / jitter: تأخیر رفت‌وبرگشت، اختلاف زمانی سیستم با آن سرور، و نوسان زمانی؛ همه بر حسب میلی‌ثانیه.

با chrony

chronyc sources -v
chronyc tracking

در خروجی tracking، مقدار System time همان اختلاف فعلی با مرجع و Leap status: Normal نشانه سلامت سینک است.

با timesyncd

timedatectl timesync-status

مشکلات رایج

  • reach صفر می‌ماند: پورت UDP 123 در جهت خروجی بسته است. با فایروال سرور و فایروال بالادستی چک کنید.
  • سرویس بالا نمی‌آید: احتمالاً سرویس دیگری هنوز فعال است؛ اگر آن سرویس ntpd یا chronyd باشد، پورت ۱۲۳ را هم گرفته است. با journalctl -u ntp -n 50 علت را ببینید.
  • ساعت درست است ولی برنامه زمان دیگری می‌دهد: مشکل از TimeZone لایه اپلیکیشن است، نه NTP.

سینک فوری، و چرا ntpdate دیگر توصیه نمی‌شود

در آموزش‌های قدیمی برای اصلاح فوری ساعت از این دستور استفاده می‌شد:

# منسوخ
sudo ntpdate -u pool.ntp.org

ابزار ntpdate سال‌هاست که توسط سازندگان خودش منسوخ اعلام شده و در بسیاری از توزیع‌های امروزی اصلاً نصب نیست (روی اوبونتو ۲۴.۰۴ فقط نسخه ntpsec-ntpdate باقی مانده است). ضمناً اگر ntpd یا chronyd در حال اجرا باشند و پورت ۱۲۳ را گرفته باشند، این دستور با خطای «the NTP socket is in use» شکست می‌خورد. معادل‌های درست امروزی:

# اگر chrony دارید (ساده‌ترین راه)
sudo chronyc makestep

# اگر ntpd دارید: سرویس را متوقف کنید، یکبار ست کنید، دوباره راه بیندازید
sudo systemctl stop ntp
sudo ntpd -gq
sudo systemctl start ntp

# اگر فقط timesyncd دارید
sudo systemctl restart systemd-timesyncd

در دستور ntpd -gq، سوئیچ -g اجازه می‌دهد اختلاف بزرگ‌تر از حد ایمنی هم — فقط یک‌بار، هنگام شروع — اصلاح شود و -q باعث می‌شود بعد از یک‌بار تنظیم، برنامه خارج شود.

افزایش دقت

با تنظیم فاصله پرس‌وجوها می‌توانید دقت را بالاتر ببرید (به قیمت ترافیک بیشتر روی سرورهای عمومی):

server 0.pool.ntp.org iburst minpoll 4 maxpoll 6

minpoll و maxpoll فاصله زمانی بین درخواست‌ها به سرور مرجع را تعیین می‌کنند و با توان دو بیان می‌شوند؛ یعنی مقدار ۴ برابر ۱۶ ثانیه و مقدار ۶ برابر ۶۴ ثانیه است. برای اکثر سرورها نیازی به دست زدن به این مقادیر نیست؛ اگر واقعاً دقت بالا می‌خواهید، بهتر است یک سرور NTP داخلی نزدیک به سرورهایتان راه بیندازید و همه را به آن وصل کنید.

یک هشدار مهم: سرورهای زمان گوگل (مثل time.google.com) از روش leap smear استفاده می‌کنند؛ یعنی ثانیه کبیسه را در طول ۲۴ ساعت پخش می‌کنند. این رفتار با سرورهای معمولی pool.ntp.org سازگار نیست و ترکیب این دو در یک فایل کانفیگ باعث می‌شود منابع همدیگر را رد کنند. یا همه منابع را از پول عمومی بگیرید یا همه را از یک ارائه‌دهنده smear.

سرور NTP داخلی و نکات امنیتی

اگر چند سرور دارید، منطقی است یکی را به‌عنوان سرور زمان داخلی تعریف کنید و بقیه از آن سینک شوند. در این حالت پورت UDP 123 را فقط برای شبکه داخلی باز کنید، نه برای همه:

# اوبونتو با ufw
sudo ufw allow from 192.168.0.0/24 to any port 123 proto udp

# AlmaLinux / Rocky با firewalld — محدود به همان ساب‌نت
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" service name="ntp" accept'
sudo firewall-cmd --reload

دستور ساده firewall-cmd --add-service=ntp را استفاده نکنید؛ آن دستور پورت را برای کل زون باز می‌کند و روی سرور دارای IP عمومی یعنی باز کردن سرویس زمان به روی کل اینترنت.

یک سرویس NTP که بدون محدودیت روی اینترنت باز باشد، می‌تواند به‌عنوان ابزار حمله تقویتی (amplification) علیه دیگران استفاده شود؛ مهاجم با یک بسته کوچک و آدرس جعلی، پاسخ بزرگی را به سمت قربانی هدایت می‌کند. به همین دلیل:

  • خطوط restrict default ... noquery را حذف نکنید؛ همین noquery است که پرس‌وجوهای مدیریتی و آماری از بیرون را می‌بندد و جلوی سوءاستفاده را می‌گیرد.
  • دستور قدیمی monlist که سال‌ها منبع اصلی این حملات بود، از ntpd نسخه ۴٫۲٫۷p26 به بعد حذف شده و در ntpsec اصلاً وجود ندارد. اگر روی سرور قدیمی خط disable monitor را دیدید بدانید که با وجود گزینه limited در restrict عملاً بی‌اثر است، چون آمارگیری برای اعمال محدودیت نرخ لازم است و روشن می‌ماند. تکیه اصلی شما باید روی noquery و فایروال باشد.
  • اگر سرور شما فقط مصرف‌کننده زمان است و به کسی سرویس نمی‌دهد، پورت ۱۲۳ را در جهت ورودی اصلاً باز نکنید. سینک شدن با سرورهای بیرونی فقط به ترافیک خروجی نیاز دارد.

نکته مهم روی سرور مجازی

روی سرور مجازی مبتنی بر KVM، سیستم‌عامل مهمان هسته و ساعت مستقل خودش را دارد و همه مراحل بالا عیناً کار می‌کند. اما روی کانتینر (OpenVZ، LXC یا داکر) ساعت متعلق به میزبان است و از داخل کانتینر قابل تغییر نیست؛ در این حالت نصب NTP بی‌فایده است و تلاش برای تنظیم ساعت با خطای دسترسی شکست می‌خورد. اگر ساعت چنین سروری اشتباه است، باید از ارائه‌دهنده بخواهید ساعت میزبان را اصلاح کند. توجه کنید که TimeZone در کانتینر قابل تنظیم است — چون فقط نمایش را عوض می‌کند، نه ساعت واقعی را.

آیا NTP زمان را جلو یا عقب می‌برد؟

NTP زمان سیستم را ترجیحاً تدریجی و کنترل‌شده اصلاح می‌کند. اگر اختلاف کوچک باشد (در ntpd کمتر از ۱۲۸ میلی‌ثانیه)، ساعت را با تغییر جزئی سرعت (slew) جلو یا عقب می‌برد تا هیچ پرشی رخ ندهد و سرویس‌های حساس به ترتیب زمان دچار مشکل نشوند؛ سقف این اصلاح تدریجی حدود ۵۰۰ قسمت در میلیون است، یعنی جبران هر ثانیه اختلاف حدود ۳۳ دقیقه طول می‌کشد.

اگر اختلاف بزرگ‌تر باشد، سرویس زمان را یکباره جابه‌جا می‌کند (step). و اگر اختلاف از ۱۰۰۰ ثانیه بیشتر باشد، ntpd به‌عنوان یک محافظ ایمنی از کار می‌ایستد و پیام خطا می‌دهد، مگر اینکه با سوئیچ -g اجرا شود. در chrony همین کار با دستور chronyc makestep یا خط makestep 1.0 3 در فایل کانفیگ انجام می‌شود.

نکته عملی: پرش ناگهانی ساعت به عقب می‌تواند دیتابیس‌ها و برنامه‌های حساس را گیج کند. اگر سرور شما مدت طولانی بدون سینک بوده، بهتر است اصلاح بزرگ اولیه را در بازه کم‌ترافیک و ترجیحاً با متوقف کردن سرویس‌های حساس انجام دهید.

غیرفعال کردن NTP

sudo systemctl disable --now ntp
sudo apt remove ntp -y

# اگر روی سیستم شما ntpsec نصب شده بود، بسته واقعی همین است
sudo systemctl disable --now ntpsec
sudo apt remove ntpsec -y

اما سرور را بدون هیچ منبع زمانی رها نکنید؛ ساعت داخلی به‌مرور دور می‌شود و همان مشکلات SSL و لاگ برمی‌گردد. اگر فقط می‌خواهید از ntpd به گزینه سبک‌تر برگردید، بلافاصله بعد از حذف، timesyncd را دوباره فعال کنید:

sudo systemctl enable --now systemd-timesyncd
sudo timedatectl set-ntp true

چک‌لیست نهایی

  • خروجی timedatectl منطقه زمانی درست، System clock synchronized: yes و RTC in local TZ: no را نشان می‌دهد.
  • فقط یک سرویس همگام‌سازی (timesyncd یا chrony یا ntpd/ntpsec) فعال است.
  • در ntpq -pn یا chronyc sources حداقل یک منبع با علامت * و reach 377 دیده می‌شود.
  • بسته tzdata به‌روز است.
  • مقدار date.timezone در php.ini تنظیم شده و php-fpm ری‌استارت شده است.
  • پورت UDP 123 در جهت ورودی فقط در صورت نیاز و فقط برای شبکه داخلی باز است.

با رعایت همین موارد، ساعت سرور دقیق و هماهنگ با UTC می‌ماند، خطاهای لاگ و دیتابیس و SSL ناشی از اختلاف زمانی از بین می‌رود و سرویس‌های توزیع‌شده و حساس به زمان بدون دردسر کار می‌کنند — یعنی همان چیزی که مدیریت سرور را حرفه‌ای و قابل اعتماد می‌کند.

ارسال نظر