错误(入侵): 主机匹配区分大小写,混合大小写的主机/主机名会导致错误路由(RFC 4343)

作者: winklemad创建于 2026年8月11日更新于 2026年8月23日

描述错误

访问规则匹配是区分大小写的,但主机名是不区分大小写的(RFC 4343;RFC 3986 §3.2.2 — "主机子组件是不区分大小写的")。ingress/ingress.go中的matchHost使用==strings.HasSuffix比较,而不进行正则化,且在访问包中没有其他任何地方进行正则化:

go
func matchHost(ruleHost, reqHost string) bool {
	if ruleHost == reqHost {
		return true
	}
	if strings.HasPrefix(ruleHost, "*.") {
		toMatch := strings.TrimPrefix(ruleHost, "*")
		return strings.HasSuffix(reqHost, toMatch)
	}
	return false
}

因此,规则的主机名与请求主机名之间的任何大小写差异都会使请求跳过预期的规则,并通过到捕获所有(503 或错误源)中。这可以通过两种方式实现:

  • proxy/proxy.goreq.Host(可以合法地混合大小写)直接传递给FindMatchingRule,而不进行正则化。
  • validateHostname接受混合大小写的主机名,而不进行正则化,因此如下配置将被接受,但永远不会匹配myapp.example.com
yaml
ingress:
  - hostname: myapp.example.com
    service: http://localhost:8080
  - service: http_status:404
$ cloudflared tunnel ingress rule https://MyApp.example.com/

报告捕获所有规则(http_status:404)而不是myapp.example.com。在matchHost/FindMatchingRule上进行混合大小写主机的单元测试失败了main

内容来源: cloudflare/cloudflared