SSH是Linux中的基础服务,作为IT从业者,基本上每天都要SSH连接到服务器中,从事各种各样的工作。作为这样基础的不能再基础的服务,一旦出现问题,影响也是巨大的,连不上就无法对服务器进行配置和更改,所有的事情也就无从谈起。

在这篇文章中,我们会对SSH服务进行介绍,并对一些常见的问题进行分析,进而提供相应的解决方法。话不多说,我们进入主题。

一、SSH服务简介

SSH采用的是C/S架构,SSH server端一般运行在服务器中,这里的服务器可以是物理服务器,而现在随着云计算的推广,更大的可能性是云主机,比如AWS的EC2实例,阿里云的ECS实例等。SSH client端则千差万别,Linux中是ssh命令,一般是OpenSSH软件包的一部分;Windows中比较常见的是SecureCRT,X-Shell,Moba-Xterm等。

接下来,我们以Linux Mint作为SSH client端,以AWS EC2为SSH server端进行演示和分析。

我们首先来分析一个正常的SSH连接是如何进行的,在这里我们通过ssh命令的-vvv选项,来看一下SSH连接背后发生了什么。这里为了减少不必要的影响,略去了测试用的对端IP地址,Linux Mint的ssh配置文件默认指定了连接用户为ec2-user,指定了本地的私钥文件位置为/home/user/.ssh/user.pem。

################################################

user@PC:~$ ssh IP -vvv
OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n  7 Dec 2017
#本机的ssh客户端版本信息
.....
.....
debug1: Connecting to IP [IP] port 22.
debug1: Connection established.
#与对端TCP 22端口完成建联过程
debug1: key_load_public: No such file or directory
debug1: identity file /home/user/.ssh/user.pem type -1
#本地的key文件
.....
.....
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.4
debug1: match: OpenSSH_7.4 pat OpenSSH* compat 0x04000000
#对端ssh服务器版本信息
debug2: fd 3 setting O_NONBLOCK
debug1: Authenticating to IP:22 as 'ec2-user'
#本地配置文件中指定的用户信息
.....
.....
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c
debug2: host key algorithms: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
#ssh客户端与服务器端交换支持的加密算法
.....
.....
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Trying private key: /home/user/.ssh/user.pem
#使用本地的private key进行密钥认证
debug3: sign_and_send_pubkey: RSA SHA256:imct6EHZzIK24fZ+H3bFzHAYpDLufFVELss7un64aZA
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
#本地的ssh客户端发送了publickey报文,等待ssh服务器端反馈
debug3: receive packet: type 52
#本地的ssh客户端收到来自ssh服务器端的反馈
debug1: Authentication succeeded (publickey).
#提示认证成功
Authenticated to IP ([IP]:22).
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
#认证通过后,ssh服务器端打开一个channel,用于处理ssh请求
.....
.....
debug2: channel_input_open_confirmation: channel 0: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug3: receive packet: type 99
debug2: channel_input_status_confirm: type 99 id 0
debug2: PTY allocation request accepted on channel 0
debug2: channel 0: rcvd adjust 2097152
debug3: receive packet: type 99
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
#channel 0的shell申请被接受,ssh连接已经建立
Last login: Sat Nov  2 05:04:03 2019 from IP

__|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-xx-xx-xx-xx ~]$

#######################################

综合来看,SSH连接的第一阶段为TCP建联,也就是通常的TCP三次握手机制,服务器端一般为TCP 22端口,也不排除自定义配置,这里不再赘述。

当TCP 22建联完毕后,ssh客户端和ssh服务器端开始进行通信,交换一系列信息,例如双方支持的加密算法等。进而ssh客户端将本地密钥发送到ssh服务器端进行认证,认证完毕后,ssh服务器端会将认证结果反馈给ssh客户端。如果认证成功的话,ssh服务器端会开启一个channel,用于处理来自ssh客户端的业务请求,该channel会与PTY进行关联,并申请一个shell终端。如果认证、权限等一切正常,channel打开,ssh客户端和ssh服务器端的ssh连接可用。

以上为一个正常的SSH连接所经历的环节。接下来,我们看一下各个环节中可能会遇到的问题。

二、网络部分问题

通过上述分析,我们知道SSH连接首先要进行TCP 22端口的建联,如果这个时候网络部分出现问题,SSH连接肯定无法正常工作。这个时候,我们可以使用telnet命令来测试下到特定IP地址的TCP 22端口是否通畅。

以下为一个通畅的telnet测试,这里为了减少不必要的影响,略去了测试用的对端IP地址。

###################

user@PC:~$ telnet IP 22
Trying IP...
Connected to IP.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4

###################

除此之外,还有两种比较常见的情况,分列如下:

1、Connection timed out报错

##################

user@PC:~$ telnet IP 22
Trying IP...
telnet: Unable to connect to remote host: Connection timed out

##################

此时的wireshark抓包显示如下:

可以看到本地客户端向服务器端发起了TCP的SYN包,但是服务器端一直没有响应,进而出发了TCP Retransmission,多次重传后,导致超时,也就是此处看到的Connection timed out.

2、Connection refused报错

####################

user@PC:~$ telnet IP 22
Trying IP...
telnet: Unable to connect to remote host: Connection refused

####################

此时的wireshark抓包显示如下:

可以看到本地客户端向服务器端发起了TCP的SYN包,同时服务器端回了一个RST,ACK,将对应的TCP连接进行了重置。

将二者对比,我们可以发现,同样是无法进行TCP建联,二者有着不同的含义。

对于公有云实例来说,Connection timeout代表着流量还未到达实例,在中间的某个环节已经被阻断。最常见的场景是实例的安全组、网络ACL部分存在阻断,例如没有放行对应的端口到本地客户端所在的共有IP地址等问题。排查的时候,可以先检查下实例所在的安全组,并查看本地客户端的公有IP地址,进而确保安全组中放行了对应的端口给该公有IP地址。

而Connection refused这种情况,从抓包已经看到TCP报文已经到了服务器,但是服务器由于某些原因并未接收对应的TCP报文。这种场景通常对应着实例内部,也就是操作系统层面的某些设置,例如SSH服务器端进程没起来,或者监听在不同的端口上;也有可能实例上运行了防火墙(iptables、firewalld等),不允许来自客户端的公有IP与SSH服务器端建立连接。这种场景下的排障稍微复杂一些,尤其是AWS EC2实例,由于此时已经无法ssh登陆,通常需要关停实例,卸载根卷,挂在到其它的实例中,分析配置文件、日志等,确定可能存在的问题,进而做相应的修改后,再挂载回原来的实例中,重新启动实例,尝试看是否可以解决问题。而对于阿里云的ECS实例,相应的排查则要简单的多,因为阿里云ECS实例提供了VNC功能,可以直接在console端连接到实例内部,虽然会卡一些,但毕竟可以登录进去,有点类似于物理机的管理接口,例如惠普的ILO接口、戴尔的iDrac接口、VMware的管理控制台等。这里先挖个坑,后续我们会开设AWS EC2专栏,讲解如何对EC2的EBS卷做离线分析。

三、鉴权相关问题

如果前边的TCP建联已经通过,那么接下来的问题则多数集中在鉴权等相关问题上。这里最常见的就是Permission denied报错。

以下为我们的一个讲解案例,还是通过ssh开启verbose日志的方式(-vvv选项),我们来看一下这个过程中发生了什么:

##############

debug1: Next authentication method: publickey
debug1: Trying private key: /home/user/.ssh/user.pem
#调用本地的密钥文件
.....
.....
debug2: we sent a publickey packet, wait for reply
#本地客户端将publickey认证内容发送给服务器端
debug3: receive packet: type 51
#服务器端认证失败,返回相应的结果
.....
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
#此时已经没有其它可继续认证的方法
centos@IP: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
#使用centos用户进行认证,返回Permission denied报错,认证失败

#################

从上述日志,我们能得到的有用信息主要包括以下几点:

首先,客户端和服务器端使用的是密钥认证方式;其次,客户端的密钥文件为 /home/user/.ssh/user.pem;第三,客户端使用的登录用户名为centos。

这个时候,客户端能做的排查包括以下几点:

第一,客户端尝试使用的认证方式是否正确,比如服务器端其实使用的是用户名和密码,而发送的命令格式为密钥认证

第二,确认密钥文件对应的登录用户名,也就是说此处的 /home/user/.ssh/user.pem是否为centos用户的密钥文件

第三,确认centos用户是不是正确的登录用户

而在服务器端,我们能看到的信息会更多一些,也更贴近报错本身的含义。一般来说,SSH登录相关的报错与安全息息相关,相应的日志一般记录在/var/log/secure文件中(比如Amazon Linux,CentOS,RHEL等操作系统)。

查看日志有一个小技巧,日志一般条目众多,此处我们可以根据发生的时间点有针对性的查看,极大的减少排查范围。以当前报错为例,查看到的日志内容如下:

#############

Nov  2 06:56:03 ip-xx-xx-xx-xx sshd[4495]: Invalid user centos from IP port 54632
Nov  2 06:56:03 ip-xx-xx-xx-xx sshd[4495]: input_userauth_request: invalid user centos [preauth]

#############

我们可以看到,这里的报错信息非常直观,invalid user centos,也就是说我们使用的登录用户名centos是无效的。

考虑到测试用的是AWS EC2实例,使用的是Amazon Linux操作系统,那么当前的问题的解法应该是将centos用户替换为ec2-user,即可顺利登录。

常言道,幸福的家庭千篇一律,不幸的家庭各部相同。对于SSH排障来说,这个说法也是很适用的。我们需要根据具体的报错内容,做进一步的分析,以确定可能存在的问题。

四、尾声

SSH作为一个基础服务,其涵盖的内容相当广泛,我们在这里分析的只是最最基础的一些,一些更为高级的话题,例如ssh集成ldap认证,PAM模块的应用及配置等内容,篇幅限制暂不详细展开,感兴趣的朋友们可以尝试一下。

希望上述内容能对你有所帮助。

SSH常见问题及其解决方法相关推荐

  1. SSH中known_hosts文件作用和常见问题及解决方法

    known_hosts文件 known_hosts文件是SSH客户端中的一个重要配置文件.当首次与一个SSH服务器建立连接时,客户端会记录下该服务器返回的的公钥,并保存在known_hosts文件中, ...

  2. linux lw3m多行文本使用,linux常用命令以及一些常见问题和解决方法教程.docx

    linux常用命令以及一些常见问题和解决方法教程 端口以及ip之间抓包1.监视指定网络接口的数据包tcpdump -i eth1如果不指定网卡,默认tcpdump只会监视第一个网络接口,一般是eth0 ...

  3. 群晖网络不通_群晖系统安装zerotier one进行内网穿透过程中常见问题及解决方法...

    群晖系统安装zerotier one进行内网穿透过程中常见问题及解决方法 2020-07-28 17:27:39 21点赞 330收藏 31评论 zerotier one是一款很好用的P2P内网穿透软 ...

  4. WIN7 常见问题及解决方法

    -------------------------------------------------------------- .★常见问题及解决方法 1.安装过程中出现一下的错误信息提示: Windo ...

  5. hive常见问题及解决方法

    Hive常见问题及解决方法 问题1:Specified key was too long; max key length is 1536 bytes     hive.log :  2018-01-0 ...

  6. nacos 集群_Nacos 常见问题及解决方法

    Nacos 开源至今已有一年,在这一年里,得到了很多用户的支持和反馈.在与社区的交流中,我们发现有一些问题出现的频率比较高,为了能够让用户更快的解决问题,我们总结了这篇常见问题及解决方法,这篇文章后续 ...

  7. c转义字符以及常见问题和解决方法||c中的注释

    常见问题和解决方法 vs2010编辑器 显示行号 c中的注释 自己配置vs2010注释的快捷键 注:

  8. ArcGIS Engine 10 开发常见问题的解决方法

    ArcGIS Engine 10 开发常见问题的解决方法 You are not Licensed for 弹出提示框,点击确定,VS工程自动关闭 http://www.cnblogs.com/Ris ...

  9. mysql开发问题解决_开发过程中mysql常见问题的解决方法

    本篇文章给大家带来的内容是关于开发过程中mysql常见问题的解决方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 记录开发过程中遇到mysql相关的问题以及解决方法,长期更新. 远 ...

最新文章

  1. npc寻路问题 c++_《原神》游戏中最懒的NPC出现了,她要玩家找一朵甜甜花
  2. B+树与LSM树的区别与联系
  3. GDCM:gdcm::Series的测试程序
  4. Boost:opencl测试的程序
  5. python PIL 打开\显示\保存图像
  6. QML的import目录爬坑记录
  7. Teradata Expression 12 在Windows 2003上Connection Reset 问题的解决方法
  8. 小程序分享到朋友圈_如何给小程序添加分享朋友圈
  9. linux登录成功后提示信息
  10. busybox订制小型linux(二)
  11. Java 面试题 —— java 源码
  12. JS判断一个页面是否已经打开
  13. linux cups打印中文,Linux使用cups进行打印
  14. 左岸读书-语不惊人死不休(95)
  15. Adlik发布v0.1.0(Antelope羚羊)版本,赋能深度学习模型产业化
  16. 8分频verilog线_任意分数分频Verilog实现
  17. latex论文写作心得
  18. Oracle 19c Grid Infrastructure安装
  19. Linux环境下安装Redis(保姆级教程)
  20. 基于elementUI封装了基础表单组件

热门文章

  1. C语言例题——简易计算器
  2. 【错误解决】SELECT list is not in GROUP BY clause and contains nonaggregated column
  3. java二重积分_《University Calculus》-chaper13-多重积分-二重积分的计算
  4. PTA_数据结构与算法_7-38 寻找大富翁 (25分)
  5. webpack合成sprite图
  6. jar包冲突java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException
  7. 如何安装打印机驱动程序?快速安装的方法
  8. Sandbox——沙箱技术,来自chromium开发文档
  9. 电话,手机,微信账号,邮箱正则表达式校验
  10. CSAPP LAB4 键盘驱动程序的分析与修改(谢罪)