标题:[实践OK]ssh连接慢(DNS惹的祸),之sshd与/etc/resolv.conf里的IP反解析的关系。 出处:向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除 时间:Tue, 20 Mar 2018 10:34:21 +0000 作者:jackxiang 地址:http://jackxiang.com/post/9679/ 内容: 背景:使用ssh时有时会出现连接一个服务器的时候超慢,一般会显示一下信息,然后就卡在那不动了,发现原来是/etc/resolve.conf文件里的联通DNSIP无法访问导致的,而作了两个操作1)不解析DNS:vim /etc/ssh/sshd_config,设置UseDNS为no,直接重启ssd(sudo service sshd restart)就好了,并不影响当前连接,其它连接重新来就快了。2)更改/etc/ssh/sshd_config,GSSAPIAuthentication no。因为文件里的DNS因为出不了公网尽管修改了这两个项后,依然SSH挺慢的,于是,找网络安全值班的兄弟给加了SNAT,能出公网后,SSH连接就快了。 老外说:Use DNS = no does not prevent sshd from performing DNS lookups, it prevents it from rejecting clients when PTR records don't match. -u0 prevents sshd from logging DNS names in the utmp struct. lookups might still happen depending one what a user has in their authorized_keys. See this for a decent explanation: http://lists.freebsd.org/pipermail/freebsd-stable/2006-November/030886.html 实践捕获输出看慢哪儿了? ssh -v -l xiangdong 192.168.111.** debug1: identity file /home/xiangdong/.ssh/id_ecdsa-cert type -1 #卡这一行了 ll /home/xiangdong/.ssh/id_ecdsa-cert #没有这个文件 ls: cannot access /home/xiangdong/.ssh/id_ecdsa-cert: No such file or directory 查下:ssh debug1 identity file hangs https://www.centos.org/forums/viewtopic.php?t=52538 strace ssh -T -l irdcops 10.70.36.191 捕获输出发现一直在找DNS进行确认,如下: socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.70.63.150")}, 16) = 0 poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}]) sendto(4, "\30'\1\0\0\1\0\0\0\0\0\0\003191\00236\00270\00210\7in-add"..., 43, MSG_NOSIGNAL, NULL, 0) = 43 poll([{fd=4, events=POLLIN}], 1, 5000) = 1 ([{fd=4, revents=POLLIN}]) ioctl(4, FIONREAD, [43]) = 0 recvfrom(4, "\30'\201\5\0\1\0\0\0\0\0\0\003191\00236\00270\00210\7in-add"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.70.63.150")}, [16]) = 43 close(4) = 0 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("202.106.0.20")}, 16) = 0 poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}]) sendto(4, "\30'\1\0\0\1\0\0\0\0\0\0\003191\00236\00270\00210\7in-add"..., 43, MSG_NOSIGNAL, NULL, 0) = 43 poll([{fd=4, events=POLLIN}], 1, 5000) = 0 (Timeout) socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 5 connect(5, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.70.63.150")}, 16) = 0 poll([{fd=5, events=POLLOUT}], 1, 0) = 1 ([{fd=5, revents=POLLOUT}]) sendto(5, "\30'\1\0\0\1\0\0\0\0\0\0\003191\00236\00270\00210\7in-add"..., 43, MSG_NOSIGNAL, NULL, 0) = 43 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) ioctl(5, FIONREAD, [43]) = 0 recvfrom(5, "\30'\201\5\0\1\0\0\0\0\0\0\003191\00236\00270\00210\7in-add"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.70.63.150")}, [16]) = 43 close(5) = 0 close(4) = 0 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("202.106.0.20")}, 16) = 0 poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}]) sendto(4, "\30'\1\0\0\1\0\0\0\0\0\0\003191\00236\00270\00210\7in-add"..., 43, MSG_NOSIGNAL, NULL, 0) = 43 上在访问的就是公网和内网的DNS,一直查它在不在: 关于dns 公网访问时,配置DNS服务器 202.106.0.20; 内网访问时,配置DNS服务器 10.70.63.150。 关掉/etc/ssh/sshd_config 里的DNS解析后,要快一点。 systemctl restart sshd.service 查看启动是否成功: ps -ef|grep sshd|grep sbin root 8503 1 0 Jan08 ? 00:00:00 /usr/sbin/sshd 即使之前连接着的,但是还是会不变,时间不变,为何要过滤掉那个时间,是想看是否真正重启了: ps -ef|grep sshd root 34718 1 0 10:25 ? 00:00:00 sshd: xiangdong [priv] xiangdo+ 34720 34718 0 10:25 ? 00:00:00 sshd: xiangdong@pts/0 root 34876 1 0 10:38 ? 00:00:00 sshd: xiangdong [priv] root 34877 1 0 10:38 ? 00:00:00 sshd: xiangdong [priv] xiangdo+ 34879 34877 0 10:38 ? 00:00:00 sshd: xiangdong@pts/1 xiangdo+ 34984 34876 0 10:39 ? 00:00:00 sshd: xiangdong@pts/2 root 60553 1 0 17:51 ? 00:00:00 /usr/sbin/sshd Connecting to 10.10.10.10:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'. 过好长时间之后才会显示类似以下的信息 Last login: Mon Jun 3 13:19:59 2013 from 10.10.10.1 会出现这种问题是因为ssh默认有一个配置项UseDNS(文档中解释此配置项的意思为:UseDNS Specifies whether sshd should look up the remote host name and check that the resolved host name for the remote IP address maps back to the very same IP address. The default is “yes”.) 当此项配置不开启时默认值为UseDNS yes,这样会导致ssh在有连接过来的时候进行dns解析,所以会产生较长时间的停顿,所以要解决此问题可以将此配置项打开,然后值改为no,操作如下: vim /etc/ssh/sshd_config 将第5行的注释去掉,然后将值改为no #Compression delayed #ClientAliveInterval 0 #ClientAliveCountMax 3 #ShowPatchLevel no UseDNS no #PidFile /var/run/sshd.pid #MaxStartups 10 #PermitTunnel no #ChrootDirectory none 然后重启一下sshd服务。 实践发现即使这样做了,vi /etc/ssh/sshd_config,设置UseDNS为no试试,还是慢, 原因是: 1)Sshd配置文件已经有UseDNS No选项,但似乎sshd试图做出反向dns分辨率。如何完全禁用ssh reverse dns查找? 2)如果你想禁用所有类型的连接延迟,你必须禁用,GSSAPIAuthentication如果活跃。GSSAPI是一种IETF标准,用于在基于网络的应用程序中执行强大的加密认证。它也支持openssh,但它也可能会引入延迟。有些发行版在默认情况下保持此模式处于活动状态,因此您必须在以下位置更改此项/etc/ssh/sshd_config: GSSAPIAuthentication no 来自:http://blog.51cto.com/jschu/1770095 Generated by Jackxiang's Bo-blog 2.1.1 Release