问题起源
我们的基础设施监控的使用到了prometheus,客户漏洞扫描扫到了Go pprof调试信息泄漏漏洞,按理来说环境是全内网隔离的,不存在什么风险,并且这个漏洞连CVE/CNVD/CNNVD的编号都没有,是安全厂商自己定义的一个编号,其实我是不想处理的,但是没办法,要求处理掉。
复现方式
访问http://ip:port/debug/pprof/
能够看到golang的调试页面。
处理
这个问题如果你偷懒可以直接使用iptables规则去限制,我说的是彻底解决,那么这个问题分成两个部分:Prometheus Server和exporter
Prometheus Server
我们可以在cmd/prometheus/main.go
中找到:
1
2
3
4
5
|
import (
...
// _ "net/http/pprof" // Comment this line to disable pprof endpoint.
...
)
|
把这个注释掉或者删掉,然后在web/web.go
中可以找到如下函数:
1
2
3
4
5
6
|
func New(logger log.Logger, o *Options) *Handler {
...
// router.Get("/debug/*subpath", serveDebug)
// router.Post("/debug/*subpath", serveDebug)
...
}
|
把这个路由注释掉,再把具体实现也注释掉:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
// func serveDebug(w http.ResponseWriter, req *http.Request) {
// ctx := req.Context()
// subpath := route.Param(ctx, "subpath")
// if subpath == "/pprof" {
// http.Redirect(w, req, req.URL.Path+"/", http.StatusMovedPermanently)
// return
// }
// if !strings.HasPrefix(subpath, "/pprof/") {
// http.NotFound(w, req)
// return
// }
// subpath = strings.TrimPrefix(subpath, "/pprof/")
// switch subpath {
// case "cmdline":
// pprof.Cmdline(w, req)
// case "profile":
// pprof.Profile(w, req)
// case "symbol":
// pprof.Symbol(w, req)
// case "trace":
// pprof.Trace(w, req)
// default:
// req.URL.Path = "/debug/pprof/" + subpath
// pprof.Index(w, req)
// }
// }
|
再次编译以后访问就是404了。
exporter(以node_exporter为例)
在exporter程序的主入口,也就是packege main
中,找到import
把net/http/pprof
的空白导入去掉:
1
2
3
4
5
|
import (
...
// _ "net/http/pprof"
...
)
|
再次编译以后访问就只会跳转到metrics路径了。