为什么在不存在的端口上telnet不直接拒绝,而是超时?

为什么在不存在的端口上telnet不直接拒绝,而是超时?
telnet 8.8.8.8 8888

显示

试...

我本来以为,这会被直接拒绝。

背景:当我们有一个 NGINX 反向代理服务器时,如果后端不存在,它会直接检测到,那就太好了。

答案1

这取决于远程端发回的内容。

对于没有进程正在侦听的端口,远程端会发送一个设置了重置 (RST) 位的数据包,这会导致客户端出现“连接被拒绝”错误。另一种可能性是 ICMP“端口不可达”消息,例如 Linuxiptables -j REJECT默认发送的消息。这也会导致“连接被拒绝”。

另一方面,如果远程发送回没有什么,那么客户端就无法知道问题是什么,并且可能会重试和/或等待很长一段时间。

iptablesLinux 上的示例:

# iptables -I 输入 -p tcp --dport 3001 -j 拒绝
# iptables -I 输入 -p tcp --dport 3002 -j 删除

$ NC -v 127.0.0.1 3000
nc: 连接到 127.0.0.1 端口 3000 (tcp) 失败: 连接被拒绝

$ NC -v 127.0.0.1 3001
nc: 连接到 127.0.0.1 端口 3001 (tcp) 失败: 连接被拒绝

$ NC -v 127.0.0.1 3002
(等待...)

因此,要发现后端已关闭,您需要确保有人发回错误。当然,如果整个主机出现故障,这可能很难做到,因此您可能只需要安排更短的超时。

答案2

TCP 堆栈根据一组规则(可能在防火墙级别)决定如何响应连接。您可以 REJECT 连接包 (SYN),但也可以 DROP 它。例如,由于端口扫描,放弃它是有意义的。

相关内容