From e9c3e4caa7f380e767358969f86145324032c112 Mon Sep 17 00:00:00 2001 From: eddy <1036636139@qq.com> Date: Thu, 13 Nov 2025 22:00:35 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84SSH=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=84=9A=E6=9C=AC=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=A3=80=E6=9F=A5=E3=80=81=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E5=8F=8A=E6=8C=81=E4=B9=85=E5=8C=96=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- init/00-disable-password.sh | 411 ++++++++++++++++++++++++++++-------- 1 file changed, 326 insertions(+), 85 deletions(-) diff --git a/init/00-disable-password.sh b/init/00-disable-password.sh index 2f4365f..6061bfb 100644 --- a/init/00-disable-password.sh +++ b/init/00-disable-password.sh @@ -1,6 +1,10 @@ #!/bin/bash -# chmod +x 00-disable-password.sh && ./00-disable-password.sh -# curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/00-disable-password.sh && chmod +x 00-disable-password.sh && ./00-disable-password.sh +# 用法: +# 启用安全模式: ./00-disable-password.sh enable +# 关闭安全模式: ./00-disable-password.sh disable +# 查看状态: ./00-disable-password.sh status +# +# curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/00-disable-password.sh && chmod +x 00-disable-password.sh set -e # 遇到错误立即退出 @@ -8,6 +12,7 @@ set -e # 遇到错误立即退出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' +BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 @@ -23,9 +28,15 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" } +log_status() { + echo -e "${BLUE}[STATUS]${NC} $1" +} + # 用户设置 NEW_SSH_PORT="4399" # 根据需求修改端口 +DEFAULT_SSH_PORT="22" BACKUP_DIR="/root/ssh_backup_$(date +%Y%m%d_%H%M%S)" +PERSISTENT_BACKUP_DIR="/root/ssh_config_backup" # 检查是否为root用户 if [ "$EUID" -ne 0 ]; then @@ -33,9 +44,85 @@ if [ "$EUID" -ne 0 ]; then exit 1 fi -# 创建备份目录 -mkdir -p "$BACKUP_DIR" -log_info "备份目录: $BACKUP_DIR" +# 显示使用帮助 +show_usage() { + echo "用法: $0 {enable|disable|status}" + echo "" + echo "命令:" + echo " enable - 启用 SSH 安全模式(禁用密码登录,使用密钥认证)" + echo " disable - 关闭 SSH 安全模式(恢复密码登录)" + echo " status - 查看当前 SSH 配置状态" + echo "" + echo "示例:" + echo " $0 enable # 启用安全模式" + echo " $0 disable # 关闭安全模式" + echo " $0 status # 查看状态" + exit 1 +} + +# 获取当前SSH配置状态 +get_ssh_config_value() { + local key=$1 + local config_file="/etc/ssh/sshd_config" + + # 获取配置值(忽略注释行) + grep "^${key}" "$config_file" 2>/dev/null | awk '{print $2}' | head -n1 +} + +# 检查当前状态 +check_current_status() { + local port=$(get_ssh_config_value "Port") + local password_auth=$(get_ssh_config_value "PasswordAuthentication") + local pubkey_auth=$(get_ssh_config_value "PubkeyAuthentication") + local permit_root=$(get_ssh_config_value "PermitRootLogin") + + # 默认值 + port=${port:-22} + password_auth=${password_auth:-yes} + pubkey_auth=${pubkey_auth:-yes} + permit_root=${permit_root:-yes} + + echo "当前 SSH 配置状态:" + echo "----------------------------------------" + echo " SSH 端口: $port" + echo " 密码认证: $password_auth" + echo " 公钥认证: $pubkey_auth" + echo " Root登录: $permit_root" + echo "----------------------------------------" + + # 判断是否为安全模式 + if [[ "$password_auth" == "no" ]] && [[ "$pubkey_auth" == "yes" ]]; then + log_status "当前处于【安全模式】- 密码登录已禁用" + return 0 # 安全模式 + else + log_status "当前处于【普通模式】- 密码登录已启用" + return 1 # 普通模式 + fi +} + +# 显示状态 +show_status() { + log_info "正在检查 SSH 配置状态..." + echo "" + check_current_status + + # 检查是否有备份 + if [ -d "$PERSISTENT_BACKUP_DIR" ] && [ -f "$PERSISTENT_BACKUP_DIR/sshd_config.original" ]; then + echo "" + log_info "找到配置备份: $PERSISTENT_BACKUP_DIR" + fi +} + +# 创建持久化备份 +create_persistent_backup() { + if [ ! -d "$PERSISTENT_BACKUP_DIR" ]; then + mkdir -p "$PERSISTENT_BACKUP_DIR" + cp /etc/ssh/sshd_config "$PERSISTENT_BACKUP_DIR/sshd_config.original" + log_info "已创建原始配置备份: $PERSISTENT_BACKUP_DIR/sshd_config.original" + else + log_info "使用现有配置备份: $PERSISTENT_BACKUP_DIR" + fi +} # 1. 检查公钥是否存在 check_ssh_keys() { @@ -60,20 +147,31 @@ check_ssh_keys() { # 2. 检查端口是否被占用 check_port() { - log_info "检查端口 $NEW_SSH_PORT 是否可用..." + local port=$1 + log_info "检查端口 $port 是否可用..." - if ss -tlnp | grep -q ":$NEW_SSH_PORT "; then - log_error "端口 $NEW_SSH_PORT 已被占用!" - ss -tlnp | grep ":$NEW_SSH_PORT " - exit 1 + if ss -tlnp 2>/dev/null | grep -q ":$port " || netstat -tlnp 2>/dev/null | grep -q ":$port "; then + # 检查是否是SSH服务占用 + if ss -tlnp 2>/dev/null | grep ":$port " | grep -q "sshd" || netstat -tlnp 2>/dev/null | grep ":$port " | grep -q "sshd"; then + log_info "端口 $port 已被 SSH 服务占用(正常)" + else + log_error "端口 $port 已被其他服务占用!" + ss -tlnp 2>/dev/null | grep ":$port " || netstat -tlnp 2>/dev/null | grep ":$port " + exit 1 + fi + else + log_info "端口 $port 可用" fi - log_info "端口 $NEW_SSH_PORT 可用" } -# 3. 关闭 SSH 密码登录并启用密钥认证 -disable_password_login() { +# 3. 修改SSH配置 +modify_ssh_config() { + local mode=$1 # enable 或 disable log_info "开始配置 SSH..." + # 创建临时备份目录 + mkdir -p "$BACKUP_DIR" + # 备份原始配置 cp /etc/ssh/sshd_config "$BACKUP_DIR/sshd_config.bak" log_info "已备份 SSH 配置到: $BACKUP_DIR/sshd_config.bak" @@ -81,46 +179,87 @@ disable_password_login() { # 创建新配置 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.tmp - # 修改配置(更安全的方式) - # 1. 禁止 root 密码登录,但允许密钥登录 - if grep -q "^PermitRootLogin" /etc/ssh/sshd_config.tmp; then - sed -i 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config.tmp - else - echo "PermitRootLogin prohibit-password" >> /etc/ssh/sshd_config.tmp - fi + if [ "$mode" == "enable" ]; then + log_info "配置安全模式..." - # 2. 禁用密码认证 - if grep -q "^PasswordAuthentication" /etc/ssh/sshd_config.tmp; then - sed -i 's/^PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config.tmp - else - echo "PasswordAuthentication no" >> /etc/ssh/sshd_config.tmp - fi + # 1. 禁止 root 密码登录,但允许密钥登录 + if grep -q "^PermitRootLogin" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config.tmp + fi - # 3. 启用公钥认证 - if grep -q "^PubkeyAuthentication" /etc/ssh/sshd_config.tmp; then - sed -i 's/^PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config.tmp - else - echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config.tmp - fi + # 2. 禁用密码认证 + if grep -q "^PasswordAuthentication" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config.tmp + fi - # 4. 修改端口 - if grep -q "^Port " /etc/ssh/sshd_config.tmp; then - sed -i "s/^Port [0-9]\+/Port $NEW_SSH_PORT/" /etc/ssh/sshd_config.tmp - else - sed -i "s/^#Port 22/Port $NEW_SSH_PORT/" /etc/ssh/sshd_config.tmp - fi + # 3. 启用公钥认证 + if grep -q "^PubkeyAuthentication" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config.tmp + fi - # 5. 额外的安全加固 - # 禁用空密码 - if grep -q "^PermitEmptyPasswords" /etc/ssh/sshd_config.tmp; then - sed -i 's/^PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config.tmp - else - echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config.tmp - fi + # 4. 修改端口 + if grep -q "^Port " /etc/ssh/sshd_config.tmp; then + sed -i "s/^Port [0-9]\+/Port $NEW_SSH_PORT/" /etc/ssh/sshd_config.tmp + else + sed -i "s/^#Port 22/Port $NEW_SSH_PORT/" /etc/ssh/sshd_config.tmp + fi - # 禁用质询响应认证 - if grep -q "^ChallengeResponseAuthentication" /etc/ssh/sshd_config.tmp; then - sed -i 's/^ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config.tmp + # 5. 额外的安全加固 + # 禁用空密码 + if grep -q "^PermitEmptyPasswords" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config.tmp + fi + + # 禁用质询响应认证 + if grep -q "^ChallengeResponseAuthentication" /etc/ssh/sshd_config.tmp; then + sed -i 's/^ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config.tmp + fi + + elif [ "$mode" == "disable" ]; then + log_info "配置普通模式(允许密码登录)..." + + # 如果有原始备份,直接恢复 + if [ -f "$PERSISTENT_BACKUP_DIR/sshd_config.original" ]; then + log_info "从原始备份恢复配置..." + cp "$PERSISTENT_BACKUP_DIR/sshd_config.original" /etc/ssh/sshd_config.tmp + else + # 手动修改为允许密码登录 + log_info "手动修改配置..." + + # 1. 允许 root 密码登录 + if grep -q "^PermitRootLogin" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config.tmp + fi + + # 2. 启用密码认证 + if grep -q "^PasswordAuthentication" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config.tmp + fi + + # 3. 启用公钥认证(保持) + if grep -q "^PubkeyAuthentication" /etc/ssh/sshd_config.tmp; then + sed -i 's/^PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config.tmp + else + sed -i 's/^#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config.tmp + fi + + # 4. 恢复默认端口 + if grep -q "^Port " /etc/ssh/sshd_config.tmp; then + sed -i "s/^Port [0-9]\+/Port $DEFAULT_SSH_PORT/" /etc/ssh/sshd_config.tmp + fi + fi fi # 验证配置文件语法 @@ -154,8 +293,8 @@ restart_ssh() { fi } -# 5. 配置防火墙 -configure_firewall() { +# 5. 配置防火墙(启用模式) +configure_firewall_enable() { log_info "配置防火墙..." # 检查系统并安装 UFW @@ -165,6 +304,7 @@ configure_firewall() { fi # 备份当前防火墙规则 + mkdir -p "$BACKUP_DIR" ufw status numbered > "$BACKUP_DIR/ufw_rules.bak" 2>/dev/null || true # 配置防火墙规则 @@ -188,42 +328,47 @@ configure_firewall() { ufw status verbose } -# 6. 显示最终信息 -show_summary() { - echo "" - echo "========================================" - log_info "SSH 安全配置完成!" - echo "========================================" - echo "" - echo "修改后的配置:" - echo " - SSH 端口: $NEW_SSH_PORT" - echo " - 密码登录: 已禁用" - echo " - 密钥登录: 已启用" - echo " - Root 密码登录: 已禁用" - echo "" - echo "备份信息:" - echo " - 备份目录: $BACKUP_DIR" - echo " - SSH 配置备份: $BACKUP_DIR/sshd_config.bak" - echo "" - echo "重要提示:" - echo " 1. 请勿关闭当前 SSH 连接" - echo " 2. 在新终端测试登录: ssh -p $NEW_SSH_PORT root@your_server_ip" - echo " 3. 确认新连接成功后再关闭此窗口" - echo " 4. 如果无法登录,可以使用以下命令恢复:" - echo " cp $BACKUP_DIR/sshd_config.bak /etc/ssh/sshd_config" - echo " systemctl restart sshd" - echo "" - echo "========================================" +# 6. 配置防火墙(禁用模式) +configure_firewall_disable() { + log_info "恢复防火墙配置..." + + if ! command -v ufw &> /dev/null; then + log_info "未安装 UFW,跳过防火墙配置" + return + fi + + # 允许默认SSH端口 + ufw allow $DEFAULT_SSH_PORT/tcp comment "SSH" + log_info "已允许默认 SSH 端口 $DEFAULT_SSH_PORT" + + # 询问是否删除自定义端口规则 + read -p "是否删除自定义 SSH 端口 $NEW_SSH_PORT 的防火墙规则? (y/n): " remove_port + if [[ $remove_port =~ ^[Yy]$ ]]; then + ufw delete allow $NEW_SSH_PORT/tcp 2>/dev/null || true + log_info "已删除端口 $NEW_SSH_PORT 的防火墙规则" + fi + + ufw status verbose } -# 主流程 -main() { - log_info "开始 SSH 安全配置..." +# 启用安全模式 +enable_security() { + log_info "=== 启用 SSH 安全模式 ===" echo "" + # 检查当前状态 + if check_current_status > /dev/null 2>&1; then + log_warn "SSH 已经处于安全模式" + read -p "是否要重新配置? (y/n): " reconfig + if [[ ! $reconfig =~ ^[Yy]$ ]]; then + log_info "操作已取消" + exit 0 + fi + fi + # 显示当前配置 log_info "当前 SSH 配置:" - echo " - 当前端口: $(grep "^Port " /etc/ssh/sshd_config 2>/dev/null || echo "22 (默认)")" + echo " - 当前端口: $(get_ssh_config_value "Port" || echo "22 (默认)")" echo " - 将修改为: $NEW_SSH_PORT" echo "" @@ -234,13 +379,109 @@ main() { exit 0 fi + # 创建持久化备份 + create_persistent_backup + + # 执行配置 check_ssh_keys - check_port - disable_password_login + check_port "$NEW_SSH_PORT" + modify_ssh_config "enable" restart_ssh - configure_firewall - show_summary + configure_firewall_enable + + # 显示完成信息 + echo "" + echo "========================================" + log_info "SSH 安全模式已启用!" + echo "========================================" + echo "" + echo "修改后的配置:" + echo " - SSH 端口: $NEW_SSH_PORT" + echo " - 密码登录: 已禁用" + echo " - 密钥登录: 已启用" + echo " - Root 密码登录: 已禁用" + echo "" + echo "备份信息:" + echo " - 临时备份: $BACKUP_DIR" + echo " - 永久备份: $PERSISTENT_BACKUP_DIR" + echo "" + echo "重要提示:" + echo " 1. 请勿关闭当前 SSH 连接" + echo " 2. 在新终端测试登录: ssh -p $NEW_SSH_PORT root@your_server_ip" + echo " 3. 确认新连接成功后再关闭此窗口" + echo " 4. 如需恢复,运行: $0 disable" + echo "" + echo "========================================" +} + +# 关闭安全模式 +disable_security() { + log_info "=== 关闭 SSH 安全模式 ===" + echo "" + + # 检查当前状态 + if ! check_current_status > /dev/null 2>&1; then + log_warn "SSH 已经处于普通模式" + read -p "是否要重新配置? (y/n): " reconfig + if [[ ! $reconfig =~ ^[Yy]$ ]]; then + log_info "操作已取消" + exit 0 + fi + fi + + # 警告 + log_warn "警告: 此操作将允许密码登录,安全性会降低!" + read -p "确认要关闭安全模式吗? (输入 YES 继续): " confirm + if [ "$confirm" != "YES" ]; then + log_info "操作已取消" + exit 0 + fi + + # 执行配置 + check_port "$DEFAULT_SSH_PORT" + modify_ssh_config "disable" + restart_ssh + configure_firewall_disable + + # 显示完成信息 + echo "" + echo "========================================" + log_info "SSH 安全模式已关闭!" + echo "========================================" + echo "" + echo "修改后的配置:" + echo " - SSH 端口: $DEFAULT_SSH_PORT" + echo " - 密码登录: 已启用" + echo " - 密钥登录: 已启用" + echo "" + echo "重要提示:" + echo " 1. 请勿关闭当前 SSH 连接" + echo " 2. 在新终端测试登录: ssh -p $DEFAULT_SSH_PORT root@your_server_ip" + echo " 3. 确认新连接成功后再关闭此窗口" + echo " 4. 如需重新启用安全模式,运行: $0 enable" + echo "" + echo "========================================" +} + +# 主流程 +main() { + local action=${1:-} + + case "$action" in + enable) + enable_security + ;; + disable) + disable_security + ;; + status) + show_status + ;; + *) + show_usage + ;; + esac } # 执行主函数 -main +main "$@"