本文将详细介绍多种锁定Rocky Linux系统主版本的方法,防止意外升级到新版本。其中,有相当脚本内容由AI生成,并未得到完全验证,特别对于内部升级源的地址、管理脚本需要认真鉴别再使用。
2025.06 陕西·西安·秦汉通航公司
使用dnf版本锁定插件 安装dnf-plugin-versionlock # 安装版本锁定插件 sudo dnf install -y dnf-plugin-versionlock # 验证安装 dnf list installed | grep versionlock
锁定整个系统版本 # 方法1:锁定所有已安装的包 sudo dnf versionlock add '*'
锁定特定关键包 # 锁定核心系统包 sudo dnf versionlock add kernel* sudo dnf versionlock add systemd* sudo dnf versionlock add glibc* sudo dnf versionlock add rocky-release* # 查看已锁定的包 sudo dnf versionlock list
创建锁定脚本 # !/bin/bash # lock_version.sh - 锁定Rocky Linux主版本 LOCK_FILE="/etc/dnf/plugins/versionlock.list" BACKUP_DIR="/etc/dnf/plugins/backups" echo "=== 锁定Rocky Linux系统版本 ===" # 备份当前锁定列表 if [ ! -d "$BACKUP_DIR" ]; then sudo mkdir -p "$BACKUP_DIR" fi sudo cp "$LOCK_FILE" "$BACKUP_DIR/versionlock.list.$(date +%Y%m%d_%H%M%S)" # 锁定关键包 echo "锁定核心包..." sudo dnf versionlock add \ rocky-release \ kernel \ systemd \ glibc \ openssl \ bash \ dnf \ yum \ rpm # 锁定所有rocky-repo相关包 echo "锁定仓库相关包..." for pkg in $(dnf list installed "rocky*" | grep -v "Installed Packages" | awk '{print $1}'); do sudo dnf versionlock add "$pkg" done # 锁定所有当前已安装的包(可选,但更彻底) echo "正在锁定所有已安装包..." sudo dnf versionlock add '*' echo "版本锁定完成!" echo "当前锁定的包数量: $(sudo dnf versionlock list | wc -l)"
使用yum/dnf配置锁定 配置dnf排除列表 # 编辑dnf配置文件 sudo nano /etc/dnf/dnf.conf # 添加以下排除规则 [main] excludepkgs=kernel*, rocky-release*, systemd*, glibc*, openssl*
创建版本锁定配置文件 # 创建专门的排除配置文件 sudo tee /etc/dnf/conf.d/version-lock.conf << 'EOF' # Rocky Linux 主版本锁定配置 # 创建时间: $(date ) # 系统版本: $(cat /etc/rocky-release) [version-lock] # 排除所有可能导致主版本升级的包 excludepkgs=kernel*, rocky-release*, systemd*, initscripts, glibc*, openssl* # 排除所有仓库元数据更新 metadata_timer_sync=0 # 禁用自动更新 automatic=0 EOF
通过仓库配置锁定 禁用自动仓库更新 # 检查当前启用的仓库 sudo dnf repolist enabled # 禁用所有仓库的自动更新 sudo dnf config-manager --setopt=*.metadata_timer_sync=0 --save # 禁用特定仓库 sudo dnf config-manager --set-disabled rocky-devel sudo dnf config-manager --set-disabled rocky-extras
固定仓库版本 # 备份原始仓库配置 sudo cp -r /etc/yum.repos.d /etc/yum.repos.d.backup.$(date +%Y%m%d) # 修改所有rocky仓库配置,固定到当前版本 CURRENT_VERSION=$(rpm -q rocky-release | sed 's/.*release-//' | cut -d- -f1) sudo find /etc/yum.repos.d -name "*.repo" -exec sed -i \ "s/\$releasever/$CURRENT_VERSION/g" {} \; echo "已将仓库版本固定到: $CURRENT_VERSION"
创建自定义锁定仓库配置 # 创建只包含当前版本更新的仓库 sudo tee /etc/yum.repos.d/rocky-locked.repo << EOF # Rocky Linux 锁定版本仓库 # 仅包含当前主版本的更新 [rocky-baseos-locked] name=Rocky Linux \$releasever - BaseOS - Locked baseurl=http://dl.rockylinux.org/pub/rocky/9/BaseOS/\$basearch/os/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 metadata_expire=never [rocky-appstream-locked] name=Rocky Linux \$releasever - AppStream - Locked baseurl=http://dl.rockylinux.org/pub/rocky/9/AppStream/\$basearch/os/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 metadata_expire=never # 禁用其他所有仓库 [rocky*] enabled=0 EOF
使用systemd定时任务监控和防止升级 创建版本监控脚本 # !/bin/bash # monitor_version.sh - 监控并防止系统版本升级 LOG_FILE="/var/log/version-monitor.log" ALERT_EMAIL="admin@example.com" LOCK_FILE="/etc/.rocky-version-locked" # 记录日志 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" } # 检查是否有版本升级尝试 check_upgrade_attempt() { # 检查最近的dnf/yum日志 if tail -100 /var/log/dnf.log 2>/dev/null | grep -q "Upgrading.*rocky-release"; then log "检测到rocky-release升级尝试!" return 1 fi # 检查是否有新版本的仓库元数据 if [ -f /var/cache/dnf/rocky*.xml.gz ]; then TIMESTAMP=$(stat -c %Y /var/cache/dnf/rocky*.xml.gz 2>/dev/null | head -1) NOW=$(date +%s) if [ $((NOW - TIMESTAMP)) -lt 3600 ]; then log "检测到新的仓库元数据更新" return 1 fi fi return 0 } # 阻止升级操作 prevent_upgrade() { log "执行阻止升级操作" # 清除新的仓库缓存 sudo rm -f /var/cache/dnf/rocky*.xml.gz # 重置版本锁定 if [ -f /etc/dnf/plugins/versionlock.list ]; then # 重新锁定关键包 for pkg in rocky-release kernel systemd; do if ! grep -q "^$pkg" /etc/dnf/plugins/versionlock.list; then sudo dnf versionlock add "$pkg*" >/dev/null 2>&1 fi done fi # 发送警报 echo "检测到系统版本升级尝试!已阻止。" | mail -s "Rocky Linux版本升级警报" "$ALERT_EMAIL" } # 主函数 main() { log "开始版本监控检查" if check_upgrade_attempt; then log "未检测到升级尝试" else log "检测到升级尝试,正在阻止..." prevent_upgrade fi } # 执行主函数 main
创建systemd服务 # 创建服务文件 sudo tee /etc/systemd/system/version-protect.service << 'EOF' [Unit] Description=Rocky Linux Version Protection Service After=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/monitor_version.sh User=root Group=root [Install] WantedBy=multi-user.target EOF
创建systemd定时器 sudo tee /etc/systemd/system/version-protect.timer << 'EOF' [Unit] Description=Run version protection every 5 minutes [Timer] OnBootSec=5min OnUnitActiveSec=5min [Install] WantedBy=timers.target EOF
启用监控服务 sudo cp monitor_version.sh /usr/local/bin/ sudo chmod +x /usr/local/bin/monitor_version.sh sudo chmod 700 /usr/local/bin/monitor_version.sh sudo systemctl daemon-reload sudo systemctl enable version-protect.timer sudo systemctl start version-protect.timer # 查看状态 sudo systemctl status version-protect.timer
使用rpm包验证和防护 创建rpm包验证脚本 # !/bin/bash # verify_packages.sh - 验证关键包未被更改 KEY_PACKAGES="rocky-release kernel systemd glibc" DATABASE="/var/lib/rpm/Packages" VERIFY_LOG="/var/log/rpm-verify.log" echo "=== 关键包完整性验证 $(date) ===" | tee -a "$VERIFY_LOG" for pkg in $KEY_PACKAGES; do # 获取包名 FULL_PKG=$(rpm -qa | grep "^$pkg" | head -1) if [ -n "$FULL_PKG" ]; then echo "验证包: $FULL_PKG" | tee -a "$VERIFY_LOG" # 验证包完整性 rpm -V "$FULL_PKG" 2>&1 | tee -a "$VERIFY_LOG" if [ ${PIPESTATUS[0]} -ne 0 ]; then echo "警告: $FULL_PKG 已被修改!" | tee -a "$VERIFY_LOG" # 记录到系统日志 logger -t version-lock "关键包 $FULL_PKG 已被修改" fi fi done echo "=== 验证完成 ===" | tee -a "$VERIFY_LOG"
设置rpm验证定时任务 # 添加cron定时任务 sudo crontab -l > /tmp/cron.bak echo "0 */6 * * * /usr/local/bin/verify_packages.sh" | sudo crontab - # 或使用systemd timer sudo tee /etc/systemd/system/package-verify.timer << 'EOF' [Unit] Description=Verify critical packages every 6 hours [Timer] OnCalendar=*-*-* */6:00:00 [Install] WantedBy=timers.target EOF
网络安全防护 配置防火墙规则限制外部更新 # 允许必要的更新源,阻止其他 sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="152.19.134.142" port port="80" protocol="tcp" accept' sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="152.19.134.198" port port="80" protocol="tcp" accept' # 阻止其他所有到更新服务器的连接 sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" destination address="dl.rockylinux.org" drop' sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv6" destination address="dl.rockylinux.org" drop' # 重新加载防火墙 sudo firewall-cmd --reload
使用本地镜像仓库 # 设置本地镜像源 sudo tee /etc/yum.repos.d/rocky-local.repo << 'EOF' [local-baseos] name=Rocky Linux Local - BaseOS baseurl=file:///var/www/html/rocky/BaseOS enabled=1 gpgcheck=0 [local-appstream] name=Rocky Linux Local - AppStream baseurl=file:///var/www/html/rocky/AppStream enabled=1 gpgcheck=0 EOF # 禁用官方仓库 sudo dnf config-manager --set-disabled rocky*
完整版本锁定脚本 主锁定脚本 # !/bin/bash # rocky-version-lock.sh - 完整的Rocky Linux版本锁定脚本 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 日志文件 LOG_FILE="/var/log/rocky-version-lock.log" LOCK_FILE="/etc/.rocky-version-locked" # 记录日志 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 打印带颜色的消息 print_status() { echo -e "${GREEN}[✓]${NC} $1" | tee -a "$LOG_FILE" } print_warning() { echo -e "${YELLOW}[!]${NC} $1" | tee -a "$LOG_FILE" } print_error() { echo -e "${RED}[✗]${NC} $1" | tee -a "$LOG_FILE" } # 检查是否已锁定 check_lock() { if [ -f "$LOCK_FILE" ]; then CURRENT_VERSION=$(cat "$LOCK_FILE") log "系统已锁定到版本: $CURRENT_VERSION" return 0 fi return 1 } # 获取当前版本 get_current_version() { if [ -f /etc/rocky-release ]; then grep -oP 'release \K[0-9.]+' /etc/rocky-release else echo "unknown" fi } # 安装必要的工具 install_tools() { log "安装必要的工具..." # 安装dnf版本锁定插件 if ! rpm -q dnf-plugin-versionlock >/dev/null 2>&1; then dnf install -y dnf-plugin-versionlock 2>&1 | tee -a "$LOG_FILE" print_status "已安装dnf-plugin-versionlock" else print_status "dnf-plugin-versionlock 已安装" fi # 安装其他必要工具 dnf install -y yum-utils rpm-utils 2>&1 | tee -a "$LOG_FILE" } # 锁定核心包 lock_core_packages() { log "锁定核心系统包..." # 备份当前锁定列表 if [ -f /etc/dnf/plugins/versionlock.list ]; then cp /etc/dnf/plugins/versionlock.list /etc/dnf/plugins/versionlock.list.backup.$(date +%Y%m%d_%H%M%S) fi # 定义关键包列表 CORE_PACKAGES=" rocky-release kernel systemd glibc openssl bash dnf yum rpm initscripts grub2 firewalld NetworkManager " # 锁定每个关键包 for pkg in $CORE_PACKAGES; do # 获取完整的包名 FULL_PKG=$(rpm -qa | grep "^$pkg" | head -1) if [ -n "$FULL_PKG" ]; then dnf versionlock add "$FULL_PKG" 2>&1 | tee -a "$LOG_FILE" print_status "已锁定: $FULL_PKG" fi done # 锁定所有rocky*包 for pkg in $(rpm -qa | grep "^rocky"); do dnf versionlock add "$pkg" 2>&1 | tee -a "$LOG_FILE" done print_status "核心包锁定完成" } # 配置仓库锁定 lock_repositories() { log "配置仓库锁定..." # 备份原始仓库配置 REPO_BACKUP="/etc/yum.repos.d.backup.$(date +%Y%m%d_%H%M%S)" cp -r /etc/yum.repos.d "$REPO_BACKUP" print_status "仓库配置已备份到: $REPO_BACKUP" # 固定当前版本 CURRENT_VERSION=$(get_current_version) # 更新所有仓库配置,固定版本号 find /etc/yum.repos.d -name "*.repo" -type f | while read repo_file; do sed -i "s/\$releasever/$CURRENT_VERSION/g" "$repo_file" sed -i "s/\$basearch/x86_64/g" "$repo_file" # 固定架构 done # 禁用元数据自动更新 echo -e "[main]\ngpgcheck=1\ninstallonly_limit=3\nclean_requirements_on_remove=True\nmetadata_timer_sync=0" | tee /etc/dnf/dnf.conf print_status "仓库锁定配置完成" } # 创建防护服务 setup_protection_services() { log "设置防护服务..." # 创建监控脚本 cat > /usr/local/bin/rocky-monitor.sh << 'EOF' # !/bin/bash # 监控脚本 - 防止意外升级 LOCK_FILE="/etc/.rocky-version-locked" LOG="/var/log/rocky-monitor.log" check_upgrade() { # 检查是否有升级尝试 if journalctl -u dnf-makecache --since "1 hour ago" | grep -q "Metadata cache created"; then echo "[$(date)] 检测到仓库缓存更新" >> "$LOG" return 1 fi return 0 } if check_upgrade; then echo "[$(date)] 系统状态正常" >> "$LOG" else echo "[$(date)] 警告:检测到可能的升级尝试" >> "$LOG" # 可以添加通知逻辑 fi EOF chmod +x /usr/local/bin/rocky-monitor.sh # 创建systemd服务 cat > /etc/systemd/system/rocky-protect.service << EOF [Unit] Description=Rocky Linux Version Protection After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/rocky-monitor.sh User=root EOF cat > /etc/systemd/system/rocky-protect.timer << EOF [Unit] Description=Run version protection hourly [Timer] OnBootSec=15min OnUnitActiveSec=1h [Install] WantedBy=timers.target EOF systemctl daemon-reload systemctl enable rocky-protect.timer systemctl start rocky-protect.timer print_status "防护服务已设置" } # 主函数 main() { echo "=== Rocky Linux 版本锁定工具 ===" | tee -a "$LOG_FILE" # 检查root权限 if [ "$EUID" -ne 0 ]; then print_error "请使用root权限运行此脚本" exit 1 fi # 检查是否已锁定 if check_lock; then print_warning "系统已被锁定,是否重新锁定?(y/N)" read -r response case "$response" in [yY][eE][sS]|[yY]) print_status "继续锁定操作..." ;; *) print_status "退出" exit 0 ;; esac fi # 获取当前版本 CURRENT_VERSION=$(get_current_version) log "当前系统版本: $CURRENT_VERSION" # 执行锁定步骤 install_tools lock_core_packages lock_repositories setup_protection_services # 创建锁定标记 echo "$CURRENT_VERSION" > "$LOCK_FILE" chmod 600 "$LOCK_FILE" # 显示锁定状态 echo -e "\n${GREEN}=== 版本锁定完成 ===${NC}" | tee -a "$LOG_FILE" echo "锁定版本: $CURRENT_VERSION" | tee -a "$LOG_FILE" echo "锁定包数量: $(dnf versionlock list | wc -l)" | tee -a "$LOG_FILE" echo "日志文件: $LOG_FILE" | tee -a "$LOG_FILE" echo "锁定标记: $LOCK_FILE" | tee -a "$LOG_FILE" # 最终建议 echo -e "\n${YELLOW}=== 重要提示 ===${NC}" | tee -a "$LOG_FILE" echo "1. 定期检查系统安全更新" | tee -a "$LOG_FILE" echo "2. 需要升级时,运行解锁脚本" | tee -a "$LOG_FILE" echo "3. 监控日志文件: $LOG_FILE" | tee -a "$LOG_FILE" } # 解锁函数 unlock_version() { echo "=== 解锁系统版本 ===" # 移除版本锁定 dnf versionlock clear # 恢复原始仓库配置 if [ -d "/etc/yum.repos.d.backup."* ]; then LATEST_BACKUP=$(ls -td /etc/yum.repos.d.backup.* | head -1) if [ -n "$LATEST_BACKUP" ]; then rm -rf /etc/yum.repos.d cp -r "$LATEST_BACKUP" /etc/yum.repos.d print_status "已恢复仓库配置" fi fi # 删除锁定标记 rm -f "$LOCK_FILE" # 禁用防护服务 systemctl stop rocky-protect.timer systemctl disable rocky-protect.timer print_status "系统版本已解锁" } # 参数处理 case "$1" in lock) main ;; unlock) unlock_version ;; status) if check_lock; then print_status "系统已被锁定" else print_status "系统未锁定" fi ;; *) echo "使用方法: $0 {lock|unlock|status}" exit 1 ;; esac
使用脚本 # 赋予执行权限 chmod +x rocky-version-lock.sh # 锁定系统版本 sudo ./rocky-version-lock.sh lock # 查看状态 sudo ./rocky-version-lock.sh status # 解锁系统版本 sudo ./rocky-version-lock.sh unlock
手动验证和监控 创建验证报告脚本 # !/bin/bash # version-report.sh - 生成版本锁定报告 REPORT_FILE="/var/log/version-lock-report-$(date +%Y%m%d).txt" echo "=== Rocky Linux 版本锁定状态报告 ===" > "$REPORT_FILE" echo "生成时间: $(date)" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" # 1. 系统信息 echo "1. 系统信息:" >> "$REPORT_FILE" echo " Rocky版本: $(cat /etc/rocky-release 2>/dev/null || echo '未知')" >> "$REPORT_FILE" echo " 内核版本: $(uname -r)" >> "$REPORT_FILE" echo " 系统架构: $(uname -m)" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" # 2. 锁定包状态 echo "2. 版本锁定状态:" >> "$REPORT_FILE" echo " 锁定包数量: $(dnf versionlock list | wc -l 2>/dev/null || echo '未安装插件')" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" # 3. 关键包版本 echo "3. 关键包版本:" >> "$REPORT_FILE" for pkg in rocky-release kernel systemd glibc; do version=$(rpm -q "$pkg" 2>/dev/null || echo "未安装") echo " $pkg: $version" >> "$REPORT_FILE" done echo "" >> "$REPORT_FILE" # 4. 仓库状态 echo "4. 仓库配置:" >> "$REPORT_FILE" grep -h "^\[" /etc/yum.repos.d/*.repo 2>/dev/null | sed 's/^/ /' >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" # 5. 监控状态 echo "5. 监控服务状态:" >> "$REPORT_FILE" systemctl status rocky-protect.timer 2>/dev/null | grep -E "(Active|Loaded)" | sed 's/^/ /' >> "$REPORT_FILE" echo "报告已生成: $REPORT_FILE"
注意事项 安全更新处理 虽然锁定版本,但仍需关注安全更新:
# 定期检查安全更新(不自动安装) sudo dnf check-update --security # 手动应用关键安全更新 sudo dnf update --security --skip-broken
备份策略 # 备份关键配置 sudo tar -czf /backup/rocky-lock-backup-$(date +%Y%m%d).tar.gz \ /etc/yum.repos.d \ /etc/dnf/ \ /etc/systemd/system/rocky-*.service \ /etc/systemd/system/rocky-*.timer
解锁时的注意事项
解锁前确保系统有完整备份
逐步测试更新,避免大规模升级
监控系统稳定性
最佳实践 分层锁定策略
第一层:dnf versionlock 锁定核心包
第二层:仓库配置固定版本
第三层:监控服务防止意外更新
定期审计 # 每周生成报告 0 0 * * 0 /usr/local/bin/version-report.sh
文档记录
通过以上方法,您可以有效地锁定Rocky Linux系统的主版本,防止意外升级,同时保持系统的稳定性和安全性
参考内容
Docker稳定性保障:Ubuntu环境版本锁定方案
Ubuntu Linux内核版本升级指南:mainline