"你,服务器连上了就完事了吗?"
——AptS:1547(看着满屏幕的 SSH 暴力破解日志)
恭喜你,你已经成功连上了你的第一台服务器。
你激动地在终端里输入命令,感受着"掌控一台远程机器"的快感。你可能装了个 Nginx,跑了个 Hello World,甚至给朋友炫耀了一下"看我的网站上线了"。
然后你关掉了 SSH,去睡觉了。
第二天早上,你发现你的服务器 CPU 跑满了。再仔细一看,日志里全是来自世界各地的登录尝试:莫斯科的、印度的、巴西的……他们在用各种用户名和密码尝试暴力破解你的服务器。
欢迎来到互联网的真实世界。
一、你的服务器,正在被全世界扫描
别以为你的服务器藏在某个角落就安全了。
事实上,你的服务器刚上线的那一刻,全世界的扫描器就已经盯上它了。这不是危言耸听,你可以自己看看日志:
sudo grep "Failed password" /var/log/auth.log | tail -20
你会看到类似这样的输出,满屏幕都是失败的登录尝试,来自世界各地的 IP,用着各种常见用户名——root、admin、ubuntu、test——配合着更常见的弱密码——123456、password、admin123。
这些攻击者大多数不是针对你的,他们只是在扫描整个互联网,寻找那些防护薄弱的服务器。就像小偷在一条街上挨家挨户试门把手,看看哪家没锁门。
如果你用的是弱密码,或者 root 用户可以直接登录,那你的服务器基本上就是在"裸奔"。一旦被攻破,你的服务器可能被用来挖矿、发起 DDoS 攻击、发送垃圾邮件,甚至成为攻击其他服务器的跳板。
更糟糕的是,一旦服务器被黑,你可能永远都拿不回控制权。
二、加固服务器安全,是必选项而不是可选项
你可能会说:"我的服务器上又没什么重要数据,被黑了也无所谓。"
真的吗?
黑客拿到你的服务器后,可以用它来挖矿,CPU 跑满,电费爆炸。可以用它发起攻击,你的 IP 被各大网站列入黑名单。可以用它发送垃圾邮件,云服务商直接把你账号封了。
而且,服务器被黑之后,黑客通常会安装后门,即使你重置了密码,他们还是能进来。到最后,你只能重装系统,之前部署的服务全部丢失。
所以,别心存侥幸。从一开始就把安全做好,比事后补救要省心得多。
三、安全加固的核心思路
在正式动手之前,我们先明确一个思路:安全加固不是做一次就完事,而是层层防护。
你可以把服务器安全想象成一个城堡的防御体系。城门(SSH)要加固,城墙(防火墙)要竖起来,还要有巡逻兵(监控)和陷阱(Fail2ban)。哪怕有一道防线被突破,还有其他防线可以顶住。
我们要做的,就是建立这样一套"纵深防御"体系,让攻击者即使想进来,也要付出远超预期的代价。
好了,废话不多说,我们开始动手。
四、第一道防线:禁用 root 登录
在上一篇文章的结尾,我们提到了 root 用户的危险性。现在我们要做的第一件事,就是彻底禁用 root 用户通过 SSH 登录。
为什么要这么做?因为 root 是 Linux 系统的超级管理员,拥有绝对的、不受限制的权限。你可以删除任何文件,修改任何配置,哪怕把整个系统删掉也不会有任何警告。
更重要的是,root 是黑客攻击的首要目标。所有的暴力破解脚本第一个尝试的用户名就是 root。如果你的 root 密码不够强,或者用的是弱密码,那服务器被攻破只是时间问题。
正确的做法是创建一个普通用户,日常操作用它。需要管理员权限时,在命令前加 sudo,系统会要求你输入密码确认。这样既多了一层保护,又能记录所有管理员操作,出了问题可以追溯。
创建新用户并授予 sudo 权限
如果你在上一篇文章中还没创建新用户,现在就创建一个:
# 创建新用户(把 yourusername 换成你想要的用户名)
sudo useradd -m -s /bin/bash yourusername
# 给这个用户 sudo 权限
sudo usermod -aG sudo yourusername
# 如果你是 RHEL 发行版及衍生版本(Alma、Rocky、CentOS),请使用这个命令
sudo usermod -aG wheel yourusername
这里的 -aG sudo 意思是把用户加入 sudo 用户组。Ubuntu 系统中,sudo 组的成员可以通过 sudo 命令获取管理员权限。
测试新用户是否能正常登录
在禁用 root 之前,一定要先确认新用户能正常登录。 这一步非常重要,否则你会把自己锁在门外。
打开一个新的终端窗口(不要关闭当前的 SSH 连接),尝试用新用户登录:
ssh yourusername@123.45.67.89
登录成功后,测试一下 sudo 权限:
# Debian 及衍生版
sudo apt update
# RHEL 及衍生版
sudo dnf update
如果系统要求你输入密码,并且能正常执行,说明新用户配置成功了。
禁用 root 登录
现在我们可以放心地禁用 root 登录了。编辑 SSH 配置文件:
sudo nano /etc/ssh/sshd_config
找到这一行(可能在文件的中间位置):
#PermitRootLogin yes
把它改成:
PermitRootLogin no
注意要把前面的 # 去掉,表示启用这个配置。保存文件后(Ctrl+O 保存,Ctrl+X 退出),重启 SSH 服务:
sudo systemctl restart sshd
重要提醒:在重启 SSH 服务之前,确保你有另一个终端窗口保持连接。如果配置错了导致无法登录,你还能在旧连接里改回来。
验证 root 是否真的被禁用了
打开一个新的终端窗口,尝试用 root 登录:
ssh root@123.45.67.89
如果看到 Permission denied,或者根本不让你输入密码,说明禁用成功了。
从现在开始,你只能用普通用户登录服务器了。这样,即使有人知道了你的 root 密码,也无法直接登录。
五、第二道防线:使用 SSH 密钥认证
密码认证有两个致命问题:密码可能被暴力破解,也可能被键盘记录器窃取。
SSH 密钥认证比密码安全得多。 密钥对通常是 2048 位或 4096 位的,暴力破解几乎不可能。而且私钥保存在你的电脑上,不会在网络上传输,即使有人抓包也拿不到你的私钥。
生成 SSH 密钥对
如果你还没有 SSH 密钥,在本地电脑上运行以下命令:
ssh-keygen -t ed25519 -C "your_email@example.com"
这里我们用的是 Ed25519 算法,它比传统的 RSA 更安全、更快。-C 参数是添加一个注释,方便你识别这个密钥是干什么的。
如果你的系统不支持 Ed25519(比如很老的系统),可以用 RSA:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
运行后,会提示你输入保存路径和密码。路径直接回车使用默认值就好。密码(passphrase)强烈建议设置一个,这样即使私钥被盗,也无法直接使用。
生成完成后,你会得到两个文件:~/.ssh/id_ed25519(私钥)和 ~/.ssh/id_ed25519.pub(公钥)。私钥千万不要泄露,公钥可以随便分享。
把公钥复制到服务器
最简单的方法是使用 ssh-copy-id 命令:
ssh-copy-id yourusername@123.45.67.89
这条命令会自动把你的公钥添加到服务器的 ~/.ssh/authorized_keys 文件中。
如果你的系统没有 ssh-copy-id 命令(比如 Windows),可以手动复制。先在本地电脑上查看公钥内容:
cat ~/.ssh/id_ed25519.pub
复制输出的内容,然后 SSH 登录到服务器,执行:
mkdir -p ~/.ssh
echo "这里粘贴你的公钥内容" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
这里的 chmod 命令是设置文件权限。SSH 对权限要求很严格,如果权限不对,密钥认证会失败。
测试密钥登录
打开一个新的终端窗口,尝试用密钥登录:
ssh yourusername@123.45.67.89
如果一切正常,你应该不需要输入密码(或者只需要输入私钥的 passphrase)就能直接登录。
禁用密码登录
确认密钥登录正常后,我们可以彻底禁用密码登录了。再次编辑 SSH 配置文件:
sudo nano /etc/ssh/sshd_config
找到并修改以下几行:
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
如果这些行前面有 #,记得删掉。保存后,重启 SSH 服务:
sudo systemctl restart sshd
再次提醒:在重启之前,确保你有另一个终端窗口保持连接,并且已经测试过密钥登录正常。
从现在开始,你的服务器只能通过密钥登录了。暴力破解脚本再怎么尝试密码,也无法进入你的服务器。
六、第三道防线:修改 SSH 端口
SSH 默认使用 22 端口,这也是攻击者扫描的首要目标。
修改 SSH 端口可以大幅减少被扫描的频率。虽然这不能阻止有针对性的攻击(攻击者可以扫描所有端口),但可以过滤掉大部分自动化扫描脚本。就像你把家门从一楼搬到了二楼,那些只会敲一楼门的小偷自然就找不到你了。
选择一个新端口
选择一个 1024 到 65535 之间的端口,避免使用常见端口(如 8080、3306、3389)。比如我们选择 37324。
修改 SSH 配置
编辑 SSH 配置文件:
sudo nano /etc/ssh/sshd_config
找到这一行:
#Port 22
改成:
Port 37324
记得把前面的 # 去掉。
配置防火墙(重要!)
在重启 SSH 服务之前,一定要先开放新端口,否则你会把自己锁在门外。 这一步非常关键,很多新手就是因为忘了这一步,最后只能通过云服务器控制台登录来修复。
如果你用的是 UFW(Ubuntu 默认防火墙),先检查一下防火墙状态:
sudo ufw status
如果显示 Status: inactive,说明防火墙还没启用。我们先开放新端口,然后再启用防火墙:
# 开放新端口
sudo ufw allow 37324/tcp
# 如果防火墙没启用,现在启用它
sudo ufw enable
如果你用的是 CentOS/RHEL 系统,防火墙是 firewalld:
# 开放新端口
sudo firewall-cmd --permanent --add-port=37324/tcp
sudo firewall-cmd --reload
# 如果防火墙没启用,现在启用它
sudo systemctl enable --now firewalld
CentOS/RHEL 用户还需要配置 SELinux:
如果你用的是 CentOS 或 RHEL,系统默认开启了 SELinux(Security-Enhanced Linux)。SELinux 是一个额外的安全层,它会严格控制每个程序能做什么。虽然它很安全,但也很烦人——你改了 SSH 端口,防火墙也放行了,但 SELinux 还是会拦住你。
想要被 SELinux 给折磨吗
你需要告诉 SELinux:"嘿,37324 端口也是 SSH 端口,别拦它。"命令如下:
# 查看当前 SSH 允许的端口
sudo semanage port -l | grep ssh
# 添加新端口到 SSH 端口列表
sudo semanage port -a -t ssh_port_t -p tcp 37324
如果提示 semanage 命令不存在,需要先安装:
sudo yum install policycoreutils-python-utils -y
添加完成后,可以再次查看确认:
sudo semanage port -l | grep ssh
你应该能看到 37324 已经被添加到 SSH 端口列表中了。
云服务器用户注意:如果你用的是云服务器(如腾讯云、阿里云),还需要在控制台的"安全组"中开放 37324 端口。不同云服务商的操作略有不同,但基本都是在"网络与安全"相关的菜单里。
重启 SSH 服务
防火墙配置好之后,才能放心地重启 SSH 服务:
sudo systemctl restart sshd
测试新端口
打开一个新的终端窗口,用新端口登录:
ssh -p 37324 yourusername@123.45.67.89
如果能正常登录,说明修改成功了。之后每次登录都要加 -p 37324 参数,或者在本地 SSH 配置文件中设置默认端口。
简化登录(可选)
每次都要输入 -p 37324 很麻烦,我们可以在本地电脑的 SSH 配置文件中设置默认参数。编辑(或创建)~/.ssh/config 文件:
nano ~/.ssh/config
添加以下内容:
Host myserver
HostName 123.45.67.89
User yourusername
Port 37324
IdentityFile ~/.ssh/id_ed25519
保存后,你就可以直接用 ssh myserver 登录了,不需要每次都输入 IP、端口、用户名。
七、第四道防线:配置防火墙
防火墙是服务器的第一道物理防线,它决定哪些流量可以进入服务器,哪些流量要被拒绝。
默认策略应该是拒绝所有流量,只放行必要的端口。 这就像你家的大门,默认是锁着的,只有钥匙对的人才能进来。
Ubuntu 用户:使用 UFW
UFW(Uncomplicated Firewall)是 Ubuntu 自带的防火墙工具,非常简单易用。
先检查防火墙状态:
sudo ufw status
如果显示 Status: inactive,我们现在就来配置它。
首先设置默认策略:拒绝所有入站流量,允许所有出站流量。
sudo ufw default deny incoming
sudo ufw default allow outgoing
这意思是,所有从外面进来的连接默认都会被拒绝,除非你明确允许。而你的服务器主动发起的连接(比如访问网站、下载软件包)都是允许的。
然后允许你需要的端口。比如我们修改后的 SSH 端口:
sudo ufw allow 37324/tcp
如果你要跑 Web 服务,还需要允许 HTTP 和 HTTPS:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
配置好之后,启用防火墙:
sudo ufw enable
启用时会提示你"可能会断开现有连接",不用担心,只要你已经开放了 SSH 端口,就不会断开。
查看防火墙规则:
sudo ufw status verbose
CentOS/RHEL 用户:使用 firewalld
CentOS 和 RHEL 系统使用 firewalld 作为防火墙。
先检查防火墙状态:
sudo systemctl status firewalld
如果没有启动,先启动它:
sudo systemctl enable --now firewalld
允许 SSH 端口(你修改后的端口):
sudo firewall-cmd --permanent --add-port=37324/tcp
如果你要跑 Web 服务,允许 HTTP 和 HTTPS:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
重载配置:
sudo firewall-cmd --reload
查看防火墙规则:
sudo firewall-cmd --list-all
八、第五道防线:安装 Fail2ban 防止暴力破解
即使你修改了 SSH 端口、使用了密钥认证,仍然会有攻击者尝试暴力破解。
Fail2ban 是一个自动化工具,它会监控日志文件,如果发现有 IP 在短时间内多次尝试登录失败,就会自动封禁这个 IP。 就像你家门口装了个摄像头,发现有人连续试门把手,就自动报警并锁死大门。
安装 Fail2ban
在 Ubuntu/Debian 系统上:
sudo apt update
sudo apt install fail2ban -y
在 CentOS/RHEL 系统上:
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
配置 Fail2ban
Fail2ban 的默认配置在 /etc/fail2ban/jail.conf,但我们不应该直接修改这个文件(因为更新时会被覆盖)。正确的做法是创建一个 jail.local 文件:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
找到 [sshd] 部分,修改如下:
[sshd]
enabled = true
port = 37324
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
这个配置的意思是:如果一个 IP 在 10 分钟内(findtime)尝试登录失败 3 次(maxretry),就封禁这个 IP 1 小时(bantime)。
注意:port 要改成你修改后的 SSH 端口。logpath 在 Ubuntu/Debian 上是 /var/log/auth.log,在 CentOS/RHEL 上是 /var/log/secure。
启动 Fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
查看 Fail2ban 状态
# 查看 Fail2ban 运行状态
sudo systemctl status fail2ban
# 查看 SSH 监狱的状态
sudo fail2ban-client status sshd
查看被封禁的 IP
sudo fail2ban-client status sshd
如果你不小心把自己封禁了(比如测试时输错密码太多次),可以手动解封:
sudo fail2ban-client set sshd unbanip YOUR_IP
九、第六道防线:配置自动更新
软件漏洞是服务器被攻破的常见原因之一。
操作系统和软件包经常会发现新的漏洞,开发者会发布补丁来修复这些漏洞。如果你不及时更新,你的服务器就相当于一直开着一扇破洞的窗户,等着黑客进来。
配置自动更新可以让系统自动安装安全补丁,省去了手动维护的麻烦。
Ubuntu 用户:使用 unattended-upgrades
Ubuntu 有一个叫 unattended-upgrades 的包,可以自动安装安全更新。
安装它:
sudo apt update
sudo apt install unattended-upgrades -y
配置自动更新:
sudo dpkg-reconfigure --priority=low unattended-upgrades
会弹出一个对话框,选择 "Yes" 启用自动更新。
默认配置会自动安装安全更新,一般不需要修改。如果你想自定义更新策略,可以编辑配置文件 /etc/apt/apt.conf.d/50unattended-upgrades。
CentOS/RHEL 用户:使用 yum-cron
CentOS 和 RHEL 系统使用 yum-cron 来实现自动更新。
安装它:
sudo yum install yum-cron -y
编辑配置文件:
sudo nano /etc/yum/yum-cron.conf
找到这一行:
apply_updates = no
改成:
apply_updates = yes
启动 yum-cron:
sudo systemctl start yum-cron
sudo systemctl enable yum-cron
十、第七道防线:监控异常登录
即使做了这么多防护,你仍然需要定期检查服务器是否有异常登录。
安全不是一次性的配置,而是一个持续的过程。 就像你家里装了防盗门、摄像头,但还是要定期检查有没有异常情况。
查看最近的登录记录
查看成功登录的记录:
last -20
这会显示最近 20 次成功登录的记录,包括用户名、登录时间、IP 地址。
查看失败登录的记录:
sudo grep "Failed password" /var/log/auth.log | tail -20
如果看到大量失败的登录尝试,说明有人在尝试暴力破解。如果 Fail2ban 配置正确,这些 IP 应该会被自动封禁。
查看当前登录的用户
who
或者用 w 命令,可以看到更详细的信息(包括他们在做什么):
w
如果发现有不认识的用户在线,立即采取行动。你可以强制踢出他们:
sudo pkill -u username
然后立即修改密码、检查系统是否被植入后门。
十一、常见问题 & 排坑指南
问题一:"我把自己锁在门外了,怎么办?"
症状:修改 SSH 配置后,无法登录服务器。
原因:可能是没有保留旧的 SSH 连接,或者防火墙配置错误,或者 SSH 配置写错了。
解决方案:
如果你用的是云服务器,可以通过控制台的 VNC 或者"远程连接"功能登录,然后修改配置。不同云服务商的叫法不一样,腾讯云叫"登录",阿里云叫"远程连接",AWS 叫"EC2 Serial Console"。
如果是物理服务器……那你只能去机房插键盘了。
预防方法:
修改 SSH 配置之前,保持至少一个 SSH 连接不断开。这样即使新配置有问题,你还能用旧连接改回来。
修改防火墙规则前,先确认新规则正确,再启用防火墙。
问题二:"Fail2ban 把我自己封禁了"
症状:在测试时输错密码太多次,Fail2ban 把你的 IP 封禁了,无法登录。
原因:Fail2ban 不认识你是主人,只认识规则。
解决方案:
用另一个没被封禁的 IP 登录(比如手机热点),或者通过云服务器控制台登录,然后执行:
sudo fail2ban-client set sshd unbanip YOUR_IP
预防方法:
在配置 Fail2ban 时,把你自己的 IP 加入白名单。编辑 /etc/fail2ban/jail.local,在 [DEFAULT] 部分添加:
ignoreip = 127.0.0.1/8 YOUR_IP
把 YOUR_IP 换成你的真实 IP。
问题三:"UFW 启用后,SSH 断开了"
症状:启用 UFW 后,SSH 连接立即断开,无法重新连接。
原因:没有在启用 UFW 之前开放 SSH 端口。
解决方案:
通过云服务器控制台登录,然后执行:
sudo ufw allow 37324/tcp
sudo ufw reload
把 37324 换成你的 SSH 端口。
预防方法:
在启用 UFW 之前,先开放 SSH 端口,再启用防火墙。
问题四:"修改 SSH 端口后,旧连接断开了就再也连不上"
症状:修改 SSH 端口后,旧的连接断开了,用新端口也连不上。
原因:可能是防火墙没有开放新端口,或者云服务商的安全组没有配置。
解决方案:
通过云服务器控制台登录,检查防火墙规则和云服务商的安全组配置。
十二、小结:你已经建立了一套基础防御体系
到这里,你已经完成了服务器安全的基础加固。
你建立了一套七层防御体系:禁用 root 登录、使用 SSH 密钥认证、修改 SSH 端口、配置防火墙、安装 Fail2ban、配置自动更新、监控异常登录。这些措施可以抵御 90% 以上的自动化攻击。
但请记住,安全是一个持续的过程,而不是一次性的配置。 你需要定期查看日志,发现异常行为;定期更新系统和软件包;关注安全漏洞公告,及时修补。
还有一点很重要:定期备份重要数据。 即使做了这么多防护,也不能保证 100% 不被攻破。如果真的出事了,至少你还有备份可以恢复。
但先别急着部署网站!虽然你已经做了安全加固,用过 nano 编辑文件、用过 systemctl 管理服务,但那些都是"照着做"。你可能根本不知道这些命令到底是什么意思,也不知道遇到问题该怎么排查。
在下一篇中,我们将系统学习 Linux 命令行。从最基础的"我在哪"开始,到文件管理、权限控制、进程管理,让你真正掌握命令行操作。这样等你部署网站的时候,才不会迷路。
敬请期待下一章:
《从零开始的服务器冒险 – Linux 命令行入门: 从迷路到精通》
本系列文章由 AptS:1547 编写,基于个人经验与公开资料整理。
如果你在加固服务器时遇到了问题,欢迎在评论区交流
(虽然我也不一定能帮你解决)QWQ

发表回复