软件开发架构师

SSH登陆问题及排查思路

运维 47 2019-05-11 15:18

前言

使用 SSH 登录目标服务器异常后,我们能得到的错误反馈非常少,问题排查起来不太容易。下面分享一些由系统原因导致机器登录异常的案例,以及排查异常的思路。

一些登录异常的原因

下面分两大类介绍登录异常的原因:系统文件或参数被篡改,系统资源耗尽。

篡改系统文件和参数

随意修改nofile数值

当一些应用场景出现Can’t open so many files的问题,可能需要增加open files的数目,有人图省事就直接将/etc/security/limits.conf里的nofile改成了ulimited,或者改成了一个非常大的数值,退出后就登录不上机器了。先介绍几个系统参数的含义:

参数 含义
soft nofile(/etc/security/limits.conf) 用户自己设的最大句柄数限制
hard nofile(/etc/security/limits.conf) root 给每个用户设置的最大句柄数限制。
/proc/sys/fs/file-max 系统最多可以分配的文件句柄。
/proc/sys/fs/nr_open 单进程的最大句柄数限制。

这几个参数大小关系是 /proc/sys/fs/file-max > /proc/sys/fs/nr_open > hard nofile > soft nofile。单进程的最大句柄数肯定小于系统能分配的句柄数,一个用户最多可支配的句柄数肯定小于系统为每个进程设置的句柄数限制,普通用户自己设定的句柄数限制必定在 root 为他设置的范围内。

看到这里就明白了,要想增加nofile的话需要先更改/proc/sys/fs/nr_open的数值,保证二者大小关系不变。

更改 SSHD 的 PAM 配置

LinuxPAM提供认证、账号、会话和密码管理的功能,将共享库通过配置文件与应用程序关联起来。用户可以随意添加 PAM 的认证逻辑到自己的APP中而不用修改代码。SSHD 的部分 PAM 配置如下所示。

复制代码
#/etc/pam.d/sshd
#%PAM-1.0
auth required pam_sepermit.so
auth include password-auth

我们先解释一下这份配置文件大致含义:
pam_sepermit.so是按照 PAM 标准写的动态库,是具体登录认证逻辑的载体。password-auth是一份默认的 PAM 配置,被很多应用引用。required、include是控制标记,用来处理返回值,比较常见有以下几个:

  • requisite 表示必须满足,不满足就立即返回失败;
  • required 同样表示必须满足,但本模块失败会继续运行下去,最后再返回失败;
  • sufficient 表示满足后立即返回成功,不满足也不影响整个结果;
  • include 在当前位置运行被包含的文件,相当于把被包含的文件对应的内容复制到当前位置。

工作中可能会为机器的登录添加其他认证方式,比如添加 LDAP 认证。如果使用requisiterequired, 一旦机器的sssd服务没有开启,或者远端 LDAP 不可用了,机器登录就有问题了。

复制代码
#/etc/pam.d/sshd
#%PAM-1.0
auth requisite pam_sss.so
auth required pam_sepermit.so
auth substack password-auth

所以在新增认证时候尽量用sufficient,即使新增方式不可用了,不影响接下来的认证。

修改 NSS 配置

NSS 全名是name service switch, 也是一堆动态库通过配置文件与应用程序连接在一起。机器上账户信息的基本配置如下所示。

复制代码
#/etc/nsswitch. conf
passwd: files
shado w: files
group: files

这份配置含义是用户的passwd、shadow、group信息都是从files获取,files就是 /etc/passwd、/etc/shadow、/etc/group这三个文件,获取的流程通过strace命令说明。

复制代码
# 操作:strace id
大致流程:
1. open( "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
2. open( "/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
3. open( "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
4. open( "/etc/group", O_RDONLY|O_CLOEXEC) = 3

整个流程就是打开/etc/nsswitch.conf文件,查到有files这个配置,找到/lib64/libnss_files.so.2动态库,动态库去/etc/group、/etc/passwd查找用用户信息。

有时需要添加新的账户来源,比如 LDAP。同与 PAM 相似,如果 SSSD 服务停掉或者 LDAP 不可用,用户都找不到了,肯定就登录不上了。

复制代码
passwd: files sss
shado w: files sss
group: files sss

篡改敏感文件权限

遇到过由于host_key权限问题导致的登录失败案例。centos6 机器与 centos7 的对机器host_key权限要求不同,centos7 机器的host_key对 root 组内账户可以有r权限,但 centos6 不能有。如果修改到这个文件的权限,有可能引起登录异常。

机器资源耗尽

除了修改系统文件或参数导致登录失败的问题外,机器资源耗尽也是引起登录故障的常见原因。磁盘、内存、inode、文件句柄、进程数的耗尽都会引起登录异常。这种情况客户端常见返回就是Resource temporarily unavailable
非 root 用户耗尽的可能只是自己那部分,root 账户或许还可以登录到机器。但如果是 root 的进程耗尽了资源,就不太好解决了。下面介绍几种资源耗尽问题。

文件句柄耗尽

文件句柄就是开始说的nofile了,确认没有泄露的情况下,该增加就增加。

进程数耗尽

进程数耗尽可能存在两种情况,一种进程数到limits.conf里的上限,另外一种是系统分配的pid到了/proc/sys/kernel/pid_max的上限。/proc/sys/kernel/pid_max表示系统能分配的最大pid值,从内核角度看,进程和线程都有一个pid,所以需要使用系统的线程数与/proc/sys/kernel/pid_max对比,才能发现这个问题。

Inode 耗尽

Linux 一切皆文件,inode 是记录文件元信息的一种结构,每个 inode 都有自己的编号,这个编号是系统识别文件的唯一标识。用stat命令可以查看文件的 inode 信息,有df -i可以查看 inode 的使用情况。

一般情况都是磁盘比 inode 先用完,但两者也没有绝对关系,大批量的小文件可能会把 inode 耗尽。说一个 inode 用完的案例。设置 Cron 任务一般都会把输出定向到/dev/null里边去,如果不设置的话 Crond 就会通过 senmail 或者 postfix 将 output 和 warning 信息发送给设置任务的账户。这两个服务没有开启的话,那所有邮件都会积压在/var/spool/postfix/maildrop,文件体积很小,久而久之,inode 就被先于磁盘被耗尽了。

机器 pty 耗尽

pty 是和远程系统交互的虚拟终端。这个问题常见于大量用户登录的跳板机。排查时候主要看两个参数,如果这两个参数很接近,就快出问题了。可以通过修改max值,增加系统能分配的 pty 数目解决。

复制代码
cat /proc/sys /kernel/pty/max
4096
cat /proc/sys /kernel/pty/nr
2048

排查思路

系统日志

如果运气好root账户还能登陆上的话,/var/log/messages记录了系统日志,/var/log/secure记录了与登录相关的日志,从这俩份文件或许能找到蛛丝马迹。

DEBUG

同样是root账户还能登陆的情况,使用下面的命令调试,通过输出的信息大概率能解决问题。

复制代码
# 客户端
ssh +user@ip -p 端口 -vvv
# 服务端
strace /sbin/sshd -f /etc/sshd_config -p 端口 -dd

机器监控

root账户登录不上,系统日志和 Debug 方式也就不能用了。一般线上机器都会有基础指标监控,这些上报的指标信息就成了我们排查问题的关键线索。比如,看异常机器某些指标的取值是否超出了正常范围,故障前后是否有明显突变,与同批次机器比较是否有明显不同等等。

咨询变更

询问机器的使用者从最近一次成功登录到不能登录期间做过什么操作。比如,有没有修改过系统文件和参数,系统新部署了什么服务,机器上的服务有什么特性,有没有添加过 iptables 等等。

客户端探测

使用nc、tcpdump这些命令从客户端对目标服务器探测,通过返回联想原因。

结语

线上机器异常的原因五花八门,这里只是列举了很少一部分。只有能深入了解系统,不断提炼解决思路和积累经验,遇到问题才能迎刃而解。

文章评论