Iawen's Blog

我喜欢这样自由的随手涂鸦, 因为我喜欢风......

telnet 用来调试网络问题的简单命令和语法:
telnet
因为 telnet 最初通过端口建立连接不会发送任何数据, 适用于任何协议, 包括加密协议。
连接问题服务器有四个可能会遇到的主要问题。我们会研究这四个问题, 研究它们意味着什么以及如何解决。
本教程默认已经在 samba.example.com 安装了 Samba[1] 服务器而且本地客户无法连上服务器。

Error 1 - 连接挂起

首先, 我们需要试着用 telnet 连接 Samba 服务器。使用下列命令 (Samba 监听端口445):

[root@localhost ~]# telnet www.iawen.com 445
Trying 120.78.223.25...

这意味着 telnet 没有收到任何回应来建立连接。有两个可能的原因:

  • 你和服务器之间有个路由器宕掉了。
  • 防火墙拦截了你的请求。

为了排除第 1 点, 对服务器上进行一个快速 mtr samba.example.com[2] 。

[root@localhost ~]# mtr www.iawen.com  
                                                      My traceroute  [v0.85]
localhost.localdomain (0.0.0.0)                                                                           Sun Nov  3 08:49:20 2019
Keys:  Help   Display mode   Restart statistics   Order of fields   quit
                                                                                          Packets               Pings
 Host                                                                                   Loss%   Snt   Last   Avg  Best  Wrst StDev
 1. 192.168.137.2                                                                        0.0%     2    0.1   0.1   0.1   0.1   0.0
 2. 192.168.1.1                                                                          0.0%     2    0.5   0.5   0.5   0.5   0.0
 3. 100.64.0.1                                                                           0.0%     2    3.4  30.7   3.4  58.0  38.6
 4. 218.19.217.233                                                                       0.0%     2   12.7   8.2   3.7  12.7   6.3
 5. ???
 6. ???
 7. 183.2.182.118                                                                        0.0%     2    6.8   6.9   6.8   7.0   0.0
 8. 183.2.184.142                                                                        0.0%     1    7.7   7.7   7.7   7.7   0.0
 9. 42.120.239.250           
 ...

如果服务器是可达的, 那么便是防火墙(注意: 防火墙总是存在的)。
首先用 iptables -L -v -n 命令检查服务器本身有没有防火墙, 没有的话你能看到以下内容:

[root@localhost ~]# iptables -nvL
Chain INPUT (policy ACCEPT 2946 packets, 3731K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 DOCKER     all  --  *      br-02c13d5d163b  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  *      br-02c13d5d163b  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  br-02c13d5d163b !br-02c13d5d163b  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  br-02c13d5d163b br-02c13d5d163b  0.0.0.0/0            0.0.0.0/0     

如果你看到其他东西那可能就是问题所在了。为了检验, 停止 iptables 一下并再次运行 telnet samba.example.com 445 看看你是否能连接。如果你还是不能连接看看你的提供商或企业有没有防火墙拦截你。

Error 2 - DNS 问题

DNS 问题通常发生在你正使用的主机名没有解析到 IP 地址。错误如下:

telnet samba.example.com 445
Server lookup failure: samba.example.com:445, Name or service not known

第一步是把主机名替换成服务器的 IP 地址。如果你可以连上那么就是主机名的问题。
有很多发生的原因(以下是我见过的):

  • 域名注册了吗?用 whois 来检验
  • 域名过期了吗?用 whois 来检验
  • 是否使用正确的主机名?用 dig 或 host 来确保你使用的主机名解析到正确的 IP
  • 你的 A 记录正确吗?确保你没有偶然创建类似 smaba.example.com 的 A 记录。

一定要多检查几次拼写和主机名是否正确(是 samba.example.com 还是 samba1.example.com)?这些经常会困扰你, 特别是比较长、难记或其它国家的主机名。

Error 3 - 服务器没有侦听端口

这种错误发生在 telnet 可达服务器但是指定端口没有监听。就像这样:

telnet samba.example.com 445
Trying 172.31.25.31...
telnet: Unable to connect to remote host :Connection refused

有这些原因:

  • 你 确定 连接的是正确的服务器?
  • 你的应用服务器没有侦听预期的端口。在服务器上运行 netstat -plunt 来查看它究竟在干什么并看哪个端口才是对的, 实际正在监听中的
  • 应用服务器没有运行。这可能突然而又悄悄地发生在你启动应用服务器之后。启动服务器运行 ps auxf 或 systemctl status application.service 查看运行。

Error 4 - 连接被服务器关闭

这种错误发生在连接成功建立但是应用服务器建立的安全措施一连上就将其结束。错误如下:

[root@localhost ~]# telnet www.iawen.com 80
Trying 120.78.223.25...
Connected to www.iawen.com.
Escape character is '^]'.
Connection closed by foreign host.

最后一行 Connection closed by foreign host. 意味着连接被服务器主动终止。为了修复这个问题, 需要看看应用服务器的安全设置确保你的 IP 或用户允许连接。
成功连接
成功的 telnet 连接如下:

[root@localhost ~]# telnet www.iawen.com 80
Trying 120.78.223.25...
Connected to www.iawen.com.
Escape character is '^]'.

连接会保持一段时间只要你连接的应用服务器时限没到。
输入 CTRL+] 中止连接, 然后当你看到 telnet> 提示, 输入 quit 并按回车:

[root@localhost ~]# telnet www.iawen.com 80
Trying 120.78.223.25...
Connected to www.iawen.com.
Escape character is '^]'.
^]
telnet> q
Connection closed.

总结

客户程序连不上服务器的原因有很多。确切原因很难确定, 特别是当客户是图形用户界面提供很少或没有错误信息。用 telnet 并观察输出可以让你很快确定问题所在节约很多时间。