为有效防止服务器被暴力破解,可以配置 SSH 密钥登录并全面禁用密码登录。由于手动为每位用户配置密钥的过程较为繁琐,本文档提供了一套自动化脚本及相关配置流程,以便于快速配置。

1. 自动化配置脚本

1.1 一键创建用户并配置 SSH 密钥

针对新用户,我们可以使用以下脚本一键完成用户创建、加入 data 组、配置 SSH 登录公钥以及相关环境初始化(如拷贝网络登录脚本等)。

#!/bin/bash
set -euo pipefail

SCRIPT_SRC_DIR="/home/fridemn/scripts"

read -rp "请输入用户名: " username
read -rp "请输入用户公钥: " user_pubkey

# 基本校验
if [[ -z "$username" ]]; then
    echo "错误:用户名不能为空。"
    exit 1
fi

if [[ -z "$user_pubkey" ]]; then
    echo "错误:用户公钥不能为空。"
    exit 1
fi

# 如果 data 组不存在,则自动创建
if ! getent group data > /dev/null; then
    sudo groupadd data
fi

# 检查用户是否已存在
if id "$username" &>/dev/null; then
    echo "错误:用户 '$username' 已存在。"
    exit 1
fi

# 创建用户(不强制设置密码,后续仅允许 SSH 密钥登录)
sudo useradd -m -d "/home/$username" -G data -s /bin/bash "$username"

# 创建 .ssh 目录并配置 authorized_keys
sudo mkdir -p "/home/$username/.ssh"
echo "$user_pubkey" | sudo tee "/home/$username/.ssh/authorized_keys" > /dev/null

# 修正 .ssh 相关权限
sudo chown -R "$username:$username" "/home/$username/.ssh"
sudo chmod 700 "/home/$username/.ssh"
sudo chmod 600 "/home/$username/.ssh/authorized_keys"

# 创建 scripts 目录准备放置常用脚本
sudo mkdir -p "/home/$username/scripts"

# 检查源脚本是否存在
if [[ ! -f "$SCRIPT_SRC_DIR/login.sh" ]]; then
    echo "错误:未找到 $SCRIPT_SRC_DIR/login.sh"
    exit 1
fi

if [[ ! -f "$SCRIPT_SRC_DIR/logout.sh" ]]; then
    echo "错误:未找到 $SCRIPT_SRC_DIR/logout.sh"
    exit 1
fi

# 复制校园网登录/注销脚本
sudo cp "$SCRIPT_SRC_DIR/login.sh" "/home/$username/scripts/login.sh"
sudo cp "$SCRIPT_SRC_DIR/logout.sh" "/home/$username/scripts/logout.sh"

# 修正 scripts 目录及其内容的属主和权限
sudo chown -R "$username:$username" "/home/$username/scripts"
sudo chmod 755 "/home/$username/scripts"
sudo chmod 750 "/home/$username/scripts/login.sh" "/home/$username/scripts/logout.sh"

echo "用户 '$username' 创建成功。"
echo "已配置 SSH 公钥登录:/home/$username/.ssh/authorized_keys"
echo "已复制脚本到:/home/$username/scripts/"

这个脚本的作用是:

  • 输入用户名和用户 ssh 公钥,自动创建用户并添加到 data 用户组
  • 自动配置 ssh-key
  • 将校园网登录、注销脚本拷贝到用户 scripts 目录

1.2 为现有用户追加补录 SSH 密钥

有时候用户在初始创建时并未配置 SSH 密钥(例如初始管理员账号)。为此,我们提供了一个专用的密钥配置脚本。该脚本仅专注于向已有账户追加或覆盖公钥配置。

#!/bin/bash
set -euo pipefail

read -rp "请输入已存在的用户名: " username
read -rp "请输入用户公钥: " user_pubkey
read -rp "请选择写入模式 [a=追加, o=覆盖],默认追加: " mode

mode="${mode:-a}"

if [[ -z "$username" ]]; then
    echo "错误:用户名不能为空。"
    exit 1
fi

if [[ -z "$user_pubkey" ]]; then
    echo "错误:用户公钥不能为空。"
    exit 1
fi

# 校验用户是否存在
if ! id "$username" &>/dev/null; then
    echo "错误:用户 '$username' 不存在。"
    exit 1
fi

# 获取用户的家目录路径
user_home=$(getent passwd "$username" | cut -d: -f6)

if [[ -z "$user_home" || ! -d "$user_home" ]]; then
    echo "错误:无法找到用户 '$username' 的家目录。"
    exit 1
fi

# 确保 .ssh 目录存在
sudo mkdir -p "$user_home/.ssh"

case "$mode" in
    a|A)
        echo "$user_pubkey" | sudo tee -a "$user_home/.ssh/authorized_keys" > /dev/null
        echo "已追加公钥到 $user_home/.ssh/authorized_keys"
        ;;
    o|O)
        echo "$user_pubkey" | sudo tee "$user_home/.ssh/authorized_keys" > /dev/null
        echo "已覆盖写入公钥到 $user_home/.ssh/authorized_keys"
        ;;
    *)
        echo "错误:写入模式只能是 a 或 o。"
        exit 1
        ;;
esac

# 统一修正权限,确保 SSH 鉴权能够顺利通过
sudo chown -R "$username:$username" "$user_home/.ssh"
sudo chmod 700 "$user_home/.ssh"
sudo chmod 600 "$user_home/.ssh/authorized_keys"

echo "用户 '$username' 的 SSH 公钥已配置完成。"
echo "请确认用户本地私钥正确,并测试:ssh $username@服务器IP"

2. 客户端 (本地设备) 生成 SSH 公钥指南

服务端脚本要求输入公钥内容。这里简要说明用户如何在自己的个人设备上查看或生成 SSH 密钥对。

2.1 检查是否已有公钥

在生成新密钥前,建议用户先检查设备是否已经存在密钥(通常存放于用户目录下的 .ssh/ 文件夹内)。

Linux / macOS:

cat ~/.ssh/id_ed25519.pub

Windows - PowerShell:

type $env:USERPROFILE\.ssh\id_ed25519.pub

Windows - CMD:

type %USERPROFILE%\.ssh\id_ed25519.pub

2.2 生成新的 ED25519 密钥对

如果终端提示文件不存在,说明需要生成新的密钥对(推荐使用安全性更高的 ed25519 算法)。

在任意系统终端中执行:

ssh-keygen -t ed25519 -C "备注"

例如:

ssh-keygen -t ed25519 -C "fridemn@806-ai"

按提示一路回车即可生成,随后再次使用 2.1 中的命令获取公钥内容。


3. 服务器安全加固:禁用密码登录

在确保新用户能够通过 SSH 密钥正常连接后,应该在系统层面彻底关闭密码登录机制。

3.1 修改 SSHD 配置

编辑 SSH 守护进程的主配置文件:

sudo vim /etc/ssh/sshd_config

查找并修改为如下配置(若不存在则在文末添加):

# 允许且仅允许密钥验证
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM yes
# 根据需要,建议禁止 root 用户直接登录
PermitRootLogin no

3.2 验证与生效

验证配置内容:
可以运行以下命令快速核对关键配置项是否已正确修改:

grep -R "PasswordAuthentication\|KbdInteractiveAuthentication\|ChallengeResponseAuthentication\|PubkeyAuthentication" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null

测试配置语法:
修改完配置后,务必检查语法,避免因语法错误导致后续无法连接服务器:

sudo sshd -t

(如果没有输出任何信息,则代表配置文件语法正常。)

重启 SSH 服务使配置生效:

sudo systemctl daemon-reload
sudo systemctl reload ssh