ssh登录太慢了,每次都要20s
背景
大家工作时,少不了ssh登录各个服务器,我这边手里也有很多服务器,有一些登录很快就进去了,有些要卡半天才能进去。之前以为是公司网络问题,每次也就忍了,这次突然不想忍了,决定定位一下。
我这边的服务器是10.80.121.46。因为这个问题是可复现的,算是个好问题,于是在本地开了wireshark,ssh登录,看看能不能看出端倪。
host 10.80.121.46 and tcp port 22

可以看到,服务端在00:13,发了第一个消息过来;过了20s,发了第二个消息过来。
总的来说,应该是服务端问题。
定位过程
看日志
由于是ssh这种加密了的协议,抓包也看不出个啥。所以我首先的思路是看看sshd这个服务端进程的日志。sshd是systemd管理的,所以看看状态先。

这种的话,一般也能看到最新的日志,如果要看完整的日志,可以用如下命令:
journalctl -u sshd
ps: journalctl -u sshd -f 可以像tailf那样持续跟踪日志
但是,发现只有info级别的日志,也看不出什么特别.
Apr 03 15:27:30 nginx2 sshd[87616]: Accepted password for root from 10.0.235.72 port 11481 ssh2
接下来,又看了下其他日志:
/var/log/messages:
Apr 3 15:27:30 year-account-nginx2 systemd-logind: New session 13336 of user root.
Apr 3 15:27:30 year-account-nginx2 systemd: Started Session 13336 of user root.
/var/log/secure:
Apr 3 15:27:30 year-account-nginx2 sshd[87616]: Accepted password for root from 10.0.235.72 port 11481 ssh2
Apr 3 15:27:30 year-account-nginx2 sshd[87616]: pam_unix(sshd:session): session opened for user root by (uid=0)
反正看了好些日志,没啥用,这边上个链接,讲linux下的各种日志。
https://www.plesk.com/blog/featured/linux-logs-explained/
https://www.eurovps.com/blog/important-linux-log-files-you-must-be-monitoring/
开启debug日志
上网查了下,怎么开启sshd的debug级别日志,结论如下:
vim /etc/ssh/sshd_config
加一行:
LogLevel DEBUG
这个LogLevel的取值有哪些呢,具体可以在机器上执行:
man sshd_config
没想到取值还有更逆天的:

我之前就是在debug级别下测试的,然后看日志:
journalctl -u sshd -f

看到出现了20s的间隔,但是,还是没有什么错误或者警告。当时,我就开始上网查了,但是这次,咱们要不试试把日志级别弄成DEBUG3:

这里日志细了一些,但还是看不太出来啥问题。这个10.0.235.72,是我本机windows的ip。
服务端dns抓包
经过上网冲浪,发现很多文章提到了一点,就是sshd会拿着我们客户端的ip,去dns 服务器查询ip对应的主机名(域名)。很明显,我这个ip,肯定是没什么域名的。大概率是这个原因,但是基于严谨的角度考虑,我还是先找找证据。
dns服务器对外的端口是53,所以我抓的就是这个端口的网络包:

可以发现,本机是给两个dns服务器发请求的,分别是8.8.8.8 8.8.4.4
看下机器的dns服务器配置:
vim /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
不知道为啥是这个地址,反正是运维同事给的。
测试了端口通不通,发现tcp不通,udp不知道咋测(试了下netcat、nmap,没太弄懂)
ping也不通,不知道是真不通,还是对端禁ping了。
这些都不重要,重要的是,这个报文也不知道是啥意思,看起来和我的问题没什么关系。
strace排查
暂时放下dns这块,准备strace试试,反正,死马当活马医。
strace这个一般用得少,选项记不住,一开始就这么试试:
netstat -nltp|grep 22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 93585/sshd
tcp 0 0 0.0.0.0:4822 0.0.0.0:* LISTEN 31633/nginx: master
tcp6 0 0 :::22 :::* LISTEN 93585/sshd
拿到sshd pid为93585,开启strace:

但是啥也没看出来。
找了下以前笔记,加了几个选项:
strace -p 121920 -s 1000 -t -e trace=network,file,desc,process
-s: 字符串显示1000个字符串,不截断(默认是32,会看不全)
-t:显示时间
-e trace=network,file,desc,process,监控网络、文件、文件描述符、进程相关的系统调用

这次信息多一点,还是啥都看不出来。
上网查
没法了,把之前dns抓的包拿下来用wireshark分析分析。


这个dns查询,有点看不懂,直接拿关键字搜了下,大家看如下链接吧:
https://www.cloudflare.com/zh-cn/learning/dns/dns-records/dns-ptr-record/

难怪,dns进行反向查找时,客户端ip是反的,我的实际ip是:10.0.235.72
到了上图,就变成了:

也难怪我没看出来,这个基本算是一个强力证据了,大概率是dns解析的问题,毕竟用了我的ip。
修改sshd配置
那就禁用这个机制吧,方式如下:
vim /etc/ssh/sshd_config
UseDNS no
然后重启sshd
systemctl restart sshd
这样基本就ok了。重新试了下,再没有卡20s了,秒登录。
继续探索strace
找到问题原因后,strace我又继续研究了下。原来是少了个选项,-f:
-f
--follow-forks
Trace child processes as they are created by currently traced processes as a result of the fork(2), vfork(2) and
clone(2) system calls. Note that -p PID -f will attach all threads of process PID if it is multi-threaded, not only
thread with thread_id = PID.
这个选项是跟踪子进程的系统调用,因为,sshd收到一个客户端连接时,会fork一个新进程出来。前面都忘了加-f,所以导致没跟踪到。
换下命令:
strace -p 93585 -s 1000 -t -e trace=network,file,desc,process -f

这次可以跟踪了。
补充
在写这篇文章的时候,对一个地方产生了疑问。一般看日志的时候,对于systemd管理的service,我会看journalctl,也会看/var/log/messages,经常的情况是,在journalctl中的日志,在/var/log/messages中也能看到。
查了下两者的机制,参考:
systemd会写日志到一些文件(journalctl就会读这些文件),然后,另一个后台进程rsyslogd,也会读这些日志,然后写到/var/log/messages这些文件中。
[root@year-account-nginx2 log]# ps -ef|grep rsys
root 1614 1 0 2022 ? 00:46:28 /usr/sbin/rsyslogd -n

ssh登录太慢了,每次都要20s的更多相关文章
- SSH 首次登录太慢问题
这两天在使用 Docker 做测试,发现新建的容器在首次 ssh 登录的时候经常超时,我们简单将超时时间设置成60秒,但仍然会偶尔超时.所以简单延迟超时时间此路不通. 于是想到是否可以通过修改 ssh ...
- ssh 登录
一.ssh登录过程 在实际开发中,经常使用ssh进行远程登录.ssh 登录到远程主机的过程包括: 版本号协商 密钥和算法协商 认证 交互 1.1 版本号协商阶段 (1) 服务端打开22端口(也可以为了 ...
- SSH 登录缓慢解决方案
SSH 登录太慢可能是 DNS 解析的问题,默认配置下 sshd 初次接受 ssh 客户端连接的时候会自动反向解析客户端 IP 以得到 ssh 客户端的域名或主机名. 如果这个时候 DNS 的反向解析 ...
- SharePoint 2013:解决添加域名后每次都需要登录的问题
在SharePoint 2013中,当我们添加一个域名给SP后(添加域名的方法请参考此文:http://www.cnblogs.com/jianyus/archive/2013/08/10/32494 ...
- 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译
如果你干预到了项目的编译过程,可能就需要考虑到差量编译了.不然--当你的项目大起来的时候,就会感受到每次都重新编译时,每次重复调试的过程都要进行漫长等待时的绝望和无奈. 如果你正遭遇差量编译失效,每次 ...
- 【转】ssh登录原理以及ssh免密码登陆
一.什么是SSH? 简单说,SSH是一种网络协议,用于计算机之间的加密登录. 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会 ...
- Mac下,使用sshpass让iterm2支持多ssh登录信息保存
windows里有个Xshell非常的方便好使,因为它能保存你所有的ssh登录帐号信息.MAC下并没有xshell,有些也提供这样的功能,但效果都不好.iterm2是很好的终端,但却不能很好的支持多p ...
- sudo,linux 新建账号,并开通ssh登录
新建账号需要root账号或sudo权限,sudo配置保存在/etc/sudoers文件. sudoers的配置格式一般为: root ALL=(ALL:ALL) ALL %sudo ALL=(ALL: ...
- Jenkins踩坑系列--你试过linux主机ssh登录windows,启动java进程吗,来试试吧
一.问题概述 在一个多月前,组长让我研究下持续集成.我很自然地选择了jenkins.当时,(包括现在也是),部分服务器用的是windows主机. 我当时想了想,如果我把jenkins装在windows ...
- <转载>Mac下,使用sshpass让iterm2支持多ssh登录信息保存
windows里有个Xshell非常的方便好使,因为它能保存你所有的ssh登录帐号信息.MAC下并没有xshell,有些也提供这样的功能,但效果都不好.iterm2是很好的终端,但却不能很好的支持多p ...
随机推荐
- win32 - Redirect Input and Output
如果要将exe的输出重定向到cmd,则可以使用匿名管道将子进程的标准输入和输出句柄重定向.请注意,命名管道也可以用于重定向进程I / O //CMD.exe #include <windows. ...
- java+文件实现的超市管理系统
一.需求 1.使用java语言实现系统 2.数据存储使用io读写文件 3.超市的商品管理+销售功能 二.效果 商品列表 商品增删改查 购买 三.说明 1.开发工具/技术 java eclipse 2 ...
- Django3.2
Django3.2 前言 之前我们介绍过web应用程序和http协议,简单了解过web开发的概念.Web应用程序的本质 接收并解析HTTP请求,获取具体的请求信息 处理本次HTTP请求,即完成本次请求 ...
- 【ACM专项练习#02】整行字符串、输入vector、打印图形、处理n组数据以及链表操作等
输入整行字符串 平均绩点 题目描述 每门课的成绩分为A.B.C.D.F五个等级,为了计算平均绩点,规定A.B.C.D.F分别代表4分.3分.2分.1分.0分. 输入 有多组测试样例.每组输入数据占一行 ...
- 【Python OO其二】设计模式之工厂模式(举例说明)
工厂模式 工厂模式中的"工厂"实际上就是把类看成制造某种模板的工具(工厂),由这个类生成的实例除了本身自有的属性外,还可以通过指定的方式产出具有不同属性的同一类实例 比如:有一个面 ...
- 【Azure 存储服务】App Service 访问开启防火墙的存储账号时遇见 403 (This request is not authorized to perform this operation.)
问题描述 需要 App Service 访问开启防火墙的存储账号.存储账号中设置为允许选中的VNET访问,同时允许了信任的Azure服务的访问,但是仍然报错 "403 (This reque ...
- Java 多线程------解决 实现Runnabel接口方式线程的线程安全问题 方式二:同步方法 +总结
方式二:同步方法* 如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的 1 package bytezero.threadsynchronization; 2 3 4 5 /** ...
- 解决element-ui的date-picker组件的picker-options属性不生效的问题
网上查半天都没查到,好像没人写,于是俺怀着激动的心情来记录下 项目来需求,说要控制日期选择的最大最小范围,看似简单,实则藏深坑! 小白的我天真地按照网上的例子(主要是官网也不给一个!)写完如下: 1. ...
- Vue实现图片瀑布流
在线演示地址:点击前往 一,创建一个Waterfall组件 代码如下: <template> <div class="waterfall"> <!-- ...
- 问答:C程序为何for循环和while循环无法相互替代?
百鸡百钱问题: C代码: include <stdio.h> main() { int cock, hen, chicken; for(cock=0;cock<=20;cock++) ...