1. 为什么“默认禁用root登录”这件事值得单独拿出来讲
很多人第一次在虚拟机或云主机上装完Ubuntu,想用root账号直接登录,结果发现要么密码根本不知道,要么SSH连上去就被拒绝。这不是系统坏了,而是Ubuntu从设计之初就做了一个明确的安全取舍:默认不启用root账户的密码登录,也不允许root通过远程方式直接登录。这个策略在桌面版和服务器版上都存在,只是表现形式不太一样。
我见过不少刚接触Linux的朋友,遇到权限不够就习惯性敲sudo su,敲完发现还要输当前用户密码,觉得麻烦,于是想干脆把root打开算了。这个想法本身没错,但“打开root登录”这件事在不同场景下做法完全不同:你是想在本地终端直接以root身份登录,还是想通过远程连接工具用root账号连进来?这两种需求的配置路径、风险等级、后续维护方式都不一样。如果混为一谈,很容易出现“本地能登、远程登不上”或者“改完配置重启后系统进不去”的尴尬局面。
这篇文章面向的是有一定Linux基础、但没系统整理过root登录配置的读者。我会把本地TTY登录、远程SSH登录、以及“只想要root权限但不想开root账号”这三种常见诉求拆开讲清楚,每一步都说明为什么这么做、改的是哪个文件、改完怎么验证、出问题怎么回滚。全文基于Ubuntu 20.04/22.04/24.04这几个长期支持版本的通用实践,不同版本之间如果有差异我会单独标注。
注意:开启root登录会显著降低系统的抗风险能力。如果你的机器暴露在公网环境,强烈建议优先考虑用普通用户加sudo的方式完成日常运维,而不是直接把root推到前台。
2. 先把概念理清:root账户、sudo、su、SSH到底谁管谁
在动手改配置之前,有必要把几个容易混淆的概念摆清楚。很多人配置失败不是因为命令敲错了,而是因为没搞明白这几个东西各自负责什么环节。
2.1 root账户在Ubuntu里的特殊状态
Linux系统里root是超级用户,UID为0,拥有对系统所有文件和进程的完全控制权。但在Ubuntu的默认安装中,root账户是被“锁定”的——注意,是锁定而不是删除。所谓锁定,是指root的密码字段被设成了一个无效值,任何密码都无法通过验证。你可以用下面这条命令查看root账户状态:
sudo passwd -S root输出里如果看到L,就代表locked(已锁定)。这时候你没法用root密码登录,也没法用su -切换到root,因为su需要验证root密码。但系统里所有需要root权限的操作并没有消失,它们是通过sudo机制来完成的。
2.2 sudo和su的本质区别
su是switch user的缩写,默认切到root,需要输入目标用户的密码。sudo则是以其他用户身份执行单条命令,默认以root身份执行,需要输入的是当前用户自己的密码。Ubuntu默认把安装时创建的第一个用户加入sudo组,这个组的成员可以通过sudo临时获得root权限。
这里有个关键点:sudo的授权是“按命令”的,而su的授权是“按会话”的。你sudo su之后得到的那个root shell,本质上还是通过sudo提权拿到的,跟直接用root密码登录是两码事。理解这一点,后面配置SSH的PermitRootLogin时就不会迷糊。
2.3 SSH的登录控制和系统账户控制是两层
远程连接工具连上服务器时,走的是SSH协议。SSH服务端有自己的配置文件,里面有一个PermitRootLogin指令,控制是否允许root通过SSH登录。这个指令和root账户本身是否解锁是相互独立的。也就是说,可能出现下面四种组合:
| root账户状态 | PermitRootLogin | 结果 |
|---|---|---|
| 锁定 | 任意值 | root无法通过密码登录,因为密码无效 |
| 已解锁 | no | root有密码,但SSH拒绝root登录 |
| 已解锁 | yes | root可以通过SSH密码登录 |
| 已解锁 | prohibit-password | root可以用密钥登录,但不能用密码 |
很多教程只讲了改PermitRootLogin,却没提root账户可能还是锁定状态,结果读者改完SSH配置发现还是登不上,白白折腾半天。所以正确的顺序应该是:先决定要不要解锁root账户,再决定SSH层面怎么放行。
3. 本地终端以root身份登录的完整操作路径
先讲本地场景。所谓本地,是指你坐在机器前面,或者通过虚拟化平台的控制台直接操作,不经过SSH。这个场景下要让root能登录,核心就一件事:给root设置一个有效密码。
3.1 给root账户设置密码并解锁
在Ubuntu里,给root设密码这个动作本身就会解锁账户。命令很简单:
sudo passwd root系统会提示你输入新的root密码,并要求确认。这里有个细节值得注意:passwd命令在设置密码时会做简单的强度检查,太短的、纯数字的、跟用户名相同的密码会被拒绝。这是PAM模块在起作用,不是命令本身的问题。如果你确实需要设置一个符合特定策略的密码,可以先用sudo passwd -S root确认状态,设完之后再查一次,看到P就代表密码已设置、账户已解锁。
设完之后,你可以在本地终端用su -测试:
su -输入刚设置的root密码,如果提示符从$变成#,说明本地root登录已经通了。这里用su -而不是su,是因为带横杠会加载root的完整登录环境,包括环境变量和家目录,更接近真正的root登录体验。
3.2 为什么有些桌面版还需要额外处理显示管理器
如果你用的是Ubuntu桌面版,想在登录界面直接选root账户登录图形界面,那上面这一步还不够。GNOME显示管理器默认会隐藏root账户,而且很多桌面环境明确禁止root登录图形会话。这个限制来自/etc/gdm3/custom.conf或者相应的显示管理器配置,不同版本位置不一样。
我的建议是:不要在桌面版上折腾root图形登录。桌面环境本身依赖大量用户级配置和会话组件,用root跑图形界面容易出各种权限错乱,比如配置文件属主变成root导致普通用户下次登录异常。如果你只是想要root权限,在终端里sudo -i就够了,没必要把整个图形会话都变成root。
3.3 本地root登录后的环境差异
用root登录后,你会发现环境变量和普通用户不一样。最明显的是PATH,root的PATH里通常包含/sbin和/usr/sbin,而普通用户的PATH默认不含这些目录。这就是为什么有些系统管理命令普通用户直接敲会提示找不到,加sudo或者切到root就能用。
另外,root的家目录是/root,里面的配置文件(比如.bashrc)和普通用户的是分开的。如果你在root下配了别名或者环境变量,切回普通用户是不生效的。这个细节在排查“为什么同一个命令在不同用户下行为不一样”时特别有用。
提示:本地root登录配置完成后,建议至少保留一个可用的sudo用户作为后备。万一root密码忘了或者配置出错,还能用sudo用户救回来。
4. 远程SSH允许root登录:改哪个文件、改哪一行、怎么验证
远程场景是大多数人真正关心的。配置SSH允许root登录,涉及两个层面:root账户本身要可用,SSH服务端要放行。上一节已经讲了怎么解锁root账户,这一节重点讲SSH配置。
4.1 SSH服务端配置文件的结构
Ubuntu上SSH服务端的配置文件是/etc/ssh/sshd_config。这个文件里跟root登录直接相关的指令是PermitRootLogin。在较新的Ubuntu版本中,这个指令的默认值通常是prohibit-password,意思是允许root用密钥登录,但禁止密码登录。
你可以用下面这条命令查看当前生效的值:
sudo sshd -T | grep permitrootlogin注意sshd -T输出的是最终生效的配置,它会合并主配置文件和sshd_config.d/目录下的片段。Ubuntu 22.04之后,很多配置被拆到了/etc/ssh/sshd_config.d/下的独立文件里,直接改主文件可能被后面的片段覆盖。这是很多人改了配置不生效的头号原因。
4.2 修改PermitRootLogin的两种做法及取舍
第一种做法是直接编辑主配置文件:
sudo nano /etc/ssh/sshd_config找到PermitRootLogin那一行,改成:
PermitRootLogin yes第二种做法是在sshd_config.d/目录下新建一个片段文件,比如/etc/ssh/sshd_config.d/99-root-login.conf,内容写:
PermitRootLogin yes我更推荐第二种。原因是主配置文件在系统升级时可能被包管理器提示冲突,而独立片段文件不会。而且片段文件的加载顺序靠文件名排序,用99-前缀可以保证它排在后面,覆盖前面的设置。改完之后一定要用sshd -T再确认一次最终值,别只看文件里写了什么。
4.3 改完配置后的验证与重载
SSH配置改完后不能直接重启服务就完事,正确流程是:
- 先用
sudo sshd -t做语法检查,没输出就代表语法没问题。 - 再
sudo sshd -T | grep permitrootlogin确认最终生效值。 - 然后
sudo systemctl reload ssh重载配置。用reload而不是restart,是因为reload不会断开已有连接,万一新配置有问题,你当前这个SSH会话还在,可以马上改回来。
这里有个血泪教训:如果你在远程SSH会话里改配置,千万不要在验证之前关闭当前会话。正确的做法是另开一个终端窗口尝试用root登录,确认能登上之后,再关掉旧会话。我见过有人改完直接exit,结果新配置有问题,root登不上、普通用户也被影响,只能去虚拟化控制台救火。
4.4 密码登录和密钥登录的额外开关
就算PermitRootLogin设成了yes,如果SSH服务端全局禁用了密码认证,root照样没法用密码登录。控制密码认证的指令是PasswordAuthentication。你可以用sudo sshd -T | grep passwordauthentication查看。如果它是no,那所有用户的密码登录都被禁了,root也不例外。
这种情况下你有两个选择:要么把PasswordAuthentication改成yes(不推荐,会降低整体安全性),要么给root配置SSH密钥登录。密钥登录的配置跟普通用户一样,把公钥追加到/root/.ssh/authorized_keys,权限设成600,.ssh目录设成700。注意root的家目录是/root,别写到普通用户目录去了。
5. 比“开root登录”更值得考虑的替代方案
讲完怎么开root登录,我得说句实在话:在绝大多数生产环境里,直接开root远程登录都不是最优解。下面这几个替代方案,能达到同样的操作效率,但风险低得多。
5.1 sudo -i 与 sudo su - 的差别
日常运维中,如果你只是想要一个root shell,sudo -i是最干净的方式。它会加载root的登录环境,相当于一次完整的root登录,但走的是sudo授权通道,不需要root密码,也不需要开SSH的root登录。sudo su -也能达到类似效果,但多了一层su的调用,环境变量继承上略有差异。
这两个命令的区别在排查环境问题时很重要。sudo -i模拟的是登录shell,会读取/root/.profile等文件;sudo su -虽然也带横杠,但中间经过了su,某些环境下环境变量会有细微不同。我个人的习惯是统一用sudo -i,行为最可预期。
5.2 用普通用户加sudo规则实现精细化授权
如果你的诉求是“让某个账号能执行特定管理命令”,那完全不需要开root。可以在/etc/sudoers.d/下建一个文件,给指定用户或组授权特定命令,甚至配置成免密码。比如:
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx这样deploy用户只能免密重启nginx,其他操作还是要密码。这种精细化授权比直接给root账号安全得多,也更容易审计。改sudoers文件一定要用visudo或者visudo -f指定文件,因为它会做语法检查,避免写错导致sudo完全不可用。
5.3 密钥登录加禁用密码的组合
如果确实需要root远程登录,最稳妥的组合是:root账户解锁、PermitRootLogin设为prohibit-password、给root配好密钥、全局PasswordAuthentication设为no。这样root只能用密钥登录,暴力破解密码的路子直接被堵死。密钥的位数建议用ed25519或者至少4096位的RSA,私钥一定要加passphrase保护。
这个组合的配置顺序是:先给root配密钥并验证能登录,再改PermitRootLogin,最后关密码认证。顺序反了的话,可能出现密钥还没配好、密码认证已经关了,直接把自己锁在外面。
6. 配置过程中最容易翻车的几个点
这一节是我自己踩过和见别人踩过的坑的汇总,按出现频率排序。
6.1 改了sshd_config.d里的文件但被主文件覆盖
前面提过,Ubuntu新版把配置拆到了sshd_config.d/目录。但主配置文件sshd_config里如果也有PermitRootLogin,而且Include指令的位置在文件末尾,那片段文件会覆盖主文件;如果Include在前面,主文件反而会覆盖片段。判断依据是sshd_config里Include那一行的位置。最保险的做法是改完用sshd -T看最终值,不要猜。
6.2 root密码设了但SSH还是拒绝
这种情况通常是PermitRootLogin没改,或者改错了文件。还有一种可能是SELinux或AppArmor在拦截,不过Ubuntu默认用AppArmor,对SSH的root登录一般不做额外限制。排查顺序是:先sshd -T确认配置,再看/var/log/auth.log里的具体拒绝原因,日志里会写清楚是密码错误还是配置拒绝。
6.3 改完配置重启SSH导致当前会话断开
用systemctl restart ssh会断开所有现有连接,包括你正在操作的那个。如果新配置有问题,你就失去了远程访问能力。所以永远用reload,并且另开会话验证。如果已经断开了,只能通过虚拟化平台的控制台或者物理终端去救。
6.4 忘记保留sudo用户导致无法提权
有些人为了“彻底用root”,把普通用户从sudo组里移除了。结果root密码又忘了,或者root登录配置有问题,就彻底没法提权了。恢复方法是重启进入恢复模式,以root身份挂载文件系统后修改。这个过程比较繁琐,最好的办法就是别把自己逼到那一步——永远保留至少一个可用的sudo用户。
7. 配置完成后的验证清单与回滚思路
配置做完不算完,得有一套验证和回滚的方案,心里才踏实。
7.1 分层验证的具体命令
验证要分三层:账户层、SSH配置层、实际连接层。
账户层用sudo passwd -S root确认是P状态。SSH配置层用sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'确认最终生效值。实际连接层就是另开终端,用ssh root@目标地址实测,能登上且权限正确才算通。
如果用了密钥,还要确认/root/.ssh/authorized_keys的权限是600,/root/.ssh是700,/root本身不能是组可写的。SSH对权限检查很严格,权限不对会直接拒绝密钥认证,而且日志里的提示比较隐晦,容易误判成密钥本身的问题。
7.2 出问题时的回滚顺序
万一配置完发现有问题,回滚顺序跟配置顺序相反:先恢复SSH配置(把PermitRootLogin改回去,reload),再考虑要不要重新锁定root账户。如果只是SSH登不上但本地能操作,优先从本地改。如果本地也进不去,就得走恢复模式。
恢复模式的大致流程是:重启时在GRUB菜单选恢复模式,进入root shell,然后mount -o remount,rw /把根文件系统挂成可写,改完配置再重启。不同版本的GRUB界面略有差异,但思路一致。这个操作有一定门槛,建议提前在测试环境练一遍。
7.3 长期维护的建议
root登录配置不是一劳永逸的。系统大版本升级时,SSH配置可能被包管理器重置或提示合并,sshd_config.d/下的自定义片段一般会保留,但主文件里的改动可能丢失。所以每次升级后,建议重新跑一遍sshd -T确认关键指令的值。另外,如果团队里有多人需要root权限,与其共享root账号,不如每人一个sudo账号,出问题能追溯到人。
我个人在实际操作中的体会是,root登录这件事,能不开就不开,非开不可就只开密钥、不开密码,并且一定要留好后路。配置本身不难,难的是对风险的预判和出问题时的自救能力。把验证和回滚方案提前准备好,比配置本身更重要。