#!/bin/bash # install_patch_system.sh - 补丁管理系统安装脚本 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INSTALL_DIR="/opt/patch-management" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"; } info() { log "INFO: $1"; } error() { log "ERROR: $1"; exit 1; } warn() { log "WARNING: $1"; } # 检测是否在Docker容器中运行 is_docker_environment() { # 检查多种Docker环境标识 if [[ -f /.dockerenv ]]; then return 0 fi if grep -q docker /proc/1/cgroup 2>/dev/null; then return 0 fi if grep -q lxc /proc/1/cgroup 2>/dev/null; then return 0 fi if [[ -n "${container:-}" ]]; then return 0 fi if [[ -n "${DOCKER_CONTAINER:-}" ]]; then return 0 fi # 检查容器相关的环境变量组合 local env_vars=( "HOSTNAME" "HOME" "USER" ) for var in "${env_vars[@]}"; do if [[ -n "${!var:-}" ]] && [[ "${!var}" =~ ^[a-f0-9]{12,}$ ]]; then # 检查环境变量值是否像容器ID if [[ ${!var} =~ ^[a-f0-9]{12,64}$ ]]; then return 0 fi fi done return 1 } # 获取适当的命令前缀(在Docker中使用空前缀,否则使用sudo) get_cmd_prefix() { if is_docker_environment; then echo "" else echo "sudo" fi } install_dependencies() { info "安装系统依赖..." local sudo_prefix sudo_prefix=$(get_cmd_prefix) if command -v apt-get >/dev/null 2>&1; then # Debian/Ubuntu $sudo_prefix apt-get update $sudo_prefix apt-get install -y tar gzip jq coreutils findutils util-linux bc elif command -v yum >/dev/null 2>&1; then # CentOS/RHEL $sudo_prefix yum install -y tar gzip jq coreutils findutils util-linux bc else warn "无法自动安装依赖,请手动安装: tar, gzip, jq, coreutils, findutils, util-linux, bc" fi # 安装GPG(用于签名验证) if command -v apt-get >/dev/null 2>&1; then $sudo_prefix apt-get install -y gnupg elif command -v yum >/dev/null 2>&1; then $sudo_prefix yum install -y gnupg fi } create_directories() { info "创建目录结构..." local sudo_prefix sudo_prefix=$(get_cmd_prefix) $sudo_prefix mkdir -p "$INSTALL_DIR" $sudo_prefix mkdir -p "/var/backups/patch" $sudo_prefix mkdir -p "/var/log/patch_system" $sudo_prefix mkdir -p "/etc/patch/keys" # 设置权限 $sudo_prefix chmod 755 "$INSTALL_DIR" $sudo_prefix chmod 755 "/var/backups/patch" $sudo_prefix chmod 755 "/var/log/patch_system" $sudo_prefix chmod 700 "/etc/patch/keys" } install_scripts() { info "安装脚本文件..." local sudo_prefix sudo_prefix=$(get_cmd_prefix) # 复制脚本文件, 存在则覆盖 $sudo_prefix cp --force "$SCRIPT_DIR/patch_generator.sh" "$INSTALL_DIR/" $sudo_prefix cp --force "$SCRIPT_DIR/patch_fnc.sh" "$INSTALL_DIR/" $sudo_prefix cp --force "$SCRIPT_DIR/patch_applier.sh" "$INSTALL_DIR/" $sudo_prefix cp --force "$SCRIPT_DIR/patch_rollback.sh" "$INSTALL_DIR/" $sudo_prefix cp --force "$SCRIPT_DIR/patch_verifier.sh" "$INSTALL_DIR/" $sudo_prefix cp --force "$SCRIPT_DIR/patch_workflow.sh" "$INSTALL_DIR/" $sudo_prefix cp --force "$SCRIPT_DIR/patch_config.sh" "$INSTALL_DIR/" info "脚本文件已安装在: $INSTALL_DIR/" # 设置执行权限 $sudo_prefix chmod +x "$INSTALL_DIR"/*.sh # 创建符号链接 $sudo_prefix ln -sf "$INSTALL_DIR/patch_workflow.sh" "/usr/local/bin/patch-mgmt" info "符号链接已创建: /usr/local/bin/patch-mgmt" } setup_cron() { info "设置定时任务..." if is_docker_environment; then info "Docker环境,跳过系统定时任务设置" info "如需定时任务,请考虑使用宿主机的crontab或Docker运行参数" return 0 fi local sudo_prefix sudo_prefix=$(get_cmd_prefix) local cron_job="0 2 * * * $INSTALL_DIR/patch_verifier.sh /opt/patches batch > /var/log/patch_system/batch_verify.log 2>&1" if ! crontab -l 2>/dev/null | grep -q "patch_verifier.sh"; then (crontab -l 2>/dev/null; echo "$cron_job") | crontab - info "定时任务已添加" else info "定时任务已存在" fi } generate_keys() { info "生成签名密钥..." local key_dir="/etc/patch/keys" local sudo_prefix sudo_prefix=$(get_cmd_prefix) if [[ ! -f "$key_dir/private.pem" ]]; then $sudo_prefix mkdir -p "$key_dir" # 生成RSA密钥对 openssl genrsa -out "$key_dir/private.pem" 4096 openssl rsa -in "$key_dir/private.pem" -pubout -out "$key_dir/public.pem" $sudo_prefix chmod 600 "$key_dir/private.pem" $sudo_prefix chmod 644 "$key_dir/public.pem" info "密钥对已生成: $key_dir/" else info "密钥对已存在" fi } main() { info "开始安装企业级补丁管理系统" echo "========================================" # 检查运行环境 if is_docker_environment; then info "检测到Docker容器环境,将以root权限执行(不适用sudo)" SUDO_CMD="" else info "检测到主机环境,将使用sudo执行管理员操作" SUDO_CMD="sudo" # 在非Docker环境中,建议非root用户运行 if [[ $EUID -eq 0 ]]; then warn "检测到以root用户运行,建议在非Docker环境中使用具备sudo权限的普通用户" fi fi # 安装依赖 install_dependencies # 创建目录 create_directories # 安装脚本 install_scripts # 设置定时任务 setup_cron # 生成密钥 generate_keys info "🎉 补丁管理系统安装完成!" echo "" echo "📁 安装目录: $INSTALL_DIR" echo "🔧 使用命令: patch-mgmt" echo "📋 配置文件: $INSTALL_DIR/patch_config.sh" echo "" echo "💡 下一步操作:" echo " 1. 编辑配置文件: $INSTALL_DIR/patch_config.sh" echo " 2. 测试系统: patch-mgmt --help" echo " 3. 配置通知: 修改SLACK_WEBHOOK等设置" } main "$@"