news 2026/10/17 9:01:46

Ubuntu开启root远程登录:SSH配置详解与安全加固指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ubuntu开启root远程登录:SSH配置详解与安全加固指南

1. Ubuntu为什么默认锁死root远程登录

拿到一台全新的Ubuntu服务器,很多人第一件事就是拿旧环境的root密码去SSH登录,结果迎面一句Permission denied。这真不是密码输错了,Ubuntu在root账号和SSH服务两个层面各自设了一道锁,两道锁叠在一起,才形成了你看到的“死局”。想打开root登录,得先把这两道锁的来龙去脉弄清楚。

1.1 root账号本身没有密码

Ubuntu安装过程中并不会让你设置root密码,系统装完之后,root账号实际上处于“锁定”状态,日常操作一律通过sudo完成。这是从其他发行版转过来的用户最容易忽略的一环:别的系统装完可以直接root登录,Ubuntu这里连在本地终端里输入root密码都是进不去的。

你可以用下面这条命令查看root账号的真实状态:

sudo passwd -S root

正常情况下输出结果类似这样:

root L 01/01/2024 -1 -1 -1 -1 0000 -1

看到大写字母L,说明root账号是锁定的。想解锁,最直接的方式就是给它设置一个密码:

sudo passwd root

这一步是整个流程的前提条件。如果root没有可用密码,就算后面把sshd配置改成PermitRootLogin yes,登录时也会提示密码认证失败,因为系统里压根不存在可以通过认证的root密码。

1.2 sshd层面还有第二道闸门

即使root有了密码,SSH服务端默认也不会放行。OpenSSH从7.0版本开始,把PermitRootLogin的编译默认值改成了prohibit-password,含义是:允许root使用公钥登录,但禁止root使用密码登录。Ubuntu自带的/etc/ssh/sshd_config里也保留了对应注释行:

#PermitRootLogin prohibit-password

注意这一行是被注释掉的,也就是说系统没有做显式配置,但OpenSSH内部默认值就是prohibit-password,实际效果等同于启用了这一行。网上不少教程说“取消注释改成yes就行”,这只说对了一半——配置文件改了,但root没有密码,照样进不去。

所以完整的逻辑是:先在系统层面给root准备一个可用的认证方式,也就是密码或公钥,再在sshd层面放开root登录权限。两个条件缺一不可。下面我会先从密码登录这条线路把整套流程跑通,再说怎么收尾加固。

2. 动手之前:版本确认、密码准备和配置备份

改SSH配置属于高危操作,出问题直接连不上机器。每次动手之前,我会老老实实花上几分钟做环境确认和备份,这些习惯能帮我省掉大量排错时间。

2.1 先花两分钟确认系统和SSH版本

确认Ubuntu版本:

cat /etc/os-release

确认OpenSSH版本:

sshd -V

目前主流的Ubuntu 20.04、22.04、24.04都适用我下面要讲的配置方式,更早的16.04、18.04也能用,只是在新版本新增的Include目录和云镜像预置配置上略有差异,排查章节我会单独展开。版本信息记下来,后续看日志、查文档时心里有数。

2.2 给root设置密码,这一步很多人会漏

前面说过,Ubuntu默认root是锁定状态。执行:

sudo passwd root

系统会要求先输入当前sudo用户的密码,然后连续两次输入root的新密码。看到passwd: password updated successfully就说明设置成功,账号也随之解锁。这里有个容易误解的点:sudo passwd root和sudo passwd -l root是相反操作,前者是设密码、解锁,后者是给密码字段加锁标记、锁定账号。如果你之前做过安全加固锁过root,后面无论怎么改sshd配置都不可能用密码登录,排查时别忘了这一层。

2.3 备份配置,并注意Include目录的覆盖规则

改配置前备份是基本操作,别嫌多余。我在每台服务器上都这么干:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)

备份文件名带日期,方便日后回滚时快速识别。

另一个重要细节:Ubuntu 22.04及之后版本的sshd_config开头通常会有一行:

Include /etc/ssh/sshd_config.d/*.conf

这句话会让/etc/ssh/sshd_config.d/目录下所有.conf文件参与配置合并。由于Include出现在文件最顶部,按OpenSSH“先到先得的参数生效规则”,这个目录里的配置优先级反而高于主配置文件后面写的任何内容。云厂商的Ubuntu镜像经常会在该目录下放一个50-cloud-init.conf,里面可能写着PasswordAuthentication yes或PermitRootLogin no之类的覆盖项。如果后面怎么改主配置都不生效,先去这个目录翻一翻,问题多半出在这里。

2.4 留一条绝对安全的回退通道

改SSH配置时最怕的是:自己在服务器上改了配置并重启服务,结果新配置有语法错误导致服务起不来,自己又被踢出会话,只能眼巴巴地去控制台抢救。我的习惯是动手之前确保至少还有一个已登录的SSH会话窗口不关闭,或者确认自己能打开云厂商的网页控制台。配合下面要讲的语法检查,基本就不会把自己锁在门外。

3. PermitRootLogin四种取值,选哪个直接决定能否登录

这是整篇文章最核心的参数。PermitRootLogin共有四种取值,每一种的行为差异很大,网上很多教程把它们混在一起讲,我整理了一张对照表。

3.1 四种取值的真实行为对比

取值密码登录公钥登录实际含义
yes允许允许完全放开,所有认证方式都接收
prohibit-password禁止允许密码方式对root关闭,公钥照常,OpenSSH 7.0起的内置默认值
without-password禁止允许prohibit-password的旧写法,语义相同,现在仍兼容
no禁止禁止彻底关闭root远程登录,完全锁死

如果你只想跑通“root能用密码直接SSH”,那就要改成yes。但我要提醒一句:让root密码直接暴露在公网SSH端口上,等于给全世界的扫描器留了一个极其显眼的目标。我更推荐的做法是先用yes把流程验证通过,确认没问题后马上改回prohibit-password,只保留公钥认证这一条路。后面我专门用一节讲加固,这里先把能跑通的配置做出来。

3.2 prohibit-password和without-password的纠葛

很多老教程写的是without-password,新文档里写的是prohibit-password,这俩其实是同一个意思,只是OpenSSH在不同版本换了更明确的叫法。without-password字面上容易让人误解成“不需要密码”,实际是“不允许root用密码登录”,只允许密钥。看到老配置里有这个值时别慌,直接改成新写法prohibit-password或者保持原样都可以,行为不会变。

还有一个冷知识:在OpenSSH 7.0之前,PermitRootLogin的默认值其实是yes,也就是老系统默认允许root密码登录。如果你维护的是一台很老的服务器,需要先确认它实际用的OpenSSH版本再判断默认行为,不要想当然。

3.3 密码登录的总开关PasswordAuthentication

很多人只盯着PermitRootLogin,忽略了另一个总开关PasswordAuthentication。真正的密码认证流程要求两个参数同时放行:PermitRootLogin yes决定root能不能登录,PasswordAuthentication yes决定系统允不允许使用密码这种认证方式。

看两个组合就清楚了:

  • PermitRootLogin yes+PasswordAuthentication yes:root可以用密码登录。
  • PermitRootLogin prohibit-password+PasswordAuthentication yes:普通用户可以密码登录,但root不行,root只能用密钥。

Ubuntu默认PasswordAuthentication是开启的,但如果你之前为了安全手动关过它,就算root权限全放开也没用。排查问题时一定要两个参数一起检查。

4. 从改配置到验证登录的完整流程

下面给出一套可以直接照抄的命令流程,以Ubuntu 22.04为例。整套流程的核心思路是“小步走、随时能回退”,每一步都有对应的验证手段。

4.1 修改sshd_config

打开主配置文件:

sudo nano /etc/ssh/sshd_config

找到这一行:

#PermitRootLogin prohibit-password

如果只是想让root能密码登录,把它改成:

PermitRootLogin yes

如果目标是用密钥登录root,改成:

PermitRootLogin prohibit-password

保存退出。注意不要在文件里写多个PermitRootLogin,按先到先得的规则,只有第一个出现的值会生效,多个值只会让后续维护的人一头雾水。改动之前最好再用注释注明改动日期和原因,生产环境的配置文件最怕留无头账。

4.2 重启前必做的语法检查

这一步绝对不能省。执行:

sudo sshd -t

没有任何输出,说明配置语法正确。如果返回类似这样的报错:

/etc/ssh/sshd_config line 32: Bad yes value

说明第32行有拼写或格式问题,回去改好再试。sshd -t只做语法检查,不会影响正在运行的服务,可以反复执行,放心用。它是我在任何一次SSH配置变更前都必须执行的动作,养成习惯之后,因配置写坏导致服务起不来的概率会无限趋近于零。

4.3 重启服务,注意Ubuntu的服务单元名

Ubuntu的SSH服务单元名是ssh.service,不是sshd.service。执行:

sudo systemctl restart ssh

重启后确认状态:

sudo systemctl status ssh

看到active (running)就说明服务正常起来了。如果你在配置里引入了语法错误,这里会直接看到failed状态,这时候用之前的备份文件恢复配置,再重启一次就能救回来。

这里还有个细节值得提一下:systemctl restart ssh是重启,systemctl reload ssh是让服务重新加载配置而不中断现有连接。如果你在服务器上还有别的重要会话,用reload更温和。但为了确保配置彻底生效,我一般还是用restart,因为有些参数在reload时并不会重新读取。

4.4 用新终端的实际登录作为最终验证

在你自己的电脑上打开一个新终端,执行:

ssh root@<服务器IP>

输入刚设置的root密码,能进入root shell就说明整条链路已经打通。如果提示Permission denied,先别慌,下一节就是完整的排查路径。

验证成功、确认不再需要临时调整后,记得回到配置里把PermitRootLogin改回prohibit-password,再重启一次服务,后续登录就改用密钥。“临时打开-验证-收紧”这套流程,我在很多台服务器上反复实践过,既保证了任务能完成,又把暴露时间压到了最短。

5. 配置改完还是登不进去的排查链路

这一节可能是本文最有实用价值的部分。我见过太多人卡在“明明改对了,也重启了,为什么还是进不去”。这类问题有一个典型的排查顺序,按下面的链路走,通常几分钟就能定位。

5.1 用sshd -T查看实际生效值

不要只盯着配置文件,要确认sshd真正加载了什么。执行:

sudo sshd -T | grep -i permitrootlogin

sshd -T会把最终生效的配置逐项输出,需要root权限才能看全。如果输出结果是prohibit-password,而你明明在文件里写了yes,说明一定有个地方把它覆盖了。优先检查sshd_config顶部的Include行,以及/etc/ssh/sshd_config.d/目录下的所有.conf文件,云镜像里的50-cloud-init.conf是头号嫌疑。这种“配置文件写了但实际没生效”的情况,靠肉眼看文件几乎永远找不出来,用sshd -T一秒钟就现原形。

5.2 检查root密码状态

继续用这一条命令:

sudo passwd -S root

前面说过,看到大写L说明账号锁定。需要重点排查两种场景:一是你从未设置过root密码,二是之前为了安全执行过passwd -l root,后来忘记了。这两种情况下,无论PermitRootLogin设成什么,密码登录都不可能成功。重新执行sudo passwd root设一遍密码即可。

5.3 公钥登录失败的权限排查

如果把PermitRootLogin设成了prohibit-password却依然登录失败,并且错误提示只有Permission denied (publickey),重点检查以下几项:

  • /root目录权限不能是775或777,标准做法是chmod 700 /root;
  • /root/.ssh目录权限必须是700;
  • /root/.ssh/authorized_keys文件权限必须是600;
  • 文件属主必须是root:root。

还有一个常见低级错误:在Windows上生成的公钥粘贴进authorized_keys时带上了多余空格或换行,导致密钥格式损坏。遇到这种情况,可以在服务器端执行:

ssh-keygen -l -f /root/.ssh/authorized_keys

这条命令会列出文件里所有公钥的类型和指纹。如果正常输出,说明密钥格式没问题;如果报错,说明文件内容需要重新整理。

5.4 用auth.log定位问题环节

Ubuntu的SSH登录日志写在/var/log/auth.log:

sudo tail -n 100 /var/log/auth.log

也可以实时跟进:

sudo journalctl -u ssh -f

日志里的几类关键词能帮你快速缩小范围:

  • Failed password for root:密码认证流程已经走通,只是密码不对。
  • user root not allowed because account is locked:认证阶段过了,但系统层账号是锁的。
  • Connection reset by peer:多半是网络或防火墙层面直接掐断了连接,跟SSH配置无关。

日志永远是最直接的排错入口,别一上来就盲目改配置,先看日志能省下大量时间。

6. root登录打开之后的加固方案

配置做完只是第一步,更重要的课题是如何降低风险。root远程登录一旦带着密码开放,任何直接暴露在公网上的服务器都等于挂了个醒目的靶子。我写这篇不是鼓励大家无脑开root,而是要把这个操作的正确姿势讲明白。

6.1 生产环境推荐配置:只开密钥,关掉密码

落地时我会把SSH配置收敛成这个组合:

PermitRootLogin prohibit-password PasswordAuthentication no PubkeyAuthentication yes

这样root只能通过密钥登录,普通用户也不能再使用密码登录,暴力破解的入口基本上被堵死了。如果有多人需要登录服务器,各自把公钥放进~/.ssh/authorized_keys,配合sudo来管理权限,比共享root密码干净太多,出了问题也更好追责。

6.2 用Match限定来源IP

如果某些场景确实需要root能密码登录,也别对所有IP开放。可以限定只有可信来源才能这样做:

PermitRootLogin prohibit-password Match Address 192.0.2.25 PermitRootLogin yes

这段配置的意思是:默认情况下root只能用密钥登录,只有来自192.0.2.25这个IP的会话允许root使用密码。需要特别注意的是,Match块必须放在配置文件末尾,Match之后的所有参数都会作用于匹配到的会话,位置放错了会导致后面的全局配置全部失效。用这个方式,就算密码泄露,攻击者也无法从其他IP利用它登录root。

6.3 用fail2ban把暴力破解挡在门外

给SSH加一道自动封禁的保险丝,我每台公网服务器都会装fail2ban,成本极低:

sudo apt update sudo apt install fail2ban

默认配置就会监控sshd,连续失败次数超过阈值的IP会被临时封禁。想调整参数,编辑/etc/fail2ban/jail.local:

[sshd] enabled = true maxretry = 3 bantime = 3600

重启服务生效。另外,云厂商的安全组或防火墙策略里也建议加一条:SSH端口只对你自己常用的IP段开放。软件层和网络层双保险的效果,远好于只依赖其中任何一个。

6.4 几个我一直在用的日常习惯

root登录打开后,我自己一直坚持这几件事:定期查看/var/log/auth.log里有没有大量Failed password记录;设置root密码时使用足够复杂的强密码,绝不用生日、机器名这类弱口令;长期用不到的root密码登录方式,确认不再需要后立刻重新锁死:

sudo passwd -l root

锁定之后root无法再通过密码远程登录,但sshd服务不受影响,普通用户和已配置好的密钥登录都能继续正常工作。这套习惯让我在维护了多台服务器之后,依然能有效控制root账号的暴露面。

最后说一点我持续在执行的心得。处理过的服务器里,真正长期开着PermitRootLogin yes的基本没有,绝大多数场景下prohibit-password加密钥登录已经足够。遇到必须root直连的初始化任务,我都是临时改为yes、重启、干完活、立刻改回prohibit-password、再重启,整个过程不超过十分钟。这套办法看起来有点繁琐,但帮我躲过了不止一次因配置遗留而引发的暴力破解风险。照着本文的流程走一遍,你也能把“打开root登录”这件事做得既通又稳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 9:01:19

CNN花卉枯萎识别实战:Python与PyTorch完整项目指南

最近帮某学弟看了一个毕设题目&#xff0c;叫“基于Python的CNN卷积神经网络识别花卉是否枯萎”。我第一反应是&#xff0c;这不就是常见的图像二分类吗&#xff1f;后来陪他一路做下来才发现&#xff0c;这类题目看着简单&#xff0c;真正卡人的地方全在细节里——数据集怎么搞…

作者头像 李华
网站建设 2026/10/17 8:59:27

Hadoop伪分布式集群扩展:Kafka与Sqoop集成实战指南

1. 伪分布式集群再扩展&#xff1a;为什么要在已有环境里加Kafka和Sqoop走到这一步&#xff0c;说明你前面已经在一台虚拟机或者Docker容器里把Hadoop伪分布式集群跑起来了&#xff0c;HDFS能存文件&#xff0c;YARN能调度任务&#xff0c;MapReduce也能跑通。这个阶段其实已经…

作者头像 李华
网站建设 2026/10/17 8:59:24

Codex提示Usage Limit?五个隐藏原因排查指南

用Codex跑编程任务&#xff0c;最怕看到的不是代码报错&#xff0c;而是满心欢喜敲下codex&#xff0c;结果屏幕上一行冰冷的"Usage Limit"。更气人的是&#xff0c;你明明刚查过账户&#xff0c;剩余额度还有得剩&#xff0c;根本没有归零。我上个月就被这个问题折腾…

作者头像 李华
网站建设 2026/10/17 8:58:46

superpowers:基于Codex CLI的AI编程增强技能包实战详解

1. 先搞清楚superpowers到底是什么先说结论&#xff1a;superpowers不是某个独立编程语言&#xff0c;也不是一个具体框架&#xff0c;而是一套围绕Codex CLI打造的增强技能包。说得更直白一点&#xff0c;它是一套“给AI编程助手加Buff”的规则、脚本与工作流集合&#xff0c;…

作者头像 李华
网站建设 2026/10/17 8:57:45

eWebEditor V12.0 for ASP多语言商业版实战指南

简介&#xff1a;eWebEditor V12.0 for ASP 多语言商业版是一款面向ASP技术栈Web开发者的专业级在线HTML编辑器&#xff0c;适用于内容管理系统&#xff08;CMS&#xff09;、后台富文本发布模块等场景&#xff0c;帮助开发者快速将传统textarea升级为具备Word级排版能力的可视…

作者头像 李华