/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
阿里云国际版开完实例,ssh 一敲,屏幕上出现一行 Permission denied (publickey),然后没有任何提示。
新手在这个位置最容易做的动作是重建实例。其实九成的首次登录失败,原因在客户端这一侧,重建一遍还是同样的结果。
下面按报错类型分三类。
一、密钥类:报错里带 publickey
1.1 私钥权限太宽
完整报错大概是这样:
macOS 和 Linux 上的 ssh 会检查私钥文件权限,只要 group 或 other 有读权限就拒绝使用。从浏览器下载的文件默认是 644,正好踩线。
修复:
Windows 上用 WSL 的话同理。用 PowerShell 直接 ssh 的话,权限模型不一样,通常不会报这个,但会报别的。
1.2 密钥对没绑定到实例
创建实例时如果选的是"不使用密钥对",后面再创建密钥对,两者是没有关系的,要手动绑定。
在实例详情页看"密钥对"那一栏是不是空的。空的就是没绑。
绑定操作要把实例关机,绑定完再启动。运行中的实例绑不上。
1.3 用错了密钥文件
同一个账号下有几对密钥是常事。ssh -i 后面跟的文件名要对上。判断办法是比对指纹:
输出的指纹拿去跟控制台密钥对列表里的指纹对,对不上就是拿错了。
1.4 用户名不对
阿里云国际版的 Linux 镜像,root 是默认的。但换镜像之后不一定。
Ubuntu 官方镜像有的版本默认用户是 ubuntu,Debian 是 admin,CentOS 是 root,CoreOS 是 core。这个规律跟 AWS 的 ec2-user、ubuntu 分布类似,但阿里云的镜像做得更统一一些,多数场景 root 能直接进。
判断办法是看镜像详情页的说明,或者先用 ssh -v 看认证阶段用的是哪个用户名:
这行会列出服务器接受哪些认证方式,也能看出用户名是否被识别。
二、网络类:报错是超时或拒绝
2.1 安全组没放行 22
现象是 ssh: connect to host 47.x.x.x port 22: Operation timed out,卡住二三十秒才返回。
这跟密码错误的表现完全不同。密码错误或密钥不对,是连上之后被拒,几秒内返回;端口不通,是一直等到超时。
去实例绑定的安全组,点"入方向",看有没有一条规则是 22 端口、源包含你的出口 IP。
没有就加一条。协议类型选 SSH(22),授权对象填自己的公网 IP,格式是 1.2.3.4/32。填 0.0.0.0/0 能通,但第二天日志里就会有爆破记录。
改完规则立即生效,不用重启实例。
2.2 实例没分配公网 IP
实例列表里"公网 IP"那一列是空的,说明这台机器只有私网地址,从外网根本连不到。
两种可能:创建时没勾"分配公网 IPv4 地址",或者选的是仅内网规格。
补的办法是绑定一个弹性公网 IP,在"弹性公网 IP"页面申请,然后绑定到实例。绑定是按小时计费的,闲置不绑也收费。
2.3 本地网络拦截
公司网络封 22 出站的情况不少见。判断办法是换手机热点试一次,能连就是网络问题。
也可以让 ssh 走 443 端口,前提是服务器那边把 sshd 的监听端口改了。
三、密码类:默认关着
3.1 密码登录默认关闭
阿里云国际版的 Linux 实例,sshd 配置里 PasswordAuthentication 默认是 no。用密码连会一直提示输密码再被拒,或者直接 publickey 失败。
要开的话,先通过 VNC 登录控制台,再改配置:
改完先别断开当前会话,另开一个终端验证能登上,再关。改错了又断线,只能回控制台用 VNC 救。
PermitRootLogin 那一行默认是 prohibit-password,意思是 root 只能用密钥。想用 root 加密码登录,这一行也要改。
3.2 root 密码没设过
用密钥开的实例,root 是没有密码的。passwd 都没跑过,密码登录开了也进不去。
3.3 密码里有特殊字符
命令行里带 $、!、& 的密码会被 shell 解释。用单引号包起来,或者干脆改用交互式输入。
用 -vvv 一次看清卡在哪
不确定属于哪一类的时候,让 ssh 把过程打出来:
输出很长,只看三段:
有这两行,说明网络通了,问题在认证环节。
这行说明服务器只接受公钥,密码登录是关的。想用密码,就得改 sshd_config。
这行说明客户端把默认的 id_rsa 递上去了,而不是你 -i 指定的那个。原因通常是 ~/.ssh/config 里有一条通配配置,把 IdentityFile 覆盖了。
如果 Connecting 之后一直停着,二十秒后打印 Connection timed out,网络层的问题,直接去看安全组和公网 IP。
排查顺序表
|
顺序 |
检查项 |
判断依据 |
处理 |
|
1 |
有没有公网 IP |
实例列表该列为空 |
绑定弹性公网 IP |
|
2 |
22 端口通不通 |
telnet IP 22 超时 |
安全组入方向加 SSH 规则 |
|
3 |
私钥权限 |
报 UNPROTECTED PRIVATE KEY |
chmod 600 |
|
4 |
密钥是否绑定 |
实例详情密钥对为空 |
关机后绑定再启动 |
|
5 |
密钥是否用错 |
指纹与控台不一致 |
换成正确文件 |
|
6 |
用户名 |
报错里出现 user 名 |
按镜像说明改 root/ubuntu |
|
7 |
认证方式 |
ssh -vvv 看可继续方式 |
需要密码就改 sshd_config |
前四条能解决大部分情况,后面三条属于少数派。
表里的顺序是从网络层往认证层走。反过来查也可以,但会多绕几圈。
一个容易搞混的点
Connection refused 和 Connection timed out 不是一回事。
refused 说明包到了机器,但那个端口没有服务在听。可能是 sshd 没启动,也可能端口改过。
timed out 说明包没到,或者回来的包被丢了。安全组、路由、本地防火墙都可能导致。
分不清这两个,排查会绕很远。
还有一个类似的组合:Host key verification failed。这不是认证失败,是本地 known_hosts 里存着同一个 IP 的旧指纹。重装系统或者换了实例,IP 复用,指纹就变了。处理办法是 ssh-keygen -R 47.x.x.x 删掉旧记录再连。
另外提一句,控制台自带的"远程连接"走的是 VNC,不经过 22 端口,也不依赖密钥。安全组全关的情况下它照样能进,这是最后的救命通道。但 VNC 里的粘贴很痛苦,别拿它干重活。
这一条我在新加坡区域的实例上验证过,其他区域的表现没逐一测,以官网当时的页面为准。
具体以官方文档为准。

