一个有意思的SSH登陆案例

这是一个特殊的案例,在修复ssh登陆之前,这个系统还经历了系统C库文件损坏,系统无法启动的恢复操作。

问题现象:

通过控制台管理终端可以登陆到系统内部,ssh登陆提示密码不正确,无论修改成什么密码,ssh都提示密码不正确。

在问题排查之前,我们先看下SSH 登录关联因素示意图:

一个有意思的SSH登陆案例

问题排查:

1. 确保密码正确性:
      尝试手动修改密码(通过管理终端执行passwd命令修改,我有轻微强迫症,密码还是自己改一下觉得可靠些),修改密码后对比/etc/shadow里面root用户的密文确实有变化,但是SSH依然无法登陆,提示密码不正确,而系统日志/var/log/secure日志也仅有一条failed passwd的提示 (也可以通过退出管理终端重新登录进行验证)
      PASS
2. 排除网络干扰因素:
     通过管理终端在系统内部执行 ssh root@localhost,(排查了系统加载的模块lsmod,没有安全狗,云锁之类的模块,hosts.deny,iptables也不存在问题) 
     PASS
3. 检查配置文件:
     查看ssh配置文件,对比正常的文件也没有发现明显异常   
     PASS
4. 空密码验证:
      清空root密码并允许空密码登陆ssh,本机以及外部测试依然提示密码不对  
      PASS
5. 登陆模块排查:
     视线回归到ssh的登陆过程,空密码提示密码错误说明实际并没有到密码验证的阶段,应是/etc/pam.d下面的验证模块(常见如 system-auth ,passwd,login,sshd等)的问题  
     FAILED

确认原因:

    排查过程中发现/etc/pam.d/sshd文件为空,找一台同系统版本的实例对比恢复,测试后恢复正常

疑问:

  为什么/etc/pam.d/sshd文件为空就一直提示密码不对呢?
  
  这个文件的内容又是什么?
        
  SSH登陆验证的顺序是怎样的 ?

探秘:

为了排查这个问题,我们需要先了解一下什么是PAM?

PAM(插入式验证模块(Pluggable Authentication Module,PAM))
简单来说,就是提供了一组身份验证、密码验证的统一抽象接口,应用程序员可以使用这些API接口来实现与安全性相关的功能,例如:

1) 用户验证
2) 数据加密
3) LDAP

PAM 模块的基本流程

一个有意思的SSH登陆案例

PAM 模块是按模块类型归类的。任何给定的模块至少要实现四种模块类型功能之一:

1. 验证模块(auth): 用于验证用户或设置/销毁凭证
2. 帐户管理模块(account): 将执行与访问、帐户及凭证有效期、密码限制/规则等有关的操作
3. 会话管理模块(session): 用于初始化和终止会话。
4. 密码管理模块(password)将执行与密码更改/更新有关的操作

我们看下这个文件的内容(/etc/pam.d/sshd):

#%PAM-1.0
auth       required    pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      password-auth

做一个小实验,修改/etc/ssh/sshd_config中的验证方式

UsePAM=yes/no 
PasswordAuthentication=yes

在清空/etc/pam.d/sshd以及PasswordAuthentication=yes的情况下:

  1. 设置UsePAM=yes,提示验证失败(实际验证的时候发现不同的系统版本提示不太一样,客户端是Authentication failed.secure日志有所不同,failed passwd ,pam提示都有)
    一个有意思的SSH登陆案例
  2. 设置UsePAM=no,使用正确的passwd登录成功
    一个有意思的SSH登陆案例

通过这个测试可以确定,当开启UsePAM的时候,先去找验证模块,由验证模块决定下一步的验证

(如/etc/pam.d/sshd文件里面的auth include password-auth)即使密码是正确的,如果验证模块自身有问题也无法登录

即PAM检验的优先级高于PasswordAuthentication(密码验证)

参考文献:

https://help.aliyun.com/knowledge_detail/52874.html

https://www.ibm.com/developerworks/cn/linux/l-pam/

上一篇:Java中怎样创建线程安全的方法


下一篇:多邻国的IPO大考