Operations 9 min read

One-Command Chrony Setup: Automate Precise NTP Sync on CentOS, Ubuntu, and CTyunOS

This guide explains why accurate server time is critical, compares ntpd with Chrony, and provides a single‑command script that automatically detects the OS, disables old ntpd services, installs Chrony, configures public or private NTP servers, and verifies synchronization across CentOS, Ubuntu, and CTyunOS.

Xiao Liu Lab
Xiao Liu Lab
Xiao Liu Lab
One-Command Chrony Setup: Automate Precise NTP Sync on CentOS, Ubuntu, and CTyunOS

Why Time Synchronization Matters

In distributed systems, log analysis, security auditing, and even financial transactions require highly consistent server clocks; a few seconds drift can scramble logs, cause Kubernetes nodes to disappear, or trigger security alerts.

Chrony vs. ntpd

Traditional ntpd is being replaced by the lighter, faster‑converging Chrony, but manual installation, configuration, and switching of NTP sources are cumbersome.

Script Core Features

Automatically detects the operating system (CentOS, Ubuntu, or CTyunOS) and selects the appropriate Chrony configuration file and service name.

Stops and disables any existing ntpd service.

Installs Chrony using yum or apt as appropriate.

Supports one‑click switching between public Alibaba Cloud NTP servers and private VPC NTP servers.

Backs up the original Chrony configuration safely.

Forces an immediate time step to achieve instant synchronization.

Outputs a clear status report showing NTP source health, synchronization state, and current system time zone.

Usage (Super Simple)

# Download the script (saved as setup_chrony_param.sh)
chmod +x setup_chrony_param.sh

# Public environment (e.g., regular cloud server)
sudo ./setup_chrony_param.sh public

# Private environment (recommended for lower latency and higher precision)
sudo ./setup_chrony_param.sh private

Note: Private NTP addresses work only inside an Alibaba Cloud VPC and can achieve millisecond‑level accuracy.

Full Script (Modify Private Server Addresses as Needed)

#!/bin/bash
# Script file: setup_chrony_param.sh
# Version: 1.1 (bug‑fix)
# Date: 2025/11/08
# Author: Jack.liu
# Email: [email protected]
# URL: www.xlsys.cn
# Supported: RHEL/CentOS/Fedora, Debian/Ubuntu, CTyunOS

set -e

ALIYUN_PUBLIC_NTP_SERVERS=(
    "ntp1.aliyun.com"
    "ntp2.aliyun.com"
    "ntp3.aliyun.com"
    "ntp4.aliyun.com"
)

ALIYUN_PRIVATE_NTP_SERVERS=(
    "222.22.120.52"
    "134.144.144.81"
    "132.155.166.82"
    "136.153.11.220"
    "132.108.11.220"
)

CHRONY_CONF=""
CHRONY_SERVICE=""

detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS_ID="${ID,,}"
    else
        echo "Unable to read /etc/os-release, cannot detect OS."
        exit 1
    fi
    case "$OS_ID" in
        *centos*|*rhel*|*rocky*|*almalinux*|*ctyunos*)
            CHRONY_CONF="/etc/chrony.conf"
            CHRONY_SERVICE="chronyd"
            PKG_MANAGER="yum"
            ;;
        *debian*|*ubuntu*)
            CHRONY_CONF="/etc/chrony/chrony.conf"
            CHRONY_SERVICE="chrony"
            PKG_MANAGER="apt"
            ;;
        *)
            echo "Unsupported OS: $OS_ID"
            exit 1
            ;;
    esac
}

set_timezone_to_cst() {
    CURRENT_TIMEZONE=$(timedatectl show --property=Timezone --value)
    if [[ "$CURRENT_TIMEZONE" != "Asia/Shanghai" ]]; then
        echo "Current timezone is not CST, setting to Asia/Shanghai..."
        sudo timedatectl set-timezone Asia/Shanghai
        echo "Timezone set to CST (Asia/Shanghai)."
    else
        echo "Timezone already CST (Asia/Shanghai), no change needed."
    fi
}

check_chrony_installed() {
    command -v chronyc >/dev/null
}

install_chrony() {
    echo "Installing chrony..."
    if [[ "$PKG_MANAGER" == "yum" ]]; then
        sudo yum install -y chrony
    elif [[ "$PKG_MANAGER" == "apt" ]]; then
        sudo apt-get update
        sudo apt-get install -y chrony
    fi
}

stop_ntpd() {
    echo "Stopping and disabling ntpd/ntp services..."
    for svc in ntpd ntp; do
        if systemctl is-active --quiet "$svc"; then
            sudo systemctl stop "$svc"
            sudo systemctl disable "$svc"
        fi
    done
    echo "ntpd/ntp services handled."
}

backup_chrony_conf() {
    backup_file="${CHRONY_CONF}.bak.$(date +%F_%H%M%S)"
    echo "Backing up config to $backup_file..."
    sudo cp "$CHRONY_CONF" "$backup_file"
}

configure_chrony_servers() {
    local servers=("$@")
    echo "Clearing existing server entries and adding new ones..."
    sudo sed -i '/^server /d' "$CHRONY_CONF"
    for s in "${servers[@]}"; do
        echo "server $s iburst" | sudo tee -a "$CHRONY_CONF" >/dev/null
    done
}

start_chronyd() {
    echo "Starting and enabling $CHRONY_SERVICE service..."
    sudo systemctl start "$CHRONY_SERVICE"
    sudo systemctl enable "$CHRONY_SERVICE"
}

restart_and_sync_chronyd() {
    echo "Restarting $CHRONY_SERVICE service..."
    sudo systemctl restart "$CHRONY_SERVICE"
    echo "Forcing time sync..."
    sudo chronyc -a makestep
}

display_ntp_status() {
    echo -e "
===================================="
    echo "NTP source status:"
    chronyc sources -v
    echo "------------------------------------"
    echo "Sync status:"
    chronyc tracking
    echo "------------------------------------"
    echo "System time and timezone:"
    timedatectl status | grep -E 'Local time|Time zone'
    echo -e "====================================
"
}

select_ntp_servers() {
    case "$1" in
        public)
            configure_chrony_servers "${ALIYUN_PUBLIC_NTP_SERVERS[@]}"
            ;;
        private)
            configure_chrony_servers "${ALIYUN_PRIVATE_NTP_SERVERS[@]}"
            ;;
        *)
            echo -e "
\033[1;31mError: Invalid option.\033[0m
"
            display_usage
            exit 1
            ;;
    esac
}

display_usage() {
    echo -e "
\033[1;34mUsage: $0 {public|private}\033[0m"
    echo "  public  - Use Alibaba Cloud public NTP servers"
    echo "  private - Use private VPC NTP servers"
}

main() {
    detect_os
    set_timezone_to_cst
    if ! check_chrony_installed; then
        install_chrony
    fi
    stop_ntpd
    backup_chrony_conf
    select_ntp_servers "$1"
    start_chronyd
    restart_and_sync_chronyd
    display_ntp_status
    echo -e "
\033[1;32m✅ Chrony configuration completed!\033[0m
"
}

if [[ $# -ne 1 ]]; then
    display_usage
    exit 1
else
    main "$1"
fi

Feedback

“Previously we had to edit chrony.conf manually for every deployment; now a single command handles everything, even new interns can run it!” – SRE engineer at a fintech company.

Chrony setup illustration
Chrony setup illustration
LinuxsysadminNTPtime synchronizationchrony
Xiao Liu Lab
Written by

Xiao Liu Lab

An operations lab passionate about server tinkering 🔬 Sharing automation scripts, high-availability architecture, alert optimization, and incident reviews. Using technology to reduce overtime and experience to avoid major pitfalls. Follow me for easier, more reliable operations!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.