#!/bin/bash
# =====================================================
# 机房十二时辰 · Linux 安全基线加固工具
# 适用: CentOS / Ubuntu / Debian / 麒麟 / UOS / openEuler
# 用法:
#   bash linux-hardening.sh             # 执行安全加固（输出详细日志）
#   bash linux-hardening.sh --rollback  # 一键还原（恢复加固前状态）
# =====================================================
mkdir -p /root/.jifang-hardening/backup
LOG=/root/.jifang-hardening/hardening.log
BAK=/root/.jifang-hardening/backup
log() { echo "$(date '+%F %T') [INFO] $*" | tee -a "$LOG"; }

rollback() {
  log "===== 开始一键还原 ====="
  if [ -d "$BAK" ]; then
    for f in "$BAK"/*.bak; do
      [ -e "$f" ] || continue
      target="${f%.bak}"
      log "还原: $target"
      cp -f "$f" "$target"
    done
    systemctl reload sshd 2>/dev/null || service ssh reload 2>/dev/null || true
    log "还原完成。已恢复到加固前状态。"
  else
    log "未发现备份，无可还原项。"
  fi
}

apply() {
  log "===== 开始安全基线加固（以下每项均已记录） ====="
  # 1. SSH 加固
  if [ -f /etc/ssh/sshd_config ]; then
    cp -f /etc/ssh/sshd_config "$BAK/sshd_config.bak"
    sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
    sed -i 's/^#\?PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config
    sed -i 's/^#\?MaxAuthTries.*/MaxAuthTries 4/' /etc/ssh/sshd_config
    log "SSH: PermitRootLogin=prohibit-password"
    log "SSH: PermitEmptyPasswords=no"
    log "SSH: MaxAuthTries=4"
    systemctl reload sshd 2>/dev/null || service ssh reload 2>/dev/null || true
  else
    log "SSH: 未发现 sshd_config，跳过"
  fi
  # 2. 密码策略
  if [ -f /etc/login.defs ]; then
    cp -f /etc/login.defs "$BAK/login.defs.bak"
    sed -i 's/^#\?PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
    sed -i 's/^#\?PASS_MIN_LEN.*/PASS_MIN_LEN 8/' /etc/login.defs
    log "密码策略: PASS_MAX_DAYS=90"
    log "密码策略: PASS_MIN_LEN=8"
  fi
  # 3. 防火墙
  if command -v firewall-cmd >/dev/null 2>&1; then systemctl enable --now firewalld 2>/dev/null && log "防火墙: 已启用 firewalld"; fi
  if command -v ufw >/dev/null 2>&1; then ufw --force enable 2>/dev/null && log "防火墙: 已启用 ufw"; fi
  # 4. 禁用危险服务
  systemctl disable --now telnet.socket 2>/dev/null && log "服务: 已禁用 telnet"
  systemctl disable --now rsh.socket 2>/dev/null && log "服务: 已禁用 rsh"
  # 5. 内核安全参数
  if [ -f /etc/sysctl.conf ]; then
    cp -f /etc/sysctl.conf "$BAK/sysctl.conf.bak"
    grep -q '^net.ipv4.conf.all.rp_filter' /etc/sysctl.conf || echo 'net.ipv4.conf.all.rp_filter = 1' >> /etc/sysctl.conf
    grep -q '^kernel.randomize_va_space' /etc/sysctl.conf || echo 'kernel.randomize_va_space = 2' >> /etc/sysctl.conf
    sysctl -p >/dev/null 2>&1 || true
    log "内核: net.ipv4.conf.all.rp_filter=1"
    log "内核: kernel.randomize_va_space=2"
  fi
  # 6. 锁定空密码用户
  awk -F: '$2==""{print $1}' /etc/shadow >/tmp/jifang_empty_pw 2>/dev/null
  if [ -s /tmp/jifang_empty_pw ]; then
    while read u; do passwd -l "$u" 2>/dev/null && log "账户: 已锁定空密码用户 $u"; done </tmp/jifang_empty_pw
  fi
  # 7. 权限: root 目录/关键文件权限收紧
  chmod 700 /root 2>/dev/null && log "权限: /root 设置为 700"
  log "===== 安全基线加固执行完成。日志见: $LOG ====="
}

if [ "$1" == "--rollback" ]; then rollback; else apply; fi
