远程部署的Django服务处理PATCH请求后外部无法收到响应如何解决
问题根因
这个问题是典型的网络层/安全层拦截了PATCH请求对应的响应包导致的,不属于Django或者Gunicorn的应用层问题,大概率和操作系统防火墙、云服务商的网络安全策略有关,具体原因可以分为两类:
- 服务器本地的防火墙(Ubuntu 20.04默认的ufw、iptables、nftables)加载了HTTP方法过滤模块,仅放行GET、POST等常用HTTP方法的响应流量,PATCH方法的响应被出站规则拦截
- 云服务商的安全组、网络ACL、DDoS防护等中间网络设备,默认将PATCH归类为非通用HTTP方法,拦截了对应响应包
因为请求能正常到达Django服务,说明入站规则是放行了PATCH请求的,问题出在出站方向的流量拦截。
排查步骤
- 第一步:临时关闭服务器本地防火墙验证
执行命令sudo ufw disable关闭ufw防火墙,再从外部发起PATCH请求,如果可以正常收到响应,说明是本地防火墙规则导致的问题,测试完成后执行sudo ufw enable恢复防火墙。 - 第二步:检查本地防火墙的HTTP方法过滤规则
分别检查iptables和nftables规则,确认是否存在拦截PATCH方法的配置:
# 查看iptables全量规则中是否有PATCH相关匹配 sudo iptables -L -n -v | grep -i patch # 查看nftables全量规则中是否有PATCH相关匹配 sudo nft list ruleset | grep -i patch
如果输出中存在匹配PATCH方法的DROP/REJECT规则,就是该规则导致的问题。
- 第三步:抓包确认流量走向
在服务器上执行tcpdump抓包,过滤对应服务端口的流量:
sudo tcpdump -i any port 9999 -w patch_capture.pcap
从外部发起PATCH请求后停止抓包,查看抓包文件:如果服务器已经发出了响应包但客户端没有收到,说明是云服务商中间网络拦截;如果服务器根本没有发出响应包,就是本地系统层面的拦截。
解决方案
- 本地防火墙规则问题:添加放行PATCH方法的规则即可,以iptables为例:
# 放行入站PATCH请求 sudo iptables -A INPUT -p tcp --dport 9999 --http-method PATCH -j ACCEPT # 放行对应出站响应 sudo iptables -A OUTPUT -p tcp --sport 9999 -m state --state ESTABLISHED,RELATED -j ACCEPT # 保存规则(安装iptables-persistent组件后生效) sudo netfilter-persistent save
如果使用ufw,可以在/etc/ufw/applications.d/下添加自定义规则,或者直接修改ufw的底层iptables配置。
- 云服务商网络拦截问题:登录云服务商控制台,调整安全组、网络ACL、Web应用防火墙的规则,关闭HTTP方法检测,或者手动放行PATCH方法即可。
内容的提问来源于stack exchange,提问作者YosSaL
相关产品推荐
相关产品推荐

