SSH登陆失败
背景
最近在用rock-chips的芯片做项目,在移植openssh后,无法正常使用密码登录ssh,记录解决思路和解决方法。
shadow
/etc/shadow
文件是 Linux 系统中用于存储用户密码和账户过期信息的文件。它包含了每个用户的账户信息,尤其是与身份验证和密码相关的内容。每一行包含一个用户的信息,字段之间由冒号 :
分隔。
具体格式为:
1 |
|
下面是每个字段的详细说明:
- 用户名 (
用户名
):- 存储用户的用户名。
- 例如:
root
、john
。
- 加密后的密码 (
加密后的密码
):- 存储用户的密码,通常是经过加密处理的密码。
- 如果该字段包含一个特殊字符
!
或*
,表示该账户已被锁定,不能登录。 - 例如:
$6$WqWvMyD6$zGs...
表示加密后的密码(此处为 SHA-512 加密)。
- 最后更改密码的天数 (
最后更改密码的天数
):- 记录自 1970年1月1日以来的天数,表示最后一次更改密码的日期。
- 例如:
18000
表示密码在 18000 天更改。
- 最小天数 (
最小天数
):- 密码更改的最小天数。设置为
0
时,用户可以立即更改密码;如果大于0
,则必须等待至少这个天数才能更改密码。 - 例如:
0
表示不限制密码更改的最小时间。
- 密码更改的最小天数。设置为
- 最大天数 (
最大天数
):- 密码的最大有效天数,超过此天数后必须更改密码。
- 例如:
90
表示密码在 90 天后到期,用户必须更改密码。
- 警告期 (
警告期
):- 在密码到期前的多少天开始警告用户,提醒其更改密码。
- 例如:
7
表示密码到期前 7 天开始警告用户。
- 不活动期 (
不活动期
):- 密码过期后,用户账户在不活动多少天后会被禁用。如果设置为
0
,表示密码过期后立即禁用账户。 - 例如:
30
表示密码到期后的 30 天内账户可以保持不活动状态。
- 密码过期后,用户账户在不活动多少天后会被禁用。如果设置为
- 到期时间 (
到期时间
):- 账户的到期日期,表示账户从该日期开始不再可用。值为
0
时表示没有设置到期日期。 - 例如:
0
表示账户没有设置到期日期。
- 账户的到期日期,表示账户从该日期开始不再可用。值为
- 保留字段 (
保留字段
):- 目前此字段保留,通常为空。
密码加密类型
在 /etc/shadow
文件中,密码的加密类型通常通过密码字段的前缀来标识。每种加密算法在加密后的密码字符串中都有特定的标识符。这些标识符帮助系统和程序知道如何解密和验证密码。
1 |
|
DES
:$1$
MD5
:$1$
(但与 DES 区别通常是密码长度)SHA-256
:$5$
SHA-512
:$6$
Blowfish
或bcrypt
:$2a$
或$2y$
未加密的密码
:如果密码字段为空(例如:root::
),则表示用户密码为空,或未加密(即无保护)。
密码过期
登陆失败后查看system log引入眼帘的第一个错误是密码过期:
1 |
|
重设密码后仍然显示过期,重设密码指令:
1 |
|
查看/etc/shadow
发现第三个字段为0,手动改成1800,不会再出现密码过期的错误。
改密码仍然出错的原因是系统时间不对导致,发现系统时间是19700101
1 |
|
使用date -s
修改系统事件后,再重设密码也可解决此问题。
密码错误
解决第一个问题后仍然登录失败,错误是密码错误:
1 |
|
可以确定的是我密码一定是一样的,因为设置的是1111
,首先清除密码在做尝试
1 |
|
这样是可以不用密码登录成功的,我立马想到了之前项目遇到的ssh不支持sha512的问题,觉得可能是加密方式的不支持导致的,于是更换des:
1 |
|
仍然是不用密码就登陆进来了,可能是passwd的des没有$1$
导致的,但是手动加上后仍然会密码错误。
源码分析
这种情况下只有在openssh的源码中跟踪,来查看密码为什么会被判断为错误。
1 |
|
以上是密码判断的代码,通过添加debug信息,我发现encrypted_password
为空,导致永远返回密码错误。问题应该就出现在xcrypt()
中,离真相越来越近了!
1 |
|
继续添加debug信息,最终调用的是crypt()
函数,在服务器上写test调用crypt发现可以正常加密,所以应该是编译的时候链接出了问题。
编译分析
我计划使用交叉编译工具编译和服务器相同的test,在rock-chips的板子上运行,但是我竟然没在lib目录里找到crypt
的库,只有crypto
的库,于是我立马到板子上查看也没有crypt
的库,所以在openssh的编译的链接中,没有链接到正确的库。
最终我在一个叫runtime_lib的目录中找到了crypt的库,使用这个库编译test在板子上验证通过,可以正常加密。
解决问题
在openssh的编译中链接上crypt
库,最终解决问题。