![如果是 PUT 或 DELETE 请求,则任何 http 请求都会发生“连接重置”](https://linux22.com/image/1608570/%E5%A6%82%E6%9E%9C%E6%98%AF%20PUT%20%E6%88%96%20DELETE%20%E8%AF%B7%E6%B1%82%EF%BC%8C%E5%88%99%E4%BB%BB%E4%BD%95%20http%20%E8%AF%B7%E6%B1%82%E9%83%BD%E4%BC%9A%E5%8F%91%E7%94%9F%E2%80%9C%E8%BF%9E%E6%8E%A5%E9%87%8D%E7%BD%AE%E2%80%9D.png)
我的服务器最近重新安装了 Ubuntu 18.04,遇到了非常奇怪的问题:连接重置所有请求,这是一个PUT
或DELETE
请求。以下是一些示例:
(顺便说一下,这只是一个空的 nginx 服务器)
curl <ip>
<!DOCTYPE html>
...
curl -X POST <ip>
<html>
<head><title>400 Bad Request</title></head>
...
现在到了有趣的部分:连接PUT
重置DELETE
。
curl -X PUT <ip>
curl: (56) Recv failure: Connection reset by peer
curl -X DELETE <ip>
curl: (56) Recv failure: Connection reset by peer
另一个奇怪的地方是,当发布随机的非 RESTful 请求时,连接正常:
curl -X BLARRGHRGH <ip>
<html>
<head><title>405 Not Allowed</title></head>
我使用调查了这个问题telnet
,结果发现一旦请求是PUT
和DELETE
请求,连接就会意外关闭:
telnet <ip> 80
Trying <ip>...
Connected to <ip>.
Escape character is '^]'.
PUT / HTTP/1.1
Connection closed by foreign host.
另一方面,GET 或 POST 工作正常。这个问题在所有端口和所有软件上都存在,比如 jupyter lab。它在端口 8080 上运行,这也是我开始研究这个问题的原因:
但是它不能保存或删除文件,也不能修改它们:
- 系统版本:Ubuntu 18.04.3 LTS(Bionic Beaver)
- 路由表:路由表
- 最后
iptables -S
:iptables -S
如果有人知道的话,请告诉我。我有点急于解决这个问题。谢谢!!
编辑:正如 @grawity 指出的那样,我跑过去tcpdump
看到了这个:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno1, link-type EN10MB (Ethernet), capture size 262144 bytes
02:40:41.372611 IP 10.61.144.243.64630 > 172.31.152.6.80: Flags [S], seq 1059357560, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 130796586 ecr 0,sackOK,eol], length 0
E..@..@.=.^b
=.......v.P?$.x.........L.............
...*........
02:40:41.372676 IP 172.31.152.6.80 > 10.61.144.243.64630: Flags [S.], seq 1764151353, ack 1059357561, win 28960, options [mss 1460,sackOK,TS val 2322551000 ecr 130796586,nop,wscale 7], length 0
E..<..@.@.[f....
=...P.vi&.9?$.y..q ...........
.oP....*....
02:40:41.374916 IP 10.61.144.243.64630 > 172.31.152.6.80: Flags [.], ack 1, win 2058, options [nop,nop,TS val 130796588 ecr 2322551000], length 0
E..4..@.=.^n
=.......v.P?$.yi&.:...
.W.....
...,.oP.
02:40:41.422352 IP 10.61.144.243.64630 > 172.31.152.6.80: Flags [R.], seq 1, ack 1, win 8224, options [nop,nop,TS val 130796634 ecr 2322551000], length 0
E..4fU@.=...
=.......v.P?$.yi&.:.. .......
...Z.oP.
这是一个 curl 请求。这里根本没有 PUT 或符合条件的文本。这很奇怪,因为如果此请求是由 制造的telnet
,则第一行可能会被捕获,这是有道理的,因为telnet
总是在完成一行后刷新:
02:43:14.735256 IP 10.61.144.243.65219 > 172.31.152.6.80: Flags [P.], seq 1:17, ack 1, win 2058, options [nop,nop,TS val 130949575 ecr 2322695469], length 16: HTTP: PUT / HTTP/1.1
E..D..@.=.^^
=.........P...........
z......
..!..q.-PUT / HTTP/1.1
02:43:14.735310 IP 172.31.152.6.80 > 10.61.144.243.65219: Flags [.], ack 17, win 227, options [nop,nop,TS val 2322704367 ecr 130949575], length 0
E..4..@[email protected].....
=...P...............|.....
.q....!.
02:43:23.386996 IP 10.61.144.243.65219 > 172.31.152.6.80: Flags [R.], seq 17, ack 1, win 8224, options [nop,nop,TS val 130958209 ecr 2322704367], length 0
E..4fU@.=...
=.........P.......... .......
..C..q..
然而,第二次进入后,连接意外关闭。我开始想这可能是由于学校里我不知道的数据包检查造成的?这有道理吗?
编辑: curl -v
:
curl -v -X PUT 172.31.152.6
* Trying 172.31.152.6...
* TCP_NODELAY set
* Connected to 172.31.152.6 (172.31.152.6) port 80 (#0)
> PUT / HTTP/1.1
> Host: 172.31.152.6
> User-Agent: curl/7.64.1
> Accept: */*
>
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer
答案1
您的日志显示:
带有请求的数据包甚至没有到达服务器。无论服务器端配置如何,Tcpdump 都会显示网络接口上收到的任何内容。
客户端认为它正在从服务器接收 TCP RST,但服务器上的 tcpdump 实际上并未显示它正在发送。相反,它显示 TCP RST来自客户的地址。
唯一的结论是,在你的客户端和服务器之间有一个防火墙在运行某种“入侵防御系统”——它出于某种原因阻止了它认为是恶意的数据包,并且它正在发送被欺骗TCP RST 代表对端向两个对端发送。
使用 HTTPS 来解决该问题 - 它将使确切的请求内容对于所有中间盒和其他中间设备不可见。
为了缩小发生阻塞的范围,请尝试将相同的阻塞请求从同一 LAN 发送到其他不相关的服务器(通过纯 HTTP),并从其他客户端(例如从 4G 连接)发送到您自己的服务器。