如果你刚装完 CentOS 10,打开 Xshell 准备用 root 登录,大概率会遇到这么一幕:IP 填对了,端口是 22,用户名 root,密码敲了几遍,结果要么直接连不上,要么提示 “Permission denied, please try again.”,要么干脆报 “找不到匹配的 host key 算法”。这个标题我太熟了,前后帮人排查过几十次,问题源头其实很集中,但确实有 CentOS 10 系统策略变化和 Xshell 老版本兼容性因素叠加在里面。
这篇东西不会跟你念手册,直接按实际排查顺序走一遍:先讲 CentOS 10 默认为什么不让 root 登录,再讲 Xshell 连不上的各种报错怎么解,然后讲 root 登录成功之后你以为万事大吉、结果还是会被卡住的权限问题,最后附上我建议的日常运维姿势。保证每一步都是你可以直接抄的。
1. 为什么 CentOS 10 默认不让 root 直接登录 SSH
很多人拿到 CentOS 10 的第一反应是:我 root 密码明明设了,为什么 Xshell 就是进不去?别急着怀疑密码,先在服务器本地用 root 登录终端,然后去看 SSH 的配置。CentOS 10 这一代基于 RHEL 10,系统默认把 root 远程 SSH 登录策略改了,改得很隐蔽,以至于我第一次排查时也绕了弯路。
1.1 系统策略:sshd_config.d 里的默认开关
新版 OpenSSH 在 CentOS 10 里的配置结构已经和 CentOS 7/8 时代不一样了。以前你改 /etc/ssh/sshd_config 里的一行 PermitRootLogin yes,重启 sshd 基本就能生效。但 CentOS 10 的 sshd 在启动时会额外读取 /etc/ssh/sshd_config.d/*.conf 这个目录下的所有 .conf 文件,而且会按文件名顺序加载,后面的配置会覆盖前面的。
CentOS 10 默认在这个目录下放了一个 10-permitrootlogin.conf,内容直接写死了 PermitRootLogin prohibit-password。这代表什么?代表 root 允许远程登录,但密码登录是禁止的,只接受密钥认证。这就是绝大多数 Xshell 密码登录失败的真正原因。
这里多说一句,很多老教程还在教你去改主配置文件里的 PermitRootLogin,但只要你没删掉 10-permitrootlogin.conf,你改的那行很可能会被这个文件覆盖。所以排查时别只想着一处配置,打开 sshd 配置之前最好先跑一条命令看实际生效值:
bash复制sshd -T | grep -i permitrootlogin
sshd -T 会输出最终生效的配置,不管主配置和 drop-in 文件怎么叠加,看到的就是 sshd 真正在用的值。如果输出是 permitrootlogin prohibit-password,那你密码登录被拒是正常的,不是密码错了。
1.2 PermitRootLogin 的取值如何影响 Xshell 登录方式
搞清楚这个参数的各种取值,你就能明白不同系统版本的兼容玩法。PermitRootLogin 常见取值有四个:
| 取值 | 含义 | Xshell 密码登录 |
|---|---|---|
| yes | root 可以用密码或密钥登录 | 可以 |
| prohibit-password | root 可以登录,但禁止密码认证,仅限密钥 | 不可以 |
| without-password | 旧写法,和 prohibit-password 等价 | 不可以 |
| no | root 完全禁止登录 | 不可以 |
CentOS 10 默认落在 prohibit-password,所以你在 Xshell 里怎么输密码都白搭。这一步的解决方案后面第 2 章会给出完整命令,这里先记住一点:只要确认是 prohibit-password,那就不存在密码错的问题,是策略挡了你。
1.3 CentOS 10 的 SELinux 默认策略对 SSH 的影响
CentOS 10 的 SELinux 默认是 Enforcing 状态,这个也容易成为隐患。大部分人以为 SELinux 只影响 Web 目录那种场景,其实它和 SSH 也有关系,而且影响方式很隐蔽。
最常见的一个坑是这样:你在系统里把 root 用户的 home 目录搞乱了,或者把 /root 目录的 SELinux 上下文给改了——比如曾经用过 chown、mv、tar 恢复文件之类操作——SSH 连接就会发现家目录上下文不对,直接拒绝读取 authorized_keys,连密码阶段都可能出现诡异行为。
如果你正打算配置密钥登录,改完记得检查一下 SELinux 上下文:
bash复制ls -Zd /root /root/.ssh
正常输出里应该有 home_root_t 和 ssh_home_t 之类的上下文。如果不对,就执行:
bash复制restorecon -Rv /root
另外,如果你改了 SSH 的非标准端口,CentOS 10 默认 SELinux 策略只允许 sshd 监听 22 端口,需要先安装对应工具再添加端口策略:
bash复制dnf install -y policycoreutils-python-utils
semanage port -a -t ssh_port_t -p tcp 2222
不然你防火墙放行了新端口,SSH 依然连不上。这个坑很经典,很多老手也会栽在这。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Xshell 通过密码登录 root:完整配置与踩坑
这一章直接解决“怎么让 Xshell 能用 root 密码登进 CentOS 10”。我不建议一上来就把系统改得千疮百孔,下面几种方法按推荐程度排序,你自己选。
2.1 快速开启 root 密码登录的三种方式
第一种方式最简单,适合个人开发环境、虚拟机、内网测试机。直接创建或修改 drop-in 配置文件,让它覆盖默认策略:
bash复制vim /etc/ssh/sshd_config.d/00-root-login.conf
文件里写:
ini复制PermitRootLogin yes
然后重启 sshd:
bash复制systemctl restart sshd
注意:不是 systemctl restart ssh,CentOS 10 的服务单元名是 sshd.service,写成 ssh 会提示找不到服务。重启后可以用 systemctl status sshd 确认一下状态。
第二种方式是把默认的 10-permitrootlogin.conf 文件里的 prohibit-password 改成 yes,本质上一样,但不如新增一个文件干净,因为系统升级时你的修改很可能被覆盖。
第三种方式就是彻底不用密码登录,直接用密钥。这个我强烈推荐,但如果你现在只求先连上去,用第一种方式先开通,后面再按第 4 章的密钥方案收紧。
2.2 “找不到匹配的 host key 算法”报错怎么解
这是你标题里最典型的一个问题,也是 CentOS 10 搭配老版本 Xshell 最容易翻车的地方。具体报错一般是:
找不到匹配的 host key 算法
或者英文提示:
No matching host key algorithm found.
原因很直接:CentOS 10 自带的 OpenSSH 版本已经升级到 9.8 以上,默认不在服务器端提供 ssh-rsa(SHA-1)签名算法。而旧版 Xshell,比如个人免费版还是 6.x 甚至 5.x,默认只勾选了 RSA/SHA-1 这一种 host key 算法。双方握手时发现没有共同算法,直接就中断了。
解决办法有两个方向。
方向一:升级 Xshell。Xshell 7 以上版本已经默认支持新的 host key 算法,连接 CentOS 10 基本不需要额外配置。官网下载个人免费版即可,学校邮箱或者普通邮箱都能申请。
方向二:如果你暂时不想换 Xshell 版本,可以在 CentOS 10 的 SSH 服务端开启 RSA/SHA-1 支持。在之前建好的 00-root-login.conf 里追加两行:
ini复制HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
然后重启 sshd。
但我要提醒你,ssh-rsa 是 SHA-1 签名,已经算过时算法,安全要求高的环境不建议开启。如果只是虚拟机和自己玩,问题不大。生产环境尽量升级客户端,别去迁就老算法。
除了 host key 算法,有时候还会碰到密钥交换算法不匹配的报错,比如:
找不到匹配的 kex 算法
或英文 No matching key exchange method found.
这种就打开 Xshell 的“连接 - 安全 - SSH - 加密算法”界面,勾选更现代的密钥交换算法,比如 diffie-hellman-group-exchange-sha256、curve25519-sha256 等,然后重新连接。新版 Xshell 默认配置一般不会出现这个问题,老版本才需要手动勾。
2.3 输入密码后 Permission denied 的逐层排查
如果你已经确认 PermitRootLogin yes,但 Xshell 输入 root 密码后还是报 Permission denied, please try again,那就不是配置层的问题,得一层一层往下查。
第一优先级是密码本身。CentOS 10 安装时如果设置了复杂密码,Xshell 界面下很容易输错。建议先在服务器本地终端测试 root 密码能否正常登录,本地能进,基本排除密码错误。同时注意键盘布局,Xshell 客户端 Windows 机器的输入法状态有时会把英文密码打成中文全角字符,这类问题我帮人排查时遇到过好几次。
第二优先级是用户认证日志。直接看系统日志,它会把原因写得明明白白:
bash复制journalctl -u sshd -n 50 --no-pager
常见日志含义:
| 日志关键词 | 原因 | 方向 |
|---|---|---|
Failed password for root |
密码错误 | 换密码或检查输入法 |
User root not allowed because account is locked |
账户被锁 | passwd -u root 解锁 |
maximum number of authentication attempts exceeded |
重试次数过多 | 等 30 秒再试 |
Connection closed by authenticating user |
认证前连接被关闭 | 查 Fail2ban、hosts.deny |
第三优先级是 Fail2ban 或类似防护工具。CentOS 10 如果你装了 Fail2ban,多次失败后 IP 会被临时拉黑,这时候看起来就是密码错误,实际是连认证流程都没走到。排查时看:
bash复制fail2ban-client status sshd
确认当前 IP 是否被 ban,如果是,直接解除或加白名单,再回 Xshell 重连。
第四优先级是 PAM 模块。CentOS 10 默认启用 pam_faillock,连续输错密码会锁定账户一段时间。这个机制会影响 root 密码登录,虽然安全,但排错时容易让人误解。相关文件一般在 /etc/security/faillock.conf,如果 unlock_time 设置得很短,等一会儿就恢复了。排查时可以查看锁定状态:
bash复制faillock --user root
确认错误次数如果已经达到阈值,说明系统是刻意锁的,等解锁时间过了再试即可。
3. root 登录成功后的权限边界:这些操作仍然会失败
好不容易连上了,你以为 root 就是万能的?在 CentOS 10 上还真不是。这里说的不是“你还不够权限”,而是不少操作在 root 身份下依然会碰壁,而很多人第一反应是以为系统坏了。
3.1 为什么修改 /etc 下文件还是提示只读
用 root 登录后执行 vim /etc/hosts,发现能打开但写不进去,或者提示 read-only。这通常不是文件系统只读,而是几个很具体的原因:
一是文件本身有不可修改属性。检查一下:
bash复制lsattr /etc/hosts
如果输出里有 i 属性,说明被 chattr +i 锁定了。虽然这属于人为设置的权限状态,但在安全加固过的服务器上很常见。解锁命令是 chattr -i /etc/hosts,改完文件后再重新加上。
二是 SELinux 虽然不直接造成只读,但如果你改了文件的 SELinux 类型,个别服务会拒绝读取。比如把某个文件错误标记成了普通类型,重启服务后一直报权限错误,你以为是文件没有读权限,其实上下文不对。修正方式就是前面提到的 restorecon -v 文件路径。
三是根分区挂载选项问题。查看挂载参数:
bash复制mount | grep ' / '
如果输出里有 ro,就说明根分区是只读挂载的。这种情况通常出现在系统启动异常或云主机快照恢复后,需要重新以读写方式挂载:
bash复制mount -o remount,rw /
如果开机时经常变回只读,还得检查 /etc/fstab 里对应的参数是否写入了 ro。
3.2 SELinux 上下文错误导致命令无法执行
这个坑比只读更隐蔽,表现形式五花八门。最常见的是你从别的地方拷了一个脚本或者二进制放到 /root 下,执行时系统提示权限不足,明明文件是 755 权限,owner 也是 root,可就是跑不起来。这时候不要纠结权限位,先看 SELinux。
比如你下载了一个内网运维脚本放到 /root/scripts/check.sh,直接执行,结果 Permission denied。ls -l 看权限完全正常,但 restorecon -Rv /root/scripts 之后就恢复了。这就是因为文件从 Windows 或某个 Web 目录拷贝过来时,SELinux 上下文是 httpd_sys_content_t 甚至 user_home_t,而不是 admin_home_t 或 bin_t,SELinux 策略认为这个文件不适合在 /root 下执行。
判断关键命令:
bash复制ls -Z /root/scripts/check.sh
如果发现上下文不对,就用 restorecon 恢复。如果你的脚本已经被标记成奇怪的类型,恢复不了,可以手动设置:
bash复制chcon -t bin_t /root/scripts/check.sh
顺手提醒,不要为了省事直接 setenforce 0 关 SELinux。CentOS 10 在安全加固检测里对 SELinux 状态非常敏感,关了之后等你要部署生产环境时会有更多麻烦。
3.3 终端异常与 PATH 丢失
root 登录成功后,有时会发现命令输着输着提示 command not found,连 ls 都找不到了。这就是 PATH 环境变量丢了或者被搞乱了。
常见原因是你编辑 /etc/profile 或 /root/.bashrc 时写错内容,比如 PATH 变量赋值语法错误,导致登录后整个 PATH 变成空值。这时候任何绝对路径之外的命令都用不了。
处理思路不要慌,直接用绝对路径执行命令,比如 /usr/bin/vim、/usr/bin/cat,先把配置改回来。如果你不确定哪个文件有问题,可以先用:
bash复制/bin/echo $PATH
看看内容。PATH 为空的话,临时补一个:
bash复制export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
然后逐个检查 ~/.bashrc、~/.bash_profile、/etc/profile 里的 PATH 相关行,把错误的 .bashrc 里的 export PATH= 那行注释掉。
还有一种终端异常更常见:在 Xshell 里按上下箭头变成 ^[[A、^[[B,退格键失效,vim 打开文件后界面乱码。这个跟 root 权限无关,是 TERM 环境变量的问题,但经常出现在用 root 登录后因为切换了不同系统版本而触发。解决方式是在 Xshell 的会话属性里把终端类型设为 xterm-256color,并在服务器上确认:
bash复制echo $TERM
如果是 dumb 或空白,就执行:
bash复制export TERM=xterm-256color
顺手把 /etc/profile.d 下加一个 vim.sh 写入 export TERM=xterm-256color,以后登录就正常了。还有 Xshell 的字体问题,中文字体乱码时记得把会话属性里的编码改成 UTF-8,字体选个等宽字体,比如 Consolas 或 YaHei Consolas Hybrid,基本就能解决。
4. 更推荐的做法:密钥登录 root 并避免来回改密码
密码登录 root 虽然能解决问题,但从运维角度我不建议长期这么干。特别是暴露在公网的服务器,root + 密码是暴力破解的头号目标。更稳的方案是用 Xshell 生成密钥对,让 root 只接受密钥登录。这样既绕开了密码策略,又比密码安全得多。
4.1 在 Xshell 中生成密钥并用公钥登录
这个流程不复杂,我分步走:
第一步,在 Xshell 菜单栏点击“工具 - 新建用户密钥生成向导”。
第二步,密钥类型选 RSA,长度建议 3072 或 4096。2048 虽然还能用,但新硬件下选高一点不亏。
第三步,生成过程中会让你输入密钥加密密码(passphrase)。这一步我提醒一下:别留空,至少设一个自己能记住的,不然私钥文件泄露等于把服务器钥匙直接送人。当然如果你只是内网虚拟机,嫌麻烦留空也可以用,但公网环境必须有。
第四步,生成完成后,Xshell 会显示公钥字符串,保存到本地文件,比如 id_rsa_centos10.pub。
第五步,把公钥手动传到服务器上。如果你现在还没有任何方式能登录服务器,就比较麻烦,好在通常你至少还有云控制台的 VNC 或本地终端可以登录。上传方式任意,最直接的是在本地用 Xshell 登录后执行:
bash复制mkdir -p /root/.ssh
chmod 700 /root/.ssh
vim /root/.ssh/authorized_keys
把公钥内容粘贴进去,然后:
bash复制chmod 600 /root/.ssh/authorized_keys
restorecon -Rv /root/.ssh
如果之前是通过第 2.1 章开启了密码登录,现在就可以测试:在 Xshell 新建会话,用户名填 root,认证方式选 Public Key,选择刚才保存的私钥,然后连接。能登录就说明密钥认证已经生效。
4.2 禁止远程密码登录的加固配置
密钥登录验证成功后,可以把密码登录关掉,降低被爆破的概率。修改之前的 00-root-login.conf:
ini复制PermitRootLogin prohibit-password
如果你希望 root 只能密钥登录、其他用户也全走密钥,再额外加一行:
ini复制PasswordAuthentication no
这里要特别注意:在确认密钥登录完全没问题之前,不要急着关密码。建议先保持密码登录开启,同时用密钥登录几轮,确认密钥方式稳定了,再执行密码关闭。关闭后立刻开一个新会话验证密钥登录还是通的,别把当前会话直接关了,否则一旦密钥有问题,你自己也进不去了。
重启 sshd 后检查最终生效值:
bash复制sshd -T | grep -i passwordauthentication
sshd -T | grep -i permitrootlogin
确认 passwordauthentication no、permitrootlogin prohibit-password 就对了。
4.3 日常运维建议:能用 sudo 不用 root
虽然本文通篇在讲 root 登录,但我还是要给一个反直觉的建议:日常操作尽量别用 root,非必要不给 root 开远程登录。
原因很现实:root 的权限边界太宽,一旦误操作,比如手滑执行了 rm -rf /etc、chmod -R 777 /、mv /usr /tmp,系统崩溃概率几乎是百分百,而且连挽回的机会都没有。普通用户 + sudo 至少能多一层确认,出问题还能定位操作者。
CentOS 10 默认普通用户安装时如果勾选了管理员权限,会加入 wheel 组。用普通用户登录后需要提权时直接:
bash复制sudo -
配置 sudo 免密的话,在 /etc/sudoers.d/ 下加一个文件,内容为:
code复制username ALL=(ALL) NOPASSWD:ALL
但日常使用我不建议 NOPASSWD,还是输入密码比较稳妥。真正需要在脚本里免密执行的命令,可以精确到具体命令,比如:
code复制username ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx
这样既保留了审计痕迹,也避免了 root 裸奔。
5. 一张表收拢 Xshell + CentOS 10 常见异常与对应解法
遇到问题先别翻几百条教程,我把这一套组合拳里常见的情况整理成表,你直接对号入座。
| 现象 | 根因 | 快速解法 |
|---|---|---|
| Xshell 提示“找不到匹配的 host key 算法” | 旧版 Xshell 不支持新版 OpenSSH 默认算法 | 升级 Xshell 7+,或加 HostKeyAlgorithms +ssh-rsa |
输入密码后 Permission denied, please try again |
root 密码策略或密码错误 | 查 sshd -T,看 PermitRootLogin;再查日志 |
| 连接超时/拒绝连接 | 防火墙、SSH 未启动、端口不对 | systemctl status sshd、firewall-cmd --list-ports |
| root 登录后命令找不到 | PATH 被写坏 | 绝对路径 /usr/bin/vim 修复配置 |
上下键变成 ^[[A |
TERM 环境变量不对 | 设 export TERM=xterm-256color |
| 密钥登录失败 | 权限或 SELinux 上下文不对 | chmod 600 authorized_keys、restorecon -Rv /root/.ssh |
| 改端口后 SSH 连不上 | SELinux 未放行新端口 | semanage port -a -t ssh_port_t -p tcp 端口 |
系统日志有 maximum number of authentication attempts exceeded |
重试次数过多或 Fail2ban 触发 | 等锁定时间,或检查 fail2ban-client |
这里面有几条容易误判,我再说明一下:第一,连接超时时别只查防火墙,先看 sshd 是否真的在运行,CentOS 10 里 systemctl status sshd 一眼就能确认。第二,Permission denied 不一定是密码问题,也可能是 prohibit-password 策略直接拦截了密码认证。第三,CentOS 10 系统日志默认用 journalctl,不要去找老旧的 /var/log/secure,新版日志里同样信息但要动态读取。
Xshell 自身还有几个小技巧也顺便说了:会话属性里可以设置“保持活动”的心跳包,时间间隔 30 秒,避免长时间没操作被服务器断开;Ctrl+Shift+T 可以新建标签页;cd - 可以在最近两个目录间来回切换,比反复输入绝对路径省事得多。这些对日常连服务器都有用,但对本文场景最关键的还是把算法兼容和 Perm
