#!/bin/bash
# 脚本文件名：setup_chrony_param.sh
# 修订版本：1.0
# 日期：2024/12/23
# 作者：Jack.liu
# 电子邮件：lqf@xlsys.cn
# 网址：www.xlsys.cn
# 此脚本用于关闭 ntpd 服务，检查并安装 chrony，
# 并根据命令行参数配置公网或内网 NTP 服务器同步时间。
# 注意：请在执行此脚本之前备份您的配置文件。

# 定义变量以存储阿里云的 NTP 服务器地址
ALIYUN_PUBLIC_NTP_SERVERS=(
    "ntp1.aliyun.com"
    "ntp2.aliyun.com"
    "ntp3.aliyun.com"
    "ntp4.aliyun.com"
)

ALIYUN_PRIVATE_NTP_SERVERS=(
    "222.246.130.5"
    "134.188.195.81"
    "134.188.195.82"
    "134.175.1.20"
    "134.160.1.20" # 替换为你的内网NTP服务器地址
)

# 检查并设置时区为 CST (UTC+8)
set_timezone_to_cst() {
    CURRENT_TIMEZONE=$(timedatectl status | grep 'Time zone:' | awk '{print $3}')
    
    if [[ "$CURRENT_TIMEZONE" != "Asia/Shanghai" ]]; then
        echo "检测到当前时区不是 CST (Asia/Shanghai)，正在更改为 CST..."

        # 检测系统版本
        if [ -f /etc/redhat-release ]; then
            # Red Hat/CentOS/Fedora
            sudo timedatectl set-timezone Asia/Shanghai
        elif [ -f /etc/debian_version ]; then
            # Debian/Ubuntu
            sudo timedatectl set-timezone Asia/Shanghai
        else
            echo "无法识别操作系统版本，请手动设置时区为 CST (Asia/Shanghai)."
            exit 1
        fi

        echo "时区已成功更改为 CST (Asia/Shanghai)."
    else
        echo "时区已经是 CST (Asia/Shanghai)，无需更改。"
    fi
}

# 检查是否已安装 chrony
check_chrony_installed() {
    if command -v chronyc &> /dev/null; then
        echo "检测到 chrony 已经安装。"
        return 0
    else
        echo "未检测到 chrony，需要进行安装。"
        return 1
    fi
}

# 安装 chrony
install_chrony() {
    echo "正在安装 chrony..."
    if [ -f /etc/redhat-release ]; then
        # Red Hat/CentOS/Fedora
        sudo yum install -y chrony || { echo "chrony 安装失败，请检查网络连接或yum源。"; exit 1; }
    elif [ -f /etc/debian_version ]; then
        # Debian/Ubuntu
        sudo apt-get update && sudo apt-get install -y chrony || { echo "chrony 安装失败，请检查网络连接或apt源。"; exit 1; }
    else
        echo "无法识别操作系统版本，请手动安装 chrony。"
        exit 1
    fi
}

# 停止并禁用 ntpd 服务
stop_ntpd() {
    echo "正在停止并禁用 ntpd 服务..."
    if systemctl list-unit-files --type=service | grep -q "^ntpd\.service"; then
        sudo systemctl stop ntpd
        sudo systemctl disable ntpd
    else
        echo "ntpd 服务未找到，跳过停止和禁用操作。"
    fi
}

# 备份原始的 chrony 配置文件
backup_chrony_conf() {
    CHRONY_CONF="/etc/chrony.conf"
    if [ -f /etc/debian_version ]; then
        # Debian/Ubuntu
        CHRONY_CONF="/etc/chrony/chrony.conf"
    fi
    BACKUP_CONF="${CHRONY_CONF}.bak.$(date +%F_%T)"
    echo "正在备份原始的 chrony 配置文件至 $BACKUP_CONF..."
    sudo cp "$CHRONY_CONF" "$BACKUP_CONF" || { echo "备份配置文件失败。"; exit 1; }
}

# 清空现有配置中的 server 行，并添加指定的时间服务器
configure_chrony_servers() {
    local servers=("$@")
    sudo sed -i '/^server /d' "$CHRONY_CONF" || { echo "编辑配置文件失败。"; exit 1; }  # 删除所有以 'server ' 开头的行
    for server in "${servers[@]}"; do
        echo "配置服务器: $server"
        echo "server $server iburst" | sudo tee -a "$CHRONY_CONF" > /dev/null || { echo "添加服务器到配置文件失败。"; exit 1; }
    done
}

# 确保 chronyd 服务正在运行并且设置为开机自启动
start_chronyd() {
    echo "正在启动并启用 chronyd 服务..."
    if [ -f /etc/redhat-release ]; then
        # Red Hat/CentOS/Fedora
        sudo systemctl start chronyd
        sudo systemctl enable chronyd
    elif [ -f /etc/debian_version ]; then
        # Debian/Ubuntu
        sudo systemctl start chrony
        sudo systemctl enable chrony
    else
        echo "无法识别操作系统版本，请手动启动和启用 chronyd 服务。"
        exit 1
    fi
}

# 重新启动 chronyd 以应用新配置并强制立即同步时间
restart_and_sync_chronyd() {
    echo "正在重启 chronyd 服务以应用新配置..."
    if [ -f /etc/redhat-release ]; then
        # Red Hat/CentOS/Fedora
        sudo systemctl restart chronyd || { echo "重启 chronyd 服务失败。"; exit 1; }
    elif [ -f /etc/debian_version ]; then
        # Debian/Ubuntu
        sudo systemctl restart chrony || { echo "重启 chrony 服务失败。"; exit 1; }
    else
        echo "无法识别操作系统版本，请手动重启 chronyd 服务。"
        exit 1
    fi
    
    echo "强制立即进行时间同步..."
    sudo chronyc -a makestep || { echo "时间同步失败。"; exit 1; }
}

# 显示当前使用的 NTP 源及同步状态
display_ntp_status() {
    echo -e "\n===================================="
    echo "当前配置的 NTP 源如下："
    chronyc sources -v
    echo "------------------------------------"
    echo "chronyd 同步状态："
    chronyc tracking
    echo "===================================="
    # 确认并显示当前系统时间和时区
    echo "------------------------------------"
    echo "当前系统时间和时区："
    timedatectl status | grep 'Local time\|Time zone'
    echo "====================================\n"
}

# 根据命令行参数选择配置
select_ntp_servers() {
    case "$1" in
        "public")
            configure_chrony_servers "${ALIYUN_PUBLIC_NTP_SERVERS[@]}"
            ;;
        "private")
            configure_chrony_servers "${ALIYUN_PRIVATE_NTP_SERVERS[@]}"
            ;;
        *)
            echo -e "\n\033[1;31m错误: 无效选项。\033[0m\n"
            display_usage
            exit 1
            ;;
    esac
}

# 显示使用说明
display_usage() {
    echo -e "\n\033[1;34m用法: $0 {public|private}\033[0m"
    echo "  public - 公网NTP同步"
    echo "  private - 内网NTP同步"
}

# 主程序逻辑
main() {
    # 设置时区为 CST
    set_timezone_to_cst

    # 检查并安装 chrony
    if ! check_chrony_installed; then
        install_chrony
    fi

    # 停止并禁用 ntpd 服务
    stop_ntpd

    # 备份配置文件
    backup_chrony_conf

    # 选择并配置 NTP 服务器
    select_ntp_servers "$1"

    # 启动 chronyd 服务
    start_chronyd

    # 重新启动 chronyd 以应用新配置并强制同步时间
    restart_and_sync_chronyd

    # 显示当前使用的 NTP 源及同步状态
    display_ntp_status

    echo -e "\n\033[1;32mchrony 设置已完成。chronyd 现在使用所选的 NTP 服务器。\033[0m\n"
}

# 运行主程序逻辑
if [ $# -eq 0 ]; then
    display_usage
else
    main "$1"
fi
