为有效防止服务器被暴力破解,可以配置 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
评论区