我最近更新了面向公众的 NGINX 实例的设置,以添加对 http2 的支持。之后,我查看日志以了解其使用频率,发现与托管网站无关的新日志条目快速增加。
首先是一堆发出CONNECT
请求的条目,这些条目都失败了,出现 400 错误,因为 NGINX 实例未配置为转发代理。我已设置 fail2ban 规则来丢弃来自多个源 IP 地址的流量。我对此并不特别担心(如果需要,请添加评论)。
下一组条目是GET
请求,但它们没有路径,而是有完整的 URL 作为目标,例如
222.223.121.231 - - [16/Jul/2020:12:57:37 +0100] "GET http://api.gxout.com/proxy/check.aspx HTTP/1.1" 404 199 "http://api.gxout.com/proxy/check.aspx" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
其中大多数都按预期再次收到 404 响应,并且我添加了另一个 fail2ban 规则来丢弃来自源 IP 地址的数据包(再次,我并不真正关心这些)。
还有一些类似的帖子得到了 200 条回复,这些就是我担心的,例如
35.236.60.202 - - [16/Jul/2020:11:52:28 +0100] "GET http://www.nike.com/ HTTP/1.1" 200 396 "-" "python-requests/2.20.0"
我有以下问题:
- 为什么 NGINX 会对这个请求返回 200?
- 有关如何调试这个问题的建议吗?
所有传入流量都应为 https(必需或 http2),并且我固定在 TLS 1.2 或 1.3,所以我认为使用 tcpdump 捕获流量不会有帮助(我假设我无法将私钥输入 wireshark 并解码数据包?)。
我能想到的唯一其他选择是添加一些自定义日志记录(是否可以将响应数据记录在 nginx 访问日志中?) 到 NGINX 来记录整个请求/响应。我过去曾这样做过,以调试 oAuth2.0 令牌交换问题,但仅限于我可以完全控制所有传入流量的系统。
答案1
我认为没有必要进一步调试这个问题,因为有些事情是显而易见的:
python-requests/2.20.0
as User-Agent 表示一些 Python 脚本。流行的Pythonrequests
库使编写简单的机器人变得非常容易,无论好坏。
如果 NGINX 中有一个允许响应任何Host:
标头的默认服务器,则向未知主机名返回 200 可能是很典型的。
请原谅我的措辞,但是默认情况下,NGINX 中的默认服务器将响应任何Host:
。然后,要200
返回 ,您的应用必须不检查域名,并且不针对您网站的规范域名发出重定向。
就像在典型情况下“您知道您托管哪些域”一样,任何带有外部域名(或无域名)的请求都可能被视为恶意/不受欢迎的。
你可能想看看蜜罐阻断方法对于“域名不是您的”这种请求 - 大多数恶意/坏机器人实际上只会提供裸IP作为标Host:
头的值,仅仅是因为他们懒得检查给定IP上位于哪些域名(请注意,他们只是通过枚举网络/IP地址来找到受害者)。
对于使用完整 URL 而不是 URI 的请求,这可能是任何东西,包括编写不良的机器人、代理检查器等。
如果您有很多这样的请求,并且在您的后端生成 404 错误,我建议直接在配置中使用简单规则拒绝此请求,并可能添加即时阻止,而不是使用 Fail2ban。
location ~ "^https?:/" {
return 404;
}