chrony-doctor.sh
· 4.5 KiB · Bash
Исходник
#!/usr/bin/env bash
VERSION="3.0"
SERVICE="chronyd"
CONF="/etc/chrony.conf"
LOGFILE="/tmp/chrony_doctor_$(date +%Y%m%d_%H%M%S).log"
if systemctl list-unit-files | grep -q chrony.service; then
SERVICE="chrony"
fi
pause(){
echo
read -p "按回车继续..."
}
header(){
clear
echo "========================================"
echo " Chrony Doctor v$VERSION"
echo "========================================"
echo
}
log(){
echo "$1" | tee -a "$LOGFILE"
}
# -----------------------------
# UDP 123 检测
# -----------------------------
check_ntp_port(){
log "NTP UDP 123 连通性检测"
log "--------------------------------"
SERVERS=$(grep ^server $CONF | awk '{print $2}')
for s in $SERVERS
do
echo "测试 $s ..."
timeout 2 bash -c "echo > /dev/udp/$s/123" 2>/dev/null
if [ $? -eq 0 ]; then
log "$s : UDP 123 可达"
else
log "$s : UDP 123 不可达"
fi
done
echo
}
# -----------------------------
# Chrony 服务
# -----------------------------
check_service(){
log "Chrony 服务状态"
log "--------------------------------"
STATUS=$(systemctl is-active $SERVICE)
if [ "$STATUS" = "active" ]; then
log "服务运行正常"
else
log "服务未运行"
fi
echo
}
# -----------------------------
# 时间同步状态
# -----------------------------
check_sync(){
log "系统时间同步状态"
log "--------------------------------"
timedatectl | tee -a "$LOGFILE"
echo
}
# -----------------------------
# Chrony tracking
# -----------------------------
check_tracking(){
log "Chrony Tracking"
log "--------------------------------"
TRACK=$(chronyc tracking)
echo "$TRACK" | tee -a "$LOGFILE"
OFFSET=$(echo "$TRACK" | grep "Last offset" | awk '{print $3}')
OFFSET_NUM=$(echo $OFFSET | tr -d 's')
echo
if command -v bc >/dev/null; then
if [[ $(echo "$OFFSET_NUM > 1" | bc) -eq 1 ]]; then
log "警告: 时间偏差超过 1 秒"
fi
fi
echo
}
# -----------------------------
# NTP sources
# -----------------------------
check_sources(){
log "NTP Sources"
log "--------------------------------"
chronyc sources -v | tee -a "$LOGFILE"
echo
}
# -----------------------------
# RTC检测
# -----------------------------
check_rtc(){
log "RTC 与系统时钟"
log "--------------------------------"
timedatectl | grep RTC | tee -a "$LOGFILE"
echo
}
# -----------------------------
# 防火墙检测
# -----------------------------
check_firewall(){
log "防火墙状态"
log "--------------------------------"
if systemctl is-active firewalld >/dev/null 2>&1; then
log "firewalld 正在运行"
firewall-cmd --list-ports | tee -a "$LOGFILE"
else
log "firewalld 未运行"
fi
echo
}
# -----------------------------
# 虚拟化检测
# -----------------------------
check_virtualization(){
log "虚拟化环境检测"
log "--------------------------------"
virt=$(systemd-detect-virt)
if [ "$virt" != "none" ]; then
log "当前运行在虚拟机: $virt"
log "虚拟机环境建议使用 chrony"
else
log "物理机环境"
fi
echo
}
# -----------------------------
# Chrony 配置
# -----------------------------
show_config(){
log "Chrony 配置"
log "--------------------------------"
grep -v '^#' $CONF | grep -v '^$' | tee -a "$LOGFILE"
echo
}
# -----------------------------
# 强制同步
# -----------------------------
force_sync(){
header
echo "执行时间同步..."
chronyc -a makestep
echo
pause
}
# -----------------------------
# 完整诊断
# -----------------------------
full_diagnose(){
header
echo "生成诊断报告..."
echo "日志文件: $LOGFILE"
echo
check_service
check_sync
check_tracking
check_sources
check_ntp_port
check_firewall
check_rtc
check_virtualization
show_config
echo
log "诊断完成"
pause
}
# -----------------------------
# 主菜单
# -----------------------------
menu(){
while true
do
header
echo "1 系统时间状态"
echo "2 Chrony 服务状态"
echo "3 Chrony Sources"
echo "4 Chrony Tracking"
echo "5 UDP 123 连通性检测"
echo "6 强制同步时间"
echo "7 防火墙检测"
echo "8 虚拟化环境检测"
echo "9 查看 Chrony 配置"
echo
echo "10 一键完整诊断"
echo
echo "0 退出"
echo
read -p "选择操作: " CHOICE
case $CHOICE in
1) timedatectl; pause ;;
2) systemctl status $SERVICE --no-pager; pause ;;
3) chronyc sources -v; pause ;;
4) chronyc tracking; pause ;;
5) check_ntp_port; pause ;;
6) force_sync ;;
7) check_firewall; pause ;;
8) check_virtualization; pause ;;
9) show_config; pause ;;
10) full_diagnose ;;
0) exit ;;
*) echo "无效选项"; sleep 1 ;;
esac
done
}
menu
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | VERSION="3.0" |
| 4 | SERVICE="chronyd" |
| 5 | CONF="/etc/chrony.conf" |
| 6 | LOGFILE="/tmp/chrony_doctor_$(date +%Y%m%d_%H%M%S).log" |
| 7 | |
| 8 | if systemctl list-unit-files | grep -q chrony.service; then |
| 9 | SERVICE="chrony" |
| 10 | fi |
| 11 | |
| 12 | pause(){ |
| 13 | echo |
| 14 | read -p "按回车继续..." |
| 15 | } |
| 16 | |
| 17 | header(){ |
| 18 | clear |
| 19 | echo "========================================" |
| 20 | echo " Chrony Doctor v$VERSION" |
| 21 | echo "========================================" |
| 22 | echo |
| 23 | } |
| 24 | |
| 25 | log(){ |
| 26 | echo "$1" | tee -a "$LOGFILE" |
| 27 | } |
| 28 | |
| 29 | # ----------------------------- |
| 30 | # UDP 123 检测 |
| 31 | # ----------------------------- |
| 32 | |
| 33 | check_ntp_port(){ |
| 34 | |
| 35 | log "NTP UDP 123 连通性检测" |
| 36 | log "--------------------------------" |
| 37 | |
| 38 | SERVERS=$(grep ^server $CONF | awk '{print $2}') |
| 39 | |
| 40 | for s in $SERVERS |
| 41 | do |
| 42 | echo "测试 $s ..." |
| 43 | timeout 2 bash -c "echo > /dev/udp/$s/123" 2>/dev/null |
| 44 | |
| 45 | if [ $? -eq 0 ]; then |
| 46 | log "$s : UDP 123 可达" |
| 47 | else |
| 48 | log "$s : UDP 123 不可达" |
| 49 | fi |
| 50 | done |
| 51 | |
| 52 | echo |
| 53 | } |
| 54 | |
| 55 | # ----------------------------- |
| 56 | # Chrony 服务 |
| 57 | # ----------------------------- |
| 58 | |
| 59 | check_service(){ |
| 60 | |
| 61 | log "Chrony 服务状态" |
| 62 | log "--------------------------------" |
| 63 | |
| 64 | STATUS=$(systemctl is-active $SERVICE) |
| 65 | |
| 66 | if [ "$STATUS" = "active" ]; then |
| 67 | log "服务运行正常" |
| 68 | else |
| 69 | log "服务未运行" |
| 70 | fi |
| 71 | |
| 72 | echo |
| 73 | } |
| 74 | |
| 75 | # ----------------------------- |
| 76 | # 时间同步状态 |
| 77 | # ----------------------------- |
| 78 | |
| 79 | check_sync(){ |
| 80 | |
| 81 | log "系统时间同步状态" |
| 82 | log "--------------------------------" |
| 83 | |
| 84 | timedatectl | tee -a "$LOGFILE" |
| 85 | |
| 86 | echo |
| 87 | } |
| 88 | |
| 89 | # ----------------------------- |
| 90 | # Chrony tracking |
| 91 | # ----------------------------- |
| 92 | |
| 93 | check_tracking(){ |
| 94 | |
| 95 | log "Chrony Tracking" |
| 96 | log "--------------------------------" |
| 97 | |
| 98 | TRACK=$(chronyc tracking) |
| 99 | echo "$TRACK" | tee -a "$LOGFILE" |
| 100 | |
| 101 | OFFSET=$(echo "$TRACK" | grep "Last offset" | awk '{print $3}') |
| 102 | OFFSET_NUM=$(echo $OFFSET | tr -d 's') |
| 103 | |
| 104 | echo |
| 105 | |
| 106 | if command -v bc >/dev/null; then |
| 107 | if [[ $(echo "$OFFSET_NUM > 1" | bc) -eq 1 ]]; then |
| 108 | log "警告: 时间偏差超过 1 秒" |
| 109 | fi |
| 110 | fi |
| 111 | |
| 112 | echo |
| 113 | } |
| 114 | |
| 115 | # ----------------------------- |
| 116 | # NTP sources |
| 117 | # ----------------------------- |
| 118 | |
| 119 | check_sources(){ |
| 120 | |
| 121 | log "NTP Sources" |
| 122 | log "--------------------------------" |
| 123 | |
| 124 | chronyc sources -v | tee -a "$LOGFILE" |
| 125 | |
| 126 | echo |
| 127 | } |
| 128 | |
| 129 | # ----------------------------- |
| 130 | # RTC检测 |
| 131 | # ----------------------------- |
| 132 | |
| 133 | check_rtc(){ |
| 134 | |
| 135 | log "RTC 与系统时钟" |
| 136 | log "--------------------------------" |
| 137 | |
| 138 | timedatectl | grep RTC | tee -a "$LOGFILE" |
| 139 | |
| 140 | echo |
| 141 | } |
| 142 | |
| 143 | # ----------------------------- |
| 144 | # 防火墙检测 |
| 145 | # ----------------------------- |
| 146 | |
| 147 | check_firewall(){ |
| 148 | |
| 149 | log "防火墙状态" |
| 150 | log "--------------------------------" |
| 151 | |
| 152 | if systemctl is-active firewalld >/dev/null 2>&1; then |
| 153 | log "firewalld 正在运行" |
| 154 | firewall-cmd --list-ports | tee -a "$LOGFILE" |
| 155 | else |
| 156 | log "firewalld 未运行" |
| 157 | fi |
| 158 | |
| 159 | echo |
| 160 | } |
| 161 | |
| 162 | # ----------------------------- |
| 163 | # 虚拟化检测 |
| 164 | # ----------------------------- |
| 165 | |
| 166 | check_virtualization(){ |
| 167 | |
| 168 | log "虚拟化环境检测" |
| 169 | log "--------------------------------" |
| 170 | |
| 171 | virt=$(systemd-detect-virt) |
| 172 | |
| 173 | if [ "$virt" != "none" ]; then |
| 174 | log "当前运行在虚拟机: $virt" |
| 175 | log "虚拟机环境建议使用 chrony" |
| 176 | else |
| 177 | log "物理机环境" |
| 178 | fi |
| 179 | |
| 180 | echo |
| 181 | } |
| 182 | |
| 183 | # ----------------------------- |
| 184 | # Chrony 配置 |
| 185 | # ----------------------------- |
| 186 | |
| 187 | show_config(){ |
| 188 | |
| 189 | log "Chrony 配置" |
| 190 | log "--------------------------------" |
| 191 | |
| 192 | grep -v '^#' $CONF | grep -v '^$' | tee -a "$LOGFILE" |
| 193 | |
| 194 | echo |
| 195 | } |
| 196 | |
| 197 | # ----------------------------- |
| 198 | # 强制同步 |
| 199 | # ----------------------------- |
| 200 | |
| 201 | force_sync(){ |
| 202 | |
| 203 | header |
| 204 | |
| 205 | echo "执行时间同步..." |
| 206 | |
| 207 | chronyc -a makestep |
| 208 | |
| 209 | echo |
| 210 | pause |
| 211 | } |
| 212 | |
| 213 | # ----------------------------- |
| 214 | # 完整诊断 |
| 215 | # ----------------------------- |
| 216 | |
| 217 | full_diagnose(){ |
| 218 | |
| 219 | header |
| 220 | |
| 221 | echo "生成诊断报告..." |
| 222 | echo "日志文件: $LOGFILE" |
| 223 | echo |
| 224 | |
| 225 | check_service |
| 226 | check_sync |
| 227 | check_tracking |
| 228 | check_sources |
| 229 | check_ntp_port |
| 230 | check_firewall |
| 231 | check_rtc |
| 232 | check_virtualization |
| 233 | show_config |
| 234 | |
| 235 | echo |
| 236 | log "诊断完成" |
| 237 | pause |
| 238 | } |
| 239 | |
| 240 | # ----------------------------- |
| 241 | # 主菜单 |
| 242 | # ----------------------------- |
| 243 | |
| 244 | menu(){ |
| 245 | |
| 246 | while true |
| 247 | do |
| 248 | |
| 249 | header |
| 250 | |
| 251 | echo "1 系统时间状态" |
| 252 | echo "2 Chrony 服务状态" |
| 253 | echo "3 Chrony Sources" |
| 254 | echo "4 Chrony Tracking" |
| 255 | echo "5 UDP 123 连通性检测" |
| 256 | echo "6 强制同步时间" |
| 257 | echo "7 防火墙检测" |
| 258 | echo "8 虚拟化环境检测" |
| 259 | echo "9 查看 Chrony 配置" |
| 260 | echo |
| 261 | echo "10 一键完整诊断" |
| 262 | echo |
| 263 | echo "0 退出" |
| 264 | echo |
| 265 | |
| 266 | read -p "选择操作: " CHOICE |
| 267 | |
| 268 | case $CHOICE in |
| 269 | |
| 270 | 1) timedatectl; pause ;; |
| 271 | 2) systemctl status $SERVICE --no-pager; pause ;; |
| 272 | 3) chronyc sources -v; pause ;; |
| 273 | 4) chronyc tracking; pause ;; |
| 274 | 5) check_ntp_port; pause ;; |
| 275 | 6) force_sync ;; |
| 276 | 7) check_firewall; pause ;; |
| 277 | 8) check_virtualization; pause ;; |
| 278 | 9) show_config; pause ;; |
| 279 | 10) full_diagnose ;; |
| 280 | 0) exit ;; |
| 281 | *) echo "无效选项"; sleep 1 ;; |
| 282 | |
| 283 | esac |
| 284 | |
| 285 | done |
| 286 | |
| 287 | } |
| 288 | |
| 289 | menu |
chrony-tool-v2.sh
· 4.9 KiB · Bash
Исходник
#!/usr/bin/env bash
# ============================
# Chrony 运维诊断工具 v2
# ============================
SERVICE="chronyd"
CONF="/etc/chrony.conf"
if systemctl list-unit-files | grep -q chrony.service; then
SERVICE="chrony"
fi
pause(){
echo
read -p "按回车返回菜单..."
}
header(){
clear
echo "======================================"
echo " Chrony 运维诊断工具 v2"
echo "======================================"
echo
}
# ----------------------------
# 基础信息
# ----------------------------
show_time(){
header
echo "系统时间"
echo "--------------------------------"
date
echo
timedatectl
pause
}
service_status(){
header
echo "Chrony 服务状态"
echo "--------------------------------"
systemctl status $SERVICE --no-pager
pause
}
# ----------------------------
# NTP信息
# ----------------------------
show_sources(){
header
echo "NTP Sources"
echo "--------------------------------"
chronyc sources -v
pause
}
show_tracking(){
header
echo "Chrony Tracking"
echo "--------------------------------"
chronyc tracking
pause
}
show_activity(){
header
echo "Chrony Activity"
echo "--------------------------------"
chronyc activity
pause
}
# ----------------------------
# 强制同步
# ----------------------------
force_sync(){
header
echo "尝试强制同步时间..."
echo
chronyc -a makestep
echo
echo "同步命令已执行"
pause
}
# ----------------------------
# 重启
# ----------------------------
restart_service(){
header
echo "重启 Chrony..."
echo
systemctl restart $SERVICE
echo "完成"
pause
}
# ----------------------------
# 修改NTP服务器
# ----------------------------
change_ntp(){
header
echo "当前 NTP server"
grep ^server $CONF
echo
read -p "输入新的 NTP 服务器: " NTP
if [ -z "$NTP" ]; then
echo "未输入"
pause
return
fi
cp $CONF ${CONF}.bak.$(date +%s)
sed -i '/^server/d' $CONF
echo "server $NTP iburst" >> $CONF
systemctl restart $SERVICE
echo
echo "已修改并重启 Chrony"
pause
}
# ----------------------------
# 推荐NTP
# ----------------------------
recommend_ntp(){
header
echo "推荐 NTP 服务器 (中国常用)"
echo "--------------------------------"
cat <<EOF
阿里云
ntp.aliyun.com
腾讯云
time1.cloud.tencent.com
time2.cloud.tencent.com
国家授时中心
ntp.ntsc.ac.cn
中国教育网
cn.ntp.org.cn
公网 pool
0.cn.pool.ntp.org
1.cn.pool.ntp.org
EOF
pause
}
# ----------------------------
# 健康检查
# ----------------------------
health_check(){
header
echo "Chrony 健康诊断报告"
echo "--------------------------------"
SERVICE_STATUS=$(systemctl is-active $SERVICE)
if [ "$SERVICE_STATUS" = "active" ]; then
echo "Chrony Service: OK"
else
echo "Chrony Service: ERROR"
fi
echo
SYNC=$(timedatectl | grep "System clock synchronized" | awk '{print $4}')
echo "System Clock Sync: $SYNC"
echo
TRACK=$(chronyc tracking)
OFFSET=$(echo "$TRACK" | grep "Last offset" | awk '{print $3}')
LEAP=$(echo "$TRACK" | grep "Leap status" | cut -d ':' -f2)
echo "Last Offset: $OFFSET"
echo "Leap Status: $LEAP"
echo
echo "Sources 状态"
echo "--------------------------------"
chronyc sources
echo
# offset判断
OFFSET_NUM=$(echo $OFFSET | tr -d 's')
if [[ $(echo "$OFFSET_NUM > 0.5" | bc 2>/dev/null) -eq 1 ]]; then
echo "警告: 偏差超过0.5秒"
fi
echo
echo "诊断建议"
echo "--------------------------------"
if [ "$SERVICE_STATUS" != "active" ]; then
echo "建议: 启动 chrony 服务"
fi
if [ "$SYNC" != "yes" ]; then
echo "建议: 检查 NTP 源或网络"
fi
echo
pause
}
# ----------------------------
# 完整报告
# ----------------------------
full_report(){
header
echo "Chrony 完整诊断报告"
echo "================================"
echo
echo "系统时间"
echo "--------------------------------"
date
echo
echo "timedatectl"
echo "--------------------------------"
timedatectl
echo
echo "tracking"
echo "--------------------------------"
chronyc tracking
echo
echo "sources"
echo "--------------------------------"
chronyc sources -v
echo
echo "activity"
echo "--------------------------------"
chronyc activity
echo
pause
}
# ----------------------------
# 主菜单
# ----------------------------
menu(){
while true
do
header
echo "1 查看系统时间"
echo "2 查看 Chrony 服务状态"
echo "3 查看 Sources"
echo "4 查看 Tracking"
echo "5 查看 Activity"
echo "6 强制同步时间"
echo "7 修改 NTP 服务器"
echo "8 重启 Chrony"
echo "9 推荐 NTP 服务器"
echo "10 Chrony 健康检查"
echo "11 完整诊断报告"
echo
echo "0 退出"
echo
read -p "选择操作: " CHOICE
case $CHOICE in
1) show_time ;;
2) service_status ;;
3) show_sources ;;
4) show_tracking ;;
5) show_activity ;;
6) force_sync ;;
7) change_ntp ;;
8) restart_service ;;
9) recommend_ntp ;;
10) health_check ;;
11) full_report ;;
0) exit ;;
*) echo "无效选项"; sleep 1 ;;
esac
done
}
menu
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | # ============================ |
| 4 | # Chrony 运维诊断工具 v2 |
| 5 | # ============================ |
| 6 | |
| 7 | SERVICE="chronyd" |
| 8 | CONF="/etc/chrony.conf" |
| 9 | |
| 10 | if systemctl list-unit-files | grep -q chrony.service; then |
| 11 | SERVICE="chrony" |
| 12 | fi |
| 13 | |
| 14 | pause(){ |
| 15 | echo |
| 16 | read -p "按回车返回菜单..." |
| 17 | } |
| 18 | |
| 19 | header(){ |
| 20 | clear |
| 21 | echo "======================================" |
| 22 | echo " Chrony 运维诊断工具 v2" |
| 23 | echo "======================================" |
| 24 | echo |
| 25 | } |
| 26 | |
| 27 | # ---------------------------- |
| 28 | # 基础信息 |
| 29 | # ---------------------------- |
| 30 | |
| 31 | show_time(){ |
| 32 | header |
| 33 | echo "系统时间" |
| 34 | echo "--------------------------------" |
| 35 | date |
| 36 | echo |
| 37 | timedatectl |
| 38 | pause |
| 39 | } |
| 40 | |
| 41 | service_status(){ |
| 42 | header |
| 43 | echo "Chrony 服务状态" |
| 44 | echo "--------------------------------" |
| 45 | systemctl status $SERVICE --no-pager |
| 46 | pause |
| 47 | } |
| 48 | |
| 49 | # ---------------------------- |
| 50 | # NTP信息 |
| 51 | # ---------------------------- |
| 52 | |
| 53 | show_sources(){ |
| 54 | header |
| 55 | echo "NTP Sources" |
| 56 | echo "--------------------------------" |
| 57 | chronyc sources -v |
| 58 | pause |
| 59 | } |
| 60 | |
| 61 | show_tracking(){ |
| 62 | header |
| 63 | echo "Chrony Tracking" |
| 64 | echo "--------------------------------" |
| 65 | chronyc tracking |
| 66 | pause |
| 67 | } |
| 68 | |
| 69 | show_activity(){ |
| 70 | header |
| 71 | echo "Chrony Activity" |
| 72 | echo "--------------------------------" |
| 73 | chronyc activity |
| 74 | pause |
| 75 | } |
| 76 | |
| 77 | # ---------------------------- |
| 78 | # 强制同步 |
| 79 | # ---------------------------- |
| 80 | |
| 81 | force_sync(){ |
| 82 | header |
| 83 | echo "尝试强制同步时间..." |
| 84 | echo |
| 85 | |
| 86 | chronyc -a makestep |
| 87 | |
| 88 | echo |
| 89 | echo "同步命令已执行" |
| 90 | pause |
| 91 | } |
| 92 | |
| 93 | # ---------------------------- |
| 94 | # 重启 |
| 95 | # ---------------------------- |
| 96 | |
| 97 | restart_service(){ |
| 98 | header |
| 99 | echo "重启 Chrony..." |
| 100 | echo |
| 101 | |
| 102 | systemctl restart $SERVICE |
| 103 | |
| 104 | echo "完成" |
| 105 | pause |
| 106 | } |
| 107 | |
| 108 | # ---------------------------- |
| 109 | # 修改NTP服务器 |
| 110 | # ---------------------------- |
| 111 | |
| 112 | change_ntp(){ |
| 113 | header |
| 114 | |
| 115 | echo "当前 NTP server" |
| 116 | grep ^server $CONF |
| 117 | echo |
| 118 | |
| 119 | read -p "输入新的 NTP 服务器: " NTP |
| 120 | |
| 121 | if [ -z "$NTP" ]; then |
| 122 | echo "未输入" |
| 123 | pause |
| 124 | return |
| 125 | fi |
| 126 | |
| 127 | cp $CONF ${CONF}.bak.$(date +%s) |
| 128 | |
| 129 | sed -i '/^server/d' $CONF |
| 130 | echo "server $NTP iburst" >> $CONF |
| 131 | |
| 132 | systemctl restart $SERVICE |
| 133 | |
| 134 | echo |
| 135 | echo "已修改并重启 Chrony" |
| 136 | pause |
| 137 | } |
| 138 | |
| 139 | # ---------------------------- |
| 140 | # 推荐NTP |
| 141 | # ---------------------------- |
| 142 | |
| 143 | recommend_ntp(){ |
| 144 | |
| 145 | header |
| 146 | |
| 147 | echo "推荐 NTP 服务器 (中国常用)" |
| 148 | echo "--------------------------------" |
| 149 | |
| 150 | cat <<EOF |
| 151 | |
| 152 | 阿里云 |
| 153 | ntp.aliyun.com |
| 154 | |
| 155 | 腾讯云 |
| 156 | time1.cloud.tencent.com |
| 157 | time2.cloud.tencent.com |
| 158 | |
| 159 | 国家授时中心 |
| 160 | ntp.ntsc.ac.cn |
| 161 | |
| 162 | 中国教育网 |
| 163 | cn.ntp.org.cn |
| 164 | |
| 165 | 公网 pool |
| 166 | 0.cn.pool.ntp.org |
| 167 | 1.cn.pool.ntp.org |
| 168 | |
| 169 | EOF |
| 170 | |
| 171 | pause |
| 172 | } |
| 173 | |
| 174 | # ---------------------------- |
| 175 | # 健康检查 |
| 176 | # ---------------------------- |
| 177 | |
| 178 | health_check(){ |
| 179 | |
| 180 | header |
| 181 | |
| 182 | echo "Chrony 健康诊断报告" |
| 183 | echo "--------------------------------" |
| 184 | |
| 185 | SERVICE_STATUS=$(systemctl is-active $SERVICE) |
| 186 | |
| 187 | if [ "$SERVICE_STATUS" = "active" ]; then |
| 188 | echo "Chrony Service: OK" |
| 189 | else |
| 190 | echo "Chrony Service: ERROR" |
| 191 | fi |
| 192 | |
| 193 | echo |
| 194 | |
| 195 | SYNC=$(timedatectl | grep "System clock synchronized" | awk '{print $4}') |
| 196 | |
| 197 | echo "System Clock Sync: $SYNC" |
| 198 | |
| 199 | echo |
| 200 | |
| 201 | TRACK=$(chronyc tracking) |
| 202 | |
| 203 | OFFSET=$(echo "$TRACK" | grep "Last offset" | awk '{print $3}') |
| 204 | LEAP=$(echo "$TRACK" | grep "Leap status" | cut -d ':' -f2) |
| 205 | |
| 206 | echo "Last Offset: $OFFSET" |
| 207 | echo "Leap Status: $LEAP" |
| 208 | |
| 209 | echo |
| 210 | |
| 211 | echo "Sources 状态" |
| 212 | echo "--------------------------------" |
| 213 | |
| 214 | chronyc sources |
| 215 | |
| 216 | echo |
| 217 | |
| 218 | # offset判断 |
| 219 | OFFSET_NUM=$(echo $OFFSET | tr -d 's') |
| 220 | |
| 221 | if [[ $(echo "$OFFSET_NUM > 0.5" | bc 2>/dev/null) -eq 1 ]]; then |
| 222 | echo "警告: 偏差超过0.5秒" |
| 223 | fi |
| 224 | |
| 225 | echo |
| 226 | echo "诊断建议" |
| 227 | echo "--------------------------------" |
| 228 | |
| 229 | if [ "$SERVICE_STATUS" != "active" ]; then |
| 230 | echo "建议: 启动 chrony 服务" |
| 231 | fi |
| 232 | |
| 233 | if [ "$SYNC" != "yes" ]; then |
| 234 | echo "建议: 检查 NTP 源或网络" |
| 235 | fi |
| 236 | |
| 237 | echo |
| 238 | pause |
| 239 | } |
| 240 | |
| 241 | # ---------------------------- |
| 242 | # 完整报告 |
| 243 | # ---------------------------- |
| 244 | |
| 245 | full_report(){ |
| 246 | |
| 247 | header |
| 248 | |
| 249 | echo "Chrony 完整诊断报告" |
| 250 | echo "================================" |
| 251 | echo |
| 252 | |
| 253 | echo "系统时间" |
| 254 | echo "--------------------------------" |
| 255 | date |
| 256 | echo |
| 257 | |
| 258 | echo "timedatectl" |
| 259 | echo "--------------------------------" |
| 260 | timedatectl |
| 261 | echo |
| 262 | |
| 263 | echo "tracking" |
| 264 | echo "--------------------------------" |
| 265 | chronyc tracking |
| 266 | echo |
| 267 | |
| 268 | echo "sources" |
| 269 | echo "--------------------------------" |
| 270 | chronyc sources -v |
| 271 | echo |
| 272 | |
| 273 | echo "activity" |
| 274 | echo "--------------------------------" |
| 275 | chronyc activity |
| 276 | echo |
| 277 | |
| 278 | pause |
| 279 | } |
| 280 | |
| 281 | # ---------------------------- |
| 282 | # 主菜单 |
| 283 | # ---------------------------- |
| 284 | |
| 285 | menu(){ |
| 286 | |
| 287 | while true |
| 288 | do |
| 289 | |
| 290 | header |
| 291 | |
| 292 | echo "1 查看系统时间" |
| 293 | echo "2 查看 Chrony 服务状态" |
| 294 | echo "3 查看 Sources" |
| 295 | echo "4 查看 Tracking" |
| 296 | echo "5 查看 Activity" |
| 297 | echo "6 强制同步时间" |
| 298 | echo "7 修改 NTP 服务器" |
| 299 | echo "8 重启 Chrony" |
| 300 | echo "9 推荐 NTP 服务器" |
| 301 | echo "10 Chrony 健康检查" |
| 302 | echo "11 完整诊断报告" |
| 303 | echo |
| 304 | echo "0 退出" |
| 305 | echo |
| 306 | |
| 307 | read -p "选择操作: " CHOICE |
| 308 | |
| 309 | case $CHOICE in |
| 310 | |
| 311 | 1) show_time ;; |
| 312 | 2) service_status ;; |
| 313 | 3) show_sources ;; |
| 314 | 4) show_tracking ;; |
| 315 | 5) show_activity ;; |
| 316 | 6) force_sync ;; |
| 317 | 7) change_ntp ;; |
| 318 | 8) restart_service ;; |
| 319 | 9) recommend_ntp ;; |
| 320 | 10) health_check ;; |
| 321 | 11) full_report ;; |
| 322 | 0) exit ;; |
| 323 | *) echo "无效选项"; sleep 1 ;; |
| 324 | |
| 325 | esac |
| 326 | |
| 327 | done |
| 328 | |
| 329 | } |
| 330 | |
| 331 | menu |
chrony-tool.sh
· 4.2 KiB · Bash
Исходник
#!/usr/bin/env bash
# ==============================
# Chrony 管理工具
# ==============================
CHRONY_CONF="/etc/chrony.conf"
SERVICE_NAME="chronyd"
if systemctl list-unit-files | grep -q chrony.service; then
SERVICE_NAME="chrony"
fi
pause(){
echo
read -p "按回车返回菜单..."
}
print_header(){
clear
echo "======================================"
echo " Chrony 时间同步管理工具"
echo "======================================"
echo
}
check_chrony_install(){
if ! command -v chronyc &>/dev/null; then
echo "未检测到 chrony,请先安装"
echo "CentOS/RHEL: yum install chrony"
echo "Debian/Ubuntu: apt install chrony"
exit 1
fi
}
# 当前时间
show_time(){
print_header
echo "系统当前时间"
echo "----------------------------"
date
echo
echo "timedatectl 信息"
echo "----------------------------"
timedatectl
pause
}
# Chrony服务状态
chrony_status(){
print_header
echo "Chrony 服务状态"
echo "----------------------------"
systemctl status $SERVICE_NAME --no-pager
pause
}
# Chrony源
show_sources(){
print_header
echo "NTP 来源服务器"
echo "----------------------------"
chronyc sources -v
pause
}
# Chrony tracking
show_tracking(){
print_header
echo "Chrony tracking 信息"
echo "----------------------------"
chronyc tracking
pause
}
# Chrony统计
show_activity(){
print_header
echo "Chrony 活动源"
echo "----------------------------"
chronyc activity
pause
}
# 强制同步
force_sync(){
print_header
echo "尝试立即同步时间..."
echo
chronyc -a makestep
echo
echo "同步完成"
pause
}
# 重启服务
restart_chrony(){
print_header
echo "重启 Chrony 服务..."
echo
sudo systemctl restart $SERVICE_NAME
echo "完成"
pause
}
# 查看配置
show_config(){
print_header
echo "当前 chrony.conf"
echo "----------------------------"
cat $CHRONY_CONF
pause
}
# 修改NTP服务器
modify_ntp(){
print_header
echo "当前 NTP server 配置"
echo "----------------------------"
grep ^server $CHRONY_CONF
echo
read -p "输入新的 NTP 服务器 (例如 ntp.aliyun.com): " ntpserver
if [ -z "$ntpserver" ]; then
echo "未输入"
pause
return
fi
sudo cp $CHRONY_CONF ${CHRONY_CONF}.bak.$(date +%s)
sudo sed -i '/^server/d' $CHRONY_CONF
echo "server $ntpserver iburst" | sudo tee -a $CHRONY_CONF >/dev/null
echo
echo "配置已更新"
echo "正在重启 chrony..."
sudo systemctl restart $SERVICE_NAME
echo "完成"
pause
}
# 综合检测
full_check(){
print_header
echo "系统时间"
echo "----------------------------"
date
echo
echo "timedatectl"
echo "----------------------------"
timedatectl
echo
echo "Chrony tracking"
echo "----------------------------"
chronyc tracking
echo
echo "Chrony sources"
echo "----------------------------"
chronyc sources -v
echo
echo "Chrony activity"
echo "----------------------------"
chronyc activity
pause
}
menu(){
while true
do
print_header
echo "1 查看系统时间"
echo "2 查看 Chrony 服务状态"
echo "3 查看 NTP 来源 (sources)"
echo "4 查看 Chrony tracking"
echo "5 查看 Chrony activity"
echo "6 强制同步时间"
echo "7 查看 chrony.conf"
echo "8 修改 NTP 服务器"
echo "9 重启 Chrony"
echo "10 综合检测"
echo
echo "0 退出"
echo
read -p "请选择操作: " choice
case $choice in
1) show_time ;;
2) chrony_status ;;
3) show_sources ;;
4) show_tracking ;;
5) show_activity ;;
6) force_sync ;;
7) show_config ;;
8) modify_ntp ;;
9) restart_chrony ;;
10) full_check ;;
0) exit ;;
*) echo "无效选项"; sleep 1 ;;
esac
done
}
check_chrony_install
menu
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | # ============================== |
| 4 | # Chrony 管理工具 |
| 5 | # ============================== |
| 6 | |
| 7 | CHRONY_CONF="/etc/chrony.conf" |
| 8 | SERVICE_NAME="chronyd" |
| 9 | |
| 10 | if systemctl list-unit-files | grep -q chrony.service; then |
| 11 | SERVICE_NAME="chrony" |
| 12 | fi |
| 13 | |
| 14 | pause(){ |
| 15 | echo |
| 16 | read -p "按回车返回菜单..." |
| 17 | } |
| 18 | |
| 19 | print_header(){ |
| 20 | clear |
| 21 | echo "======================================" |
| 22 | echo " Chrony 时间同步管理工具" |
| 23 | echo "======================================" |
| 24 | echo |
| 25 | } |
| 26 | |
| 27 | check_chrony_install(){ |
| 28 | if ! command -v chronyc &>/dev/null; then |
| 29 | echo "未检测到 chrony,请先安装" |
| 30 | echo "CentOS/RHEL: yum install chrony" |
| 31 | echo "Debian/Ubuntu: apt install chrony" |
| 32 | exit 1 |
| 33 | fi |
| 34 | } |
| 35 | |
| 36 | # 当前时间 |
| 37 | show_time(){ |
| 38 | print_header |
| 39 | echo "系统当前时间" |
| 40 | echo "----------------------------" |
| 41 | date |
| 42 | echo |
| 43 | echo "timedatectl 信息" |
| 44 | echo "----------------------------" |
| 45 | timedatectl |
| 46 | pause |
| 47 | } |
| 48 | |
| 49 | # Chrony服务状态 |
| 50 | chrony_status(){ |
| 51 | print_header |
| 52 | echo "Chrony 服务状态" |
| 53 | echo "----------------------------" |
| 54 | systemctl status $SERVICE_NAME --no-pager |
| 55 | pause |
| 56 | } |
| 57 | |
| 58 | # Chrony源 |
| 59 | show_sources(){ |
| 60 | print_header |
| 61 | echo "NTP 来源服务器" |
| 62 | echo "----------------------------" |
| 63 | chronyc sources -v |
| 64 | pause |
| 65 | } |
| 66 | |
| 67 | # Chrony tracking |
| 68 | show_tracking(){ |
| 69 | print_header |
| 70 | echo "Chrony tracking 信息" |
| 71 | echo "----------------------------" |
| 72 | chronyc tracking |
| 73 | pause |
| 74 | } |
| 75 | |
| 76 | # Chrony统计 |
| 77 | show_activity(){ |
| 78 | print_header |
| 79 | echo "Chrony 活动源" |
| 80 | echo "----------------------------" |
| 81 | chronyc activity |
| 82 | pause |
| 83 | } |
| 84 | |
| 85 | # 强制同步 |
| 86 | force_sync(){ |
| 87 | print_header |
| 88 | echo "尝试立即同步时间..." |
| 89 | echo |
| 90 | |
| 91 | chronyc -a makestep |
| 92 | |
| 93 | echo |
| 94 | echo "同步完成" |
| 95 | pause |
| 96 | } |
| 97 | |
| 98 | # 重启服务 |
| 99 | restart_chrony(){ |
| 100 | print_header |
| 101 | echo "重启 Chrony 服务..." |
| 102 | echo |
| 103 | |
| 104 | sudo systemctl restart $SERVICE_NAME |
| 105 | |
| 106 | echo "完成" |
| 107 | pause |
| 108 | } |
| 109 | |
| 110 | # 查看配置 |
| 111 | show_config(){ |
| 112 | print_header |
| 113 | echo "当前 chrony.conf" |
| 114 | echo "----------------------------" |
| 115 | cat $CHRONY_CONF |
| 116 | pause |
| 117 | } |
| 118 | |
| 119 | # 修改NTP服务器 |
| 120 | modify_ntp(){ |
| 121 | print_header |
| 122 | echo "当前 NTP server 配置" |
| 123 | echo "----------------------------" |
| 124 | grep ^server $CHRONY_CONF |
| 125 | echo |
| 126 | |
| 127 | read -p "输入新的 NTP 服务器 (例如 ntp.aliyun.com): " ntpserver |
| 128 | |
| 129 | if [ -z "$ntpserver" ]; then |
| 130 | echo "未输入" |
| 131 | pause |
| 132 | return |
| 133 | fi |
| 134 | |
| 135 | sudo cp $CHRONY_CONF ${CHRONY_CONF}.bak.$(date +%s) |
| 136 | |
| 137 | sudo sed -i '/^server/d' $CHRONY_CONF |
| 138 | |
| 139 | echo "server $ntpserver iburst" | sudo tee -a $CHRONY_CONF >/dev/null |
| 140 | |
| 141 | echo |
| 142 | echo "配置已更新" |
| 143 | echo "正在重启 chrony..." |
| 144 | |
| 145 | sudo systemctl restart $SERVICE_NAME |
| 146 | |
| 147 | echo "完成" |
| 148 | pause |
| 149 | } |
| 150 | |
| 151 | # 综合检测 |
| 152 | full_check(){ |
| 153 | print_header |
| 154 | echo "系统时间" |
| 155 | echo "----------------------------" |
| 156 | date |
| 157 | echo |
| 158 | |
| 159 | echo "timedatectl" |
| 160 | echo "----------------------------" |
| 161 | timedatectl |
| 162 | echo |
| 163 | |
| 164 | echo "Chrony tracking" |
| 165 | echo "----------------------------" |
| 166 | chronyc tracking |
| 167 | echo |
| 168 | |
| 169 | echo "Chrony sources" |
| 170 | echo "----------------------------" |
| 171 | chronyc sources -v |
| 172 | echo |
| 173 | |
| 174 | echo "Chrony activity" |
| 175 | echo "----------------------------" |
| 176 | chronyc activity |
| 177 | pause |
| 178 | } |
| 179 | |
| 180 | menu(){ |
| 181 | while true |
| 182 | do |
| 183 | print_header |
| 184 | |
| 185 | echo "1 查看系统时间" |
| 186 | echo "2 查看 Chrony 服务状态" |
| 187 | echo "3 查看 NTP 来源 (sources)" |
| 188 | echo "4 查看 Chrony tracking" |
| 189 | echo "5 查看 Chrony activity" |
| 190 | echo "6 强制同步时间" |
| 191 | echo "7 查看 chrony.conf" |
| 192 | echo "8 修改 NTP 服务器" |
| 193 | echo "9 重启 Chrony" |
| 194 | echo "10 综合检测" |
| 195 | echo |
| 196 | echo "0 退出" |
| 197 | echo |
| 198 | read -p "请选择操作: " choice |
| 199 | |
| 200 | case $choice in |
| 201 | 1) show_time ;; |
| 202 | 2) chrony_status ;; |
| 203 | 3) show_sources ;; |
| 204 | 4) show_tracking ;; |
| 205 | 5) show_activity ;; |
| 206 | 6) force_sync ;; |
| 207 | 7) show_config ;; |
| 208 | 8) modify_ntp ;; |
| 209 | 9) restart_chrony ;; |
| 210 | 10) full_check ;; |
| 211 | 0) exit ;; |
| 212 | *) echo "无效选项"; sleep 1 ;; |
| 213 | esac |
| 214 | done |
| 215 | } |
| 216 | |
| 217 | check_chrony_install |
| 218 | menu |