在Ubuntu服务器上,直接禁用root账户的远程SSH登录并切换到密钥认证,是每一位运维人员必须做的基础安全加固操作。具体做法分三步走:第一步,创建一个普通用户并配置SSH密钥;第二步,修改sshd配置文件禁用root登录并启用密钥认证;第三步,测试新用户登录确认无误后,再彻底锁定root远程访问。这套操作做完,你的服务器被暴力破解的概率会降低90%以上。

很多人觉得这事儿复杂,其实就是改几行配置文件的事。下面我把每一步拆开来讲,包括容易踩的坑、为什么要这么做、以及怎么验证你的配置是否生效。不管你是刚接触Linux的新手还是有经验的运维,跟着做一遍就能掌握。

为什么必须禁用root远程SSH登录

root是Linux系统的超级管理员账户,拥有最高权限。如果允许root通过SSH远程登录,意味着攻击者只要猜对密码就能直接控制整台服务器。现实中,全球每天都有大量自动化脚本在扫描开放了22端口的服务器,专门尝试用常见密码暴力破解root账户。一旦被攻破,后果不堪设想——数据泄露、被植入挖矿程序、被当作跳板攻击内网,都是常见的情况。

禁用root远程登录的核心逻辑是:让攻击者连"门"都找不到。你不开放root的SSH通道,他就算扫描到你的服务器,也只能面对普通用户账户,而普通用户权限有限,就算被攻破,损失也可控。再配合密钥认证,连密码都不需要了,暴力破解这条路基本就被堵死了。

第一步:创建普通用户并生成SSH密钥对

在操作之前,你需要先通过当前能登录的方式(可能是控制台、可能是现有的root SSH会话)进入服务器。假设你现在还能以root身份登录,先创建一个日常使用的普通用户。

adduser deployuser

执行这条命令后,系统会提示你设置密码、填写用户信息等。密码可以设一个复杂的,但后面我们会用密钥登录,这个密码其实只是备用。

接下来给这个用户配置sudo权限,方便后续管理操作:

usermod -aG sudo deployuser

然后切换到这个新用户,生成SSH密钥对。在你本地电脑(不是服务器)上执行:

ssh-keygen -t ed25519 -C "your_email@example.com"

这里推荐用ed25519算法,比传统的RSA更安全、密钥更短、速度更快。执行后会提示你保存路径,默认保存在~/.ssh/id_ed25519,直接回车就行。是否设置密码短语(passphrase)看你自己,设了更安全但每次用密钥要多输一次密码。

生成完成后,你本地会有两个文件:id_ed25519(私钥,绝对不能泄露)和id_ed25519.pub(公钥,要放到服务器上)。把公钥传到服务器:

ssh-copy-id deployuser@你的服务器IP

如果ssh-copy-id命令不可用,手动操作也行:

cat ~/.ssh/id_ed25519.pub | ssh deployuser@你的服务器IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

这一步完成后,你应该能用新用户通过密钥登录服务器了。先别急着禁用root,先测试一下新用户能不能正常登录。

第二步:修改SSH配置文件禁用root登录

确认新用户密钥登录正常后,回到服务器,用root或者有sudo权限的用户编辑SSH守护进程的配置文件:

sudo nano /etc/ssh/sshd_config

找到以下几个关键配置项,逐一修改:

# 禁用root远程登录
PermitRootLogin no

# 禁用密码认证,强制使用密钥
PasswordAuthentication no

# 确保公钥认证是开启的
PubkeyAuthentication yes

# 指定 authorized_keys 文件位置
AuthorizedKeysFile .ssh/authorized_keys

# 可选:限制只允许特定用户登录(更严格的做法)
# AllowUsers deployuser

特别注意几点:PermitRootLogin一定要设成no,这是核心;PasswordAuthentication设成no意味着所有用户都只能用密钥登录,没有密码回退;如果你想保留密码登录作为备用(不推荐但有些场景需要),可以把这个设成yes,但至少root不能用密码登录。

还有一个容易忽略的点:如果你的配置文件里有多个PermitRootLogin的设置(比如被注释掉的旧配置),只有最后一个生效。所以建议用grep检查一下:

grep -i "PermitRootLogin" /etc/ssh/sshd_config

确保输出结果只有一行且值为no。

第三步:重启SSH服务并验证配置

配置改完后,必须重启SSH服务才能生效:

sudo systemctl restart sshd

重启之前,强烈建议你不要关闭当前的SSH会话!万一配置有误导致新连接被拒绝,你还能通过当前会话修复。这是无数人踩过的坑——改完配置直接关窗口,结果再也连不上了。

打开一个新的终端窗口,尝试用新用户和密钥登录:

ssh -i ~/.ssh/id_ed25519 deployuser@你的服务器IP

如果能正常登录,说明配置成功。登录后用sudo执行一些管理命令验证权限是否正常:

sudo apt update
sudo systemctl status nginx

然后再试一下root能不能通过SSH登录——应该是直接被拒绝的。你可以用verbose模式查看详细连接过程:

ssh -v root@你的服务器IP

如果看到类似"Permission denied (publickey)"或者直接连接被断开,说明root远程登录已经被成功禁用。

进阶加固:不止于禁用root

禁用root远程登录只是第一层防护。要让服务器真正安全,还需要做以下几件事:

第一,修改SSH默认端口。22端口是所有扫描脚本的首选目标,改成一个不常用的高位端口(比如22222)能过滤掉大部分自动化攻击:

Port 22222

改完后记得在防火墙里放行新端口:

sudo ufw allow 22222/tcp

第二,配置fail2ban自动封禁暴力破解IP。这个工具会监控SSH登录失败日志,短时间内失败次数过多的IP会被自动加入防火墙黑名单:

sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

第三,禁用SSH的旧版本协议。在sshd_config中确保只使用协议2:

Protocol 2

第四,设置登录超时和最大尝试次数,减少被爆破的窗口:

LoginGraceTime 30
MaxAuthTries 3

这意味着登录过程只给30秒,最多尝试3次就断开连接。

密钥管理的注意事项

密钥认证虽然安全,但如果私钥管理不当,同样会出问题。几个必须遵守的原则:

私钥永远不要上传到任何服务器、不要发给别人、不要存在网盘里。本地保存时确保权限正确:

chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh

如果你有多台服务器需要管理,建议每台服务器用不同的密钥对,或者至少用同一个私钥对应不同的公钥文件。这样万一某台服务器的公钥泄露,不会影响其他服务器。

定期轮换密钥也是好习惯。每隔几个月生成新的密钥对,把旧的从authorized_keys中删除。特别是员工离职、设备更换的时候,必须立即撤销旧密钥。

常见问题排查

操作过程中可能遇到的问题及解决办法:

问题一:改完配置后SSH连不上了。原因通常是配置语法错误或者权限问题。解决办法:通过服务器提供商的控制台(VNC/网页终端)登录,检查/var/log/auth.log看具体报错,用sshd -t命令测试配置文件语法是否正确。

sudo sshd -t

问题二:密钥登录提示权限被拒绝。检查服务器端authorized_keys文件权限是否为600,.ssh目录权限是否为700,用户家目录权限不能是777。

问题三:sudo命令提示不在sudoers文件中。确认用户是否正确加入了sudo组,可以用visudo检查/etc/sudoers文件。

问题四:防火墙阻断了新端口。如果改了SSH端口但没在ufw或iptables里放行,连接会超时。先确认防火墙规则:

sudo ufw status verbose
总结与最佳实践

Ubuntu服务器安全加固的核心思路就是"最小权限原则"——只开放必要的访问方式,只给必要的权限。禁用root远程SSH登录配合密钥认证,是这套思路最直接的落地操作。整个过程不超过十分钟,但能挡住绝大多数自动化攻击。

记住一个原则:永远不要在没有测试的情况下关闭当前会话。永远保留一种能登录服务器的方式(控制台、VNC等),防止把自己锁在外面。安全和可用性之间需要平衡,但在SSH这件事上,安全永远优先。

把这套操作变成你部署新服务器时的标准流程,写进你的运维文档里。每一台新上线的Ubuntu服务器,都应该在第一时间完成这些配置。这不是可选项,是必选项。