diff --git a/init/00-disable-password.sh b/init/00-disable-password.sh index 631f4d2..2f4365f 100644 --- a/init/00-disable-password.sh +++ b/init/00-disable-password.sh @@ -2,43 +2,245 @@ # 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 +set -e # 遇到错误立即退出 + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# 日志函数 +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} # 用户设置 -new_ssh_port="4399" # 根据需求修改端口 +NEW_SSH_PORT="4399" # 根据需求修改端口 +BACKUP_DIR="/root/ssh_backup_$(date +%Y%m%d_%H%M%S)" -echo "1、关闭 SSH 密码登录并启用密钥认证" -disablePasswordLogin() { - # 备份 SSH 配置文件 - cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak +# 检查是否为root用户 +if [ "$EUID" -ne 0 ]; then + log_error "请使用 root 用户运行此脚本" + exit 1 +fi - # 修改 SSH 配置文件 - sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config - sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/g' /etc/ssh/sshd_config +# 创建备份目录 +mkdir -p "$BACKUP_DIR" +log_info "备份目录: $BACKUP_DIR" - # 确保 PubkeyAuthentication 开启 - sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/g' /etc/ssh/sshd_config +# 1. 检查公钥是否存在 +check_ssh_keys() { + log_info "检查 SSH 公钥..." - # 修改端口 - sed -i 's/^#\?Port [0-9]\+/Port '$new_ssh_port'/g' /etc/ssh/sshd_config - - # 重启 SSH 服务 - service sshd restart + if [ ! -f ~/.ssh/authorized_keys ] || [ ! -s ~/.ssh/authorized_keys ]; then + log_error "未找到 SSH 公钥文件或文件为空!" + log_error "路径: ~/.ssh/authorized_keys" + echo "" + log_warn "如果继续,您将无法通过 SSH 登录服务器!" + read -p "是否要继续?(输入 YES 继续): " confirm + if [ "$confirm" != "YES" ]; then + log_info "操作已取消" + exit 0 + fi + else + log_info "找到 SSH 公钥,密钥数量: $(grep -c "^ssh-" ~/.ssh/authorized_keys || echo 0)" + echo "密钥内容预览:" + head -n 2 ~/.ssh/authorized_keys + fi } -disablePasswordLogin -echo "2、开启防火墙并允许新的 SSH 端口" -openUfwPort() { - echo "开启防火墙并允许新的SSH端口: $new_ssh_port" - apt update -y && apt install -y ufw +# 2. 检查端口是否被占用 +check_port() { + log_info "检查端口 $NEW_SSH_PORT 是否可用..." + + if ss -tlnp | grep -q ":$NEW_SSH_PORT "; then + log_error "端口 $NEW_SSH_PORT 已被占用!" + ss -tlnp | grep ":$NEW_SSH_PORT " + exit 1 + fi + log_info "端口 $NEW_SSH_PORT 可用" +} + +# 3. 关闭 SSH 密码登录并启用密钥认证 +disable_password_login() { + log_info "开始配置 SSH..." + + # 备份原始配置 + cp /etc/ssh/sshd_config "$BACKUP_DIR/sshd_config.bak" + log_info "已备份 SSH 配置到: $BACKUP_DIR/sshd_config.bak" + + # 创建新配置 + 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 + + # 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 + + # 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 + + # 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 + + # 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 + + # 禁用质询响应认证 + if grep -q "^ChallengeResponseAuthentication" /etc/ssh/sshd_config.tmp; then + sed -i 's/^ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config.tmp + fi + + # 验证配置文件语法 + log_info "验证 SSH 配置文件语法..." + if sshd -t -f /etc/ssh/sshd_config.tmp; then + log_info "SSH 配置文件语法正确" + mv /etc/ssh/sshd_config.tmp /etc/ssh/sshd_config + else + log_error "SSH 配置文件语法错误!" + rm /etc/ssh/sshd_config.tmp + exit 1 + fi +} + +# 4. 重启 SSH 服务(兼容多种系统) +restart_ssh() { + log_info "重启 SSH 服务..." + + # 保持当前连接 + log_warn "注意: SSH 服务将重启,但当前连接会保持" + + if command -v systemctl &> /dev/null; then + systemctl restart sshd || systemctl restart ssh + log_info "SSH 服务已通过 systemctl 重启" + elif command -v service &> /dev/null; then + service sshd restart || service ssh restart + log_info "SSH 服务已通过 service 重启" + else + /etc/init.d/sshd restart || /etc/init.d/ssh restart + log_info "SSH 服务已通过 init.d 重启" + fi +} + +# 5. 配置防火墙 +configure_firewall() { + log_info "配置防火墙..." + + # 检查系统并安装 UFW + if ! command -v ufw &> /dev/null; then + log_info "安装 UFW 防火墙..." + apt-get update -y && apt-get install -y ufw + fi + + # 备份当前防火墙规则 + ufw status numbered > "$BACKUP_DIR/ufw_rules.bak" 2>/dev/null || true + + # 配置防火墙规则 + log_info "设置防火墙规则..." + + # 先允许新端口,避免锁死 + ufw allow $NEW_SSH_PORT/tcp comment "SSH" + + # 询问是否允许其他常用端口 + read -p "是否允许 HTTP (80) 和 HTTPS (443) 端口? (y/n): " allow_web + if [[ $allow_web =~ ^[Yy]$ ]]; then + ufw allow 80/tcp comment "HTTP" + ufw allow 443/tcp comment "HTTPS" + log_info "已允许 HTTP 和 HTTPS 端口" + fi + + # 启用防火墙 ufw --force enable - ufw allow $new_ssh_port - ufw status -} -openUfwPort -echo "------------------------" -echo "修改后的信息:" -echo "端口: $new_ssh_port" -echo "SSH 密码登录: 已关闭" -echo "请确保您的公钥已正确上传到服务器的 ~/.ssh/authorized_keys 文件中。" -echo "------------------------" + log_info "防火墙状态:" + 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 "========================================" +} + +# 主流程 +main() { + log_info "开始 SSH 安全配置..." + echo "" + + # 显示当前配置 + log_info "当前 SSH 配置:" + echo " - 当前端口: $(grep "^Port " /etc/ssh/sshd_config 2>/dev/null || echo "22 (默认)")" + echo " - 将修改为: $NEW_SSH_PORT" + echo "" + + # 确认执行 + read -p "是否继续执行? (y/n): " confirm + if [[ ! $confirm =~ ^[Yy]$ ]]; then + log_info "操作已取消" + exit 0 + fi + + check_ssh_keys + check_port + disable_password_login + restart_ssh + configure_firewall + show_summary +} + +# 执行主函数 +main