01 / 03
第 1 讲
服务器安全加固
把“谁都能来猜密码”的服务器,收紧成只认密钥、只开必要端口,并且会主动封禁攻击者的机器。
01先看见威胁
服务器接入公网的那一刻,22 端口就可能已经被自动化扫描器遍历。攻击者用大量常见用户名和密码反复尝试登录,这就是暴力破解。第一件事不是急着改配置,而是先确认:自己的机器正在被谁敲门。
sudo journalctl -u sshd | grep -i "failed" | tail -30
journalctl -u sshd:只看 sshd 这项服务的日志。grep -i "failed":筛出登录失败记录,-i忽略大小写。tail -30:只保留最后 30 条,先看最近的动静。
如果看到大量陌生 IP、并且集中在尝试 root,说明服务器已经被扫描。接下来沿着“攻击者能从哪儿进来”逐处收口。
02先分清两条登录通道
这是整讲最重要的一张地图。登录云服务器其实有两条机制完全不同的路,知道第二条路存在,才敢动手改第一条路。
| 通道 | 实际路径 | 被改坏时 | 定位 |
|---|---|---|---|
| SSH / Workbench | 公网 → 安全组 22 端口 → 主机 sshd | 改坏 sshd 或封掉 22,会一起断 | 日常操作 |
| VNC | 阿里云带外管理,不经过安全组和 sshd | 仍可用系统账号密码登录 | 救急后路 |
Workbench 本质仍是 SSH,不是后路;真正能救命的是 VNC。在 VNC 里执行 tty 会看到 /dev/tty1,这是机器本地控制台;SSH 登录则显示 /dev/pts/0 一类伪终端。两者从系统内部印证了“这是两条独立通道”。
所以,做任何高风险修改前,先按控制台提示走一遍 VNC:用普通用户登录、执行 whoami 和 tty、再 exit 退出。后路只有亲自走通过一次才可靠。
03用密钥代替密码登录
密码可能被猜中,也可能被泄露。密钥认证换了一套思路:本地生成一对相互配对的钥匙,私钥只留在自己电脑,公钥放到服务器。登录时,服务器用公钥出一道只有对应私钥才能解开的“数学题”。
私钥
身份的唯一凭证,留在自己的电脑上,绝不外传、绝不发给任何人。
公钥
可以公开。安装到服务器账号的 authorized_keys 里。
验证
服务器用公钥出题,只有持私钥的人能解开并完成登录。
先准备一个日常使用的普通用户
sudo adduser study
sudo passwd study
sudo usermod -aG wheel study
wheel 组的成员才能用 sudo 执行管理员操作。加固完成后会禁止 root 直接远程登录,所以必须先把普通用户准备好。
在本机生成密钥对
ssh-keygen -t ed25519 -C "你的名字-服务器加固"
一路回车即可。-t ed25519 指定现代、短小且安全的算法,-C 只是备注,方便日后辨认这把钥匙属于谁。生成后查看公钥:
# Windows PowerShell
type $env:USERPROFILE\.ssh\id_ed25519.pub
# macOS / Linux
cat ~/.ssh/id_ed25519.pub
复制出来的是一整行公钥,中间不能断行。不带 .pub 的那个文件才是私钥,不要复制、不要上传、不要发给老师。
把公钥安装到服务器
sudo su - study
mkdir -p ~/.ssh
chmod 700 ~/.ssh
vi ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
ls -l ~/.ssh
在 vi 中按 i 进入编辑模式,粘贴整行公钥,按 Esc,输入 :wq 回车保存。最后 ls -l 应看到 authorized_keys 权限为 -rw-------,属主是你本人。
.ssh 目录或 authorized_keys 权限过松时,SSH 会直接拒绝使用它登录,而且往往不给明显报错。目录必须是 700,文件必须是 600,属主必须正确。
先验证密钥能登录,再往下做
ssh study@服务器公网IP
给老师准备巡检账号:装公钥,不送私钥
“把私钥发给老师”是绝对错误的做法。正确思路正好相反:让老师拥有自己的密钥对,你只把老师的公钥装到服务器上。公钥可以公开,没有老师的私钥,别人拿到也进不来。
sudo adduser teacher
sudo mkdir -p /home/teacher/.ssh
sudo vi /home/teacher/.ssh/authorized_keys
sudo chmod 700 /home/teacher/.ssh
sudo chmod 600 /home/teacher/.ssh/authorized_keys
sudo chown -R teacher:teacher /home/teacher/.ssh
teacher 没有设置密码,而 wheel 组使用 sudo 必须输入本人密码,所以要给这个巡检账号单独配置免密 sudo:
echo "teacher ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/teacher
sudo chmod 440 /etc/sudoers.d/teacher
sudo visudo -c
sudo -u teacher sudo -n true && echo "teacher 免密 sudo 可用"
这里安装的是老师的公钥,不是你的公钥,别搞混。你的私钥自始至终只留在自己的电脑上。sudoers 配置写错会让所有账号的 sudo 失效,所以务必执行 visudo -c 检查;万一出错,用 VNC 以 root 登录修复。
04收紧 sshd 配置
密钥验证通过后,才开始“收口”。修改 SSH 服务端主配置文件:
sudo vi /etc/ssh/sshd_config
找到并修改以下项目,没有的就新增:
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers study teacher
| 配置 | 作用 | 风险提示 |
|---|---|---|
PubkeyAuthentication yes | 允许密钥登录,是本章加固的基础 | 保持开启 |
PasswordAuthentication no | 禁止密码登录,杜绝猜密码 | 必须确认密钥能登录后再改 |
PermitRootLogin no | 禁止 root 直接远程登录,缩小攻击面 | 需要管理时先登普通用户再 sudo |
MaxAuthTries 3 | 单次连接最多 3 次认证尝试 | 拖慢暴力破解 |
ClientAliveInterval 300 | 每 300 秒探测客户端是否还在 | 配合下一项清理空闲会话 |
ClientAliveCountMax 2 | 连续 2 次无响应就断开 | 自动释放挂着的连接 |
AllowUsers study teacher | 登录白名单,只允许这两个账号 | 写错用户名或漏掉 teacher 会把人挡在门外 |
改完不要直接重载。先测试语法,确认无误再让配置生效:
sudo sshd -t
sudo systemctl reload sshd
到这里,服务器已经从“谁都能来猜密码”,变成了“只有持有私钥的白名单用户才能进入”。
05两道门:安全组与主机防火墙
云服务器与普通物理机最大的不同,是它有两层防火墙,而且要分别配置。两层都遵循同一个原则:最小化,只开必须的门。
安全组
阿里云平台层防火墙,管公网流量能不能进入实例。
firewalld
操作系统内部防火墙,管流量到达实例后放不放行到具体服务。
两层都要开
只配一层,服务仍然可能进不来;两层相互独立。
主机防火墙:放行 SSH
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
改规则必须加 --permanent,再执行 --reload。否则规则只在当前运行状态生效,重启后就没了。
安全组:保留 SSH,删掉不必要的开放端口
- 必须保留 SSH(TCP 22):本机 SSH 客户端和控制台 Workbench 都走它,删掉会同时中断这两条路。
- 删除或收紧任何用不到的开放端口。
- ICMP-IPv4 规则可以保留,用于 ping 连通性诊断。
安全组按“协议 + 端口”控制。TCP/UDP 才有端口概念,SSH 写 TCP 22、HTTP 写 TCP 80;ICMP 是网络层诊断协议,本身不使用端口,所以控制台只能填 -1/-1 或显示“任何”。它不代表所有端口都被打开,放行 ICMP 只是允许别人 ping 通你,不能登录、不能传数据。
把服务器实际监听的端口与安全组对照,确认没有多开:
sudo ss -tlnp
-t 只看 TCP,-l 只看监听状态,-n 用数字显示不做域名解析,-p 显示占用端口的进程。
06让服务器自动反击:fail2ban
前面的加固都是“被动防守”。fail2ban 会持续盯登录日志,发现某个 IP 反复失败,就自动封禁一段时间。服务器从“守得住”升级为“会还手”。
sudo dnf install -y epel-release
sudo dnf install -y fail2ban
规范做法是在 jail.d/ 下新建 .local 文件,而不是直接改主配置 jail.conf。这样软件升级时自己的规则不会被覆盖。
sudo vi /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
backend = systemd
maxretry = 3
findtime = 600
bantime = 3600
这五行连起来就是一句话:10 分钟内失败 3 次,就把这个 IP 封禁 1 小时。
Rocky 9 的日志由 systemd 统一管理,必须写 backend = systemd。网上很多旧教程还在读 /var/log/secure,那种写法在这里不生效。
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
如果封禁名单暂时为空,不代表配置失败,只说明这台机器还没被扫描器盯上。规则已经生效,挂一段时间自然会出现记录。
07验证与自救
“能跑起来”不等于“做对了”。逐项确认:
- VNC 能以
study登录,tty显示/dev/tty1 - 本机
ssh study@公网IP能登录,且不要密码 - 用密码登录会被拒绝
- root 无法直接远程登录
sshd -t没有报错firewall-cmd --list-all能看到 ssh,且没有多余端口fail2ban-client status sshd显示规则运行中- teacher 已装老师的公钥,老师能凭自己的私钥登录
sudo -u teacher sudo -n true成功
| 现象 | 多半原因 | 怎么处理 |
|---|---|---|
| SSH 连不上 | sshd 配置改坏,或 22 端口被挡 | 用阿里云控制台 VNC 登录,把 sshd_config 改回,再 sshd -t、reload |
| 密钥登录仍要密码 | 目录或文件权限不对,属主不是本人 | 检查 ~/.ssh 为 700、authorized_keys 为 600,且属主正确 |
| 老师连不上 | AllowUsers 漏了 teacher,或 .ssh 属主不对 |
补白名单,chown -R teacher:teacher /home/teacher/.ssh |
| 所有账号 sudo 都失效 | sudoers 语法错误 | VNC 以 root 登录,修正或删除 /etc/sudoers.d/teacher,再 visudo -c |
| 防火墙规则重启后消失 | 忘了 --permanent 或 --reload |
按“永久写入 → 重载”的顺序重做 |
小结这一讲真正要带走的
- 两个入口:SSH 受 sshd 和安全组影响,VNC 才是独立后路。
- 两把锁:密钥登录 + 最小化放行;安全组和 firewalld 两层都要配。
- 一个习惯:私钥永不外传,改配置先留后路,先验证再收口。