1. 为什么 root 登录这件事值得单独拿出来说
很多人第一次接触 Linux 服务器,拿到手的是一台刚装好系统的机器,用普通用户登进去,想改个配置文件,终端立刻甩回来一句Permission denied。这时候脑子里蹦出来的第一个念头就是:我要用 root。于是开始搜"Ubuntu 怎么用 root 登录",搜出来的答案五花八门,有让你改/etc/ssh/sshd_config的,有让你passwd root的,还有让你直接sudo -i的。问题是,这些操作各自解决的是不同层面的问题,混在一起用,轻则白折腾,重则把机器锁死。
我自己前前后后管过几十台 Ubuntu 机器,从 16.04 一路用到 24.04,root 登录这个需求踩过的坑不算少。这篇文章就把这件事彻底讲清楚:Ubuntu 默认为什么不让 root 直接登录、有哪几种"以 root 身份工作"的方式、每种方式适合什么场景、具体怎么配、配完怎么验证、出问题怎么救回来。不管你是刚买了个云主机的新手,还是天天跟服务器打交道的老手,这里面的细节应该都能对上你的实际需求。
需要先明确一个概念:"root 登录"其实分两个层面。一个是本地终端或图形界面用 root 账号登录,另一个是远程通过 SSH 用 root 账号登录。这两个层面的配置完全独立,很多人搞混了,改了 SSH 配置却发现本地还是登不进去,或者本地设了密码却远程连不上,根源就在这里。下面我会把这两条线分开讲,最后再给一套我自己常用的组合方案。
2. Ubuntu 默认禁用 root 登录的底层逻辑
2.1 从安全模型说起:为什么默认不给 root 密码
Ubuntu 跟很多其他 Linux 发行版不一样的地方在于,安装的时候压根不让你设置 root 密码。这不是 bug,是 Canonical 有意为之的设计。root 账号在系统里是存在的,UID 是 0,权限最大,但它的密码字段被设成了一个特殊的锁定状态,你没法直接用密码登录。
这么设计的原因很直白:root 权限太大,一旦密码泄露或者被暴力破解,攻击者拿到的是整台机器的完全控制权,删库、装后门、当跳板,什么都干得出来。而普通用户即使密码泄露,攻击者还得再过一道sudo提权的坎,而sudo的每一次提权都是有日志记录的,可追溯。
Ubuntu 给出的替代方案是sudo。普通用户通过sudo临时获得 root 权限执行单条命令,用完即失效。这个模型的好处是:日常操作不需要 root 密码,敏感操作有审计日志,而且可以精细控制哪个用户能执行哪些命令。你可以把sudo理解成一把"临时钥匙",而不是把整串"万能钥匙"挂在门上。
2.2 root 账号的密码字段到底长什么样
想验证这一点,你可以用普通用户执行:
sudo passwd -S root输出大概是这样:
root L 01/01/2024 0 99999 7 -1第二列那个L就是 Locked 的意思,表示 root 账号的密码被锁定了。这时候你就算知道 root 的密码(其实根本没有密码),也没法用密码登录。这个锁定状态是 Ubuntu 安装器在装系统时自动设置的。
有意思的是,root 账号本身并没有被禁用,只是密码登录这条路被堵死了。你依然可以通过sudo切换到 root,或者用su配合其他方式。理解这一点很关键,因为它决定了你后面所有操作的边界。
2.3 三种"以 root 身份工作"的方式对比
在动手改配置之前,先搞清楚你真正需要的是哪种。很多人一上来就改 SSH 配置,其实他可能只需要sudo -i就够了。我把三种常见方式列个表对比一下:
| 方式 | 命令 | 是否需要 root 密码 | 是否影响远程登录 | 适用场景 |
|---|---|---|---|---|
| sudo 提权 | sudo command | 否,用当前用户密码 | 否 | 日常单条命令 |
| sudo 切换 shell | sudo -i或sudo su - | 否,用当前用户密码 | 否 | 需要连续执行多条 root 命令 |
| 直接 root 登录 | su -或 SSH root | 是,需要 root 密码 | 是(SSH 需额外配置) | 特定运维场景、自动化脚本 |
看清楚这张表,你就明白为什么很多人折腾半天没效果——他想要的是第三种,但只做了第一种的操作。下面我按"本地 root 登录"和"远程 SSH root 登录"两条线分别展开。
3. 本地终端启用 root 登录的完整操作
3.1 给 root 设置密码:第一步也是最容易翻车的一步
本地启用 root 登录,核心就一条命令:
sudo passwd root系统会提示你输入当前用户的密码(因为用了 sudo),然后让你给 root 设置新密码,要求输入两次。这里有几个细节值得说:
第一,密码强度不是闹着玩的。root 密码一旦设置,本地登录就靠它了。如果你设个123456,那跟没设一样。我一般建议至少 12 位,大小写字母加数字加符号混着来。别嫌麻烦,这是你机器的最后一道门。
第二,输入密码时终端不会有任何回显。这是 Linux 的惯例,不是键盘坏了,正常输入回车就行。新手经常在这里以为没反应,反复敲,结果密码输错。
第三,设置成功后,root 账号的锁定状态就解除了。你可以再用sudo passwd -S root验证一下,那个L应该变成了P(Password set)。
注意:给 root 设密码这个操作本身不会自动让 SSH 允许 root 登录。它只解决"本地能不能用 root 密码登录"的问题。远程 SSH 是另一套配置,别搞混。
3.2 验证本地 root 登录是否生效
设完密码,别急着关掉当前会话,先验证。开一个新的本地终端(或者按 Ctrl+Alt+F3 切到 tty 字符终端),尝试:
su -系统会提示输入 root 密码,输对了就会看到提示符从$变成#,这就说明本地 root 登录成功了。注意su -后面的那个短横线很重要,它表示加载 root 的完整登录环境(包括 PATH、环境变量等),不加横线的话你拿到的还是当前用户的环境,容易出各种诡异问题。
如果你是在图形界面下,有些桌面环境(比如 GNOME)默认不允许 root 登录图形会话,这是另一层限制,需要额外配置。不过说实话,图形界面用 root 登录的需求很少,绝大多数场景字符终端就够了。
3.3 一个容易被忽略的坑:sudoers 文件
有一种情况会让sudo passwd root直接失败:当前用户不在 sudoers 列表里。报错信息大概是:
xxx is not in the sudoers file. This incident will be reported.这时候你连 sudo 都用不了,得先想办法把当前用户加进 sudo 组。如果你还有另一个能 sudo 的账号,用它执行:
sudo usermod -aG sudo 你的用户名如果所有账号都不能 sudo,那就得进恢复模式(Recovery Mode)或者用 Live USB 挂载系统盘来修了。这个坑我在一台二手服务器上踩过,前任管理员把唯一的 sudo 账号删了,最后是进 GRUB 恢复模式搞定的。所以记住:改任何跟权限相关的配置之前,确保你至少留一条能回去的路。
4. 远程 SSH 允许 root 登录的配置细节
4.1 修改 sshd_config:找到那个关键的 PermitRootLogin
远程 root 登录的核心配置在/etc/ssh/sshd_config这个文件里。用你习惯的编辑器打开:
sudo nano /etc/ssh/sshd_config找到PermitRootLogin这一行。在较新的 Ubuntu 版本里,这行可能是被注释掉的,也可能是prohibit-password。这个参数有几个可选值,含义差别很大:
| 参数值 | 含义 | 是否允许 root 密码登录 |
|---|---|---|
yes | 允许 root 用任何方式登录 | 是 |
prohibit-password | 允许 root 登录但禁止密码方式 | 否(只能用密钥) |
forced-commands-only | 只允许执行指定命令 | 否 |
no | 完全禁止 root 登录 | 否 |
很多人以为改成yes就完事了,其实prohibit-password才是很多发行版的默认值,它允许 root 用密钥登录但禁止密码登录。如果你只想用密钥登录 root,保持这个值就行,不用改。如果你确实要用密码登录 root,才需要改成yes。
改完之后,保存退出。但先别急着重启 SSH 服务,这里有个大坑。
4.2 改配置前必须做的保命操作
我见过太多人改完 sshd_config 直接systemctl restart ssh,然后发现新配置有问题,SSH 连不上了,只能去机房或者找云服务商的控制台。避免这个悲剧的方法很简单:
第一,改配置前先备份:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak第二,改完后先测试配置语法:
sudo sshd -t这个命令会检查配置文件有没有语法错误,没输出就说明语法没问题。如果有错误,它会告诉你哪一行有问题,赶紧改回来。
第三,不要关闭当前 SSH 会话。重启 SSH 服务后,用一个新的终端窗口去连,确认能连上,再关掉旧窗口。这样万一新配置有问题,你旧窗口还开着,可以马上改回来。
第四,重启服务用 reload 而不是 restart(如果支持的话):
sudo systemctl reload sshreload是平滑重载配置,不会断开现有连接;restart会彻底重启服务,现有连接会断。虽然大多数情况下 restart 也没事,但 reload 更稳妥。
4.3 防火墙和云平台安全组的双重检查
配置改对了,服务也重启了,结果还是连不上?八成是防火墙或者云平台安全组的问题。这是新手最容易忽略的一层。
本地防火墙方面,Ubuntu 默认用的是 ufw。检查一下 22 端口有没有放行:
sudo ufw status如果显示Status: inactive,那防火墙没开,不是它的问题。如果开着,确认 22 端口是 ALLOW 状态。没放行的话:
sudo ufw allow 22/tcp云平台方面,如果你用的是云主机,除了系统内的防火墙,云服务商那边还有一层安全组(Security Group)或者网络 ACL。这一层是在系统外面的,你在机器里怎么改都影响不到它。需要登录云服务商的控制台,找到对应实例的安全组规则,确认 22 端口(或者你自定义的 SSH 端口)对你的来源 IP 是放行的。
我遇到过最离谱的一次,是安全组规则里 22 端口只对某个特定 IP 段开放,而我换了办公地点,IP 变了,自然连不上。排查了半天才想起来看安全组。所以记住这个排查顺序:SSH 配置 → 系统防火墙 → 云平台安全组,一层层往下查。
5. 密钥登录 root:比密码更靠谱的方案
5.1 为什么我更推荐密钥而不是密码
说实话,在生产环境里用 root 密码登录,我一直不太放心。密码这东西,只要存在,就有被暴力破解、被键盘记录、被肩窥的风险。而密钥登录从根本上解决了这个问题:私钥在你手里,公钥在服务器上,没有私钥谁也进不来。
配置 root 密钥登录的步骤不复杂。首先在本地生成一对密钥(如果你还没有的话):
ssh-keygen -t ed25519 -C "root@myserver"ed25519是目前推荐的算法,比传统的 RSA 更短更安全。一路回车就行,默认会生成~/.ssh/id_ed25519(私钥)和~/.ssh/id_ed25519.pub(公钥)。
然后把公钥传到服务器的 root 账号下:
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@服务器IP这一步需要你先能用某种方式登录 root(比如临时开了密码登录)。传完之后,root 的~/.ssh/authorized_keys里就有了你的公钥。
5.2 配置 sshd 只允许密钥登录 root
公钥传好后,把 sshd_config 里的PermitRootLogin设成prohibit-password:
PermitRootLogin prohibit-password这个配置的意思是:允许 root 登录,但只能用密钥,不能用密码。这样既满足了 root 登录的需求,又堵死了密码暴力破解这条路。我个人觉得这是安全性和便利性平衡得最好的方案。
同时建议把密码认证整个关掉(如果你所有账号都用密钥的话):
PasswordAuthentication no改完记得sudo sshd -t测试,然后sudo systemctl reload ssh。
5.3 密钥登录的常见故障排查
密钥登录配好了却连不上,报Permission denied (publickey),这种情况我遇到过好几次,原因基本集中在几个地方:
权限问题是最常见的。SSH 对密钥文件的权限要求很严格,太开放会直接拒绝。检查这几项:
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_ed25519服务器端的~/.ssh和authorized_keys权限不对,SSH 会静默拒绝,日志里才看得到原因。用sudo tail -f /var/log/auth.log盯着日志连一次,问题一目了然。
SELinux 或 AppArmor在某些配置下也会拦截,不过 Ubuntu 默认的 AppArmor 一般不影响 SSH 密钥。如果你是从 CentOS 转过来的,可能会习惯性怀疑 SELinux,但 Ubuntu 上这个概率很低。
公钥内容不完整也是个坑。有时候复制粘贴公钥,末尾换行丢了,或者中间断了,都会导致认证失败。用cat ~/.ssh/authorized_keys确认一下内容完整,一行一个公钥,别有多余的空格或换行。
6. 实操心得与避坑清单
6.1 我踩过的几个真实坑
坑一:改了配置忘了 reload。这个听起来很蠢,但真的经常发生。改完 sshd_config,测试也过了,就是忘了systemctl reload ssh,然后对着旧配置排查半天。养成习惯:改完配置立刻 reload,然后新开窗口验证。
坑二:root 密码设了但 SSH 还是连不上。这就是前面说的,本地 root 密码和 SSH root 登录是两回事。设了密码只解决本地登录,SSH 还得改PermitRootLogin。
坑三:云主机安全组没放行。这个坑我踩过不止一次,尤其是换了网络环境之后。排查 SSH 连不上,一定要把安全组纳入检查范围。
坑四:把唯一的 sudo 账号搞没了。有次手贱,把一个用户的 sudo 权限删了,结果那台机器上就剩这一个能登录的账号。最后是进 GRUB 恢复模式,用mount -o remount,rw /重新挂载根分区,再改 sudoers 文件救回来的。所以改权限配置前,永远确保还有另一条能进系统的路。
6.2 一份可以直接抄的检查清单
每次配置 root 登录,我都会按这个清单过一遍:
- 确认当前用户有 sudo 权限(
sudo -l能列出东西) - 备份 sshd_config(
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak) - 修改
PermitRootLogin为目标值 - 测试语法(
sudo sshd -t) - 平滑重载(
sudo systemctl reload ssh) - 新开终端验证连接
- 检查系统防火墙(
sudo ufw status) - 检查云平台安全组
- 确认密钥权限(如果用密钥登录)
- 保留旧会话直到新连接验证成功
这份清单看着啰嗦,但每一步都是血泪教训换来的。尤其是第 10 条,我现在的习惯是:改任何远程连接相关的配置,旧窗口绝对不关,直到新窗口连上为止。
6.3 关于安全的一点个人看法
最后聊点实在的。root 登录这件事,便利性和安全性天然是矛盾的。全开 root 密码登录,方便是方便,但风险也实打实。我的建议是分场景:
- 个人测试机、内网机器:怎么方便怎么来,root 密码登录开着也无所谓,反正外面进不来。
- 有公网 IP 的服务器:强烈建议用密钥登录,
PermitRootLogin设成prohibit-password,密码认证关掉。如果非要用密码,至少把 SSH 端口从 22 改成一个不常见的端口,能挡掉一大批自动化扫描。 - 生产环境:root 直接登录能不开就不开,用普通用户加 sudo,配合密钥和审计日志。真需要 root 操作,
sudo -i足够了。
还有个小技巧:如果你确实需要 root 密码登录,但又担心暴力破解,可以装个fail2ban,它会在多次登录失败后自动封禁来源 IP。配置不复杂,效果立竿见影。这个我后面可以单独写一篇,这里就不展开了。
说到底,root 登录只是手段,不是目的。搞清楚你真正要解决的问题是什么,再选对应的方案,比盲目照搬网上的教程靠谱得多。我见过太多人为了"用 root 登录"而用 root 登录,结果把一台好好的服务器配得千疮百孔。工具本身没有对错,关键看你怎么用。