Skip to content

Commit 9603dce

Browse files
committed
feat(dataproxy): added whitelist setting and feature for data proxies, closes grafana#2626
1 parent 13190f6 commit 9603dce

File tree

4 files changed

+33
-11
lines changed

4 files changed

+33
-11
lines changed

conf/defaults.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ cookie_remember_name = grafana_remember
121121
# disable gravatar profile images
122122
disable_gravatar = false
123123

124+
# data source proxy whitelist (ip_or_domain:port seperated by spaces)
125+
data_source_proxy_whitelist =
126+
124127
#################################### Users ####################################
125128
[users]
126129
# disable user signup / registration

conf/sample.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Everything has defaults so you only need to uncomment things you want to
44
# change
55

6-
# possible values : production, development
6+
# possible values : production, development
77
; app_mode = production
88

99
#################################### Paths ####################################
@@ -117,6 +117,9 @@
117117
# disable gravatar profile images
118118
;disable_gravatar = false
119119

120+
# data source proxy whitelist (ip_or_domain:port seperated by spaces)
121+
;data_source_proxy_whitelist =
122+
120123
#################################### Users ####################################
121124
[users]
122125
# disable user signup / registration

pkg/api/dataproxy.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/grafana/grafana/pkg/bus"
1212
"github.com/grafana/grafana/pkg/middleware"
1313
m "github.com/grafana/grafana/pkg/models"
14+
"github.com/grafana/grafana/pkg/setting"
1415
"github.com/grafana/grafana/pkg/util"
1516
)
1617

@@ -24,30 +25,28 @@ var dataProxyTransport = &http.Transport{
2425
TLSHandshakeTimeout: 10 * time.Second,
2526
}
2627

27-
func NewReverseProxy(ds *m.DataSource, proxyPath string) *httputil.ReverseProxy {
28-
target, _ := url.Parse(ds.Url)
29-
28+
func NewReverseProxy(ds *m.DataSource, proxyPath string, targetUrl *url.URL) *httputil.ReverseProxy {
3029
director := func(req *http.Request) {
31-
req.URL.Scheme = target.Scheme
32-
req.URL.Host = target.Host
33-
req.Host = target.Host
30+
req.URL.Scheme = targetUrl.Scheme
31+
req.URL.Host = targetUrl.Host
32+
req.Host = targetUrl.Host
3433

3534
reqQueryVals := req.URL.Query()
3635

3736
if ds.Type == m.DS_INFLUXDB_08 {
38-
req.URL.Path = util.JoinUrlFragments(target.Path, "db/"+ds.Database+"/"+proxyPath)
37+
req.URL.Path = util.JoinUrlFragments(targetUrl.Path, "db/"+ds.Database+"/"+proxyPath)
3938
reqQueryVals.Add("u", ds.User)
4039
reqQueryVals.Add("p", ds.Password)
4140
req.URL.RawQuery = reqQueryVals.Encode()
4241
} else if ds.Type == m.DS_INFLUXDB {
43-
req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath)
42+
req.URL.Path = util.JoinUrlFragments(targetUrl.Path, proxyPath)
4443
reqQueryVals.Add("db", ds.Database)
4544
req.URL.RawQuery = reqQueryVals.Encode()
4645
if !ds.BasicAuth {
4746
req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.User, ds.Password))
4847
}
4948
} else {
50-
req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath)
49+
req.URL.Path = util.JoinUrlFragments(targetUrl.Path, proxyPath)
5150
}
5251

5352
if ds.BasicAuth {
@@ -72,11 +71,20 @@ func ProxyDataSourceRequest(c *middleware.Context) {
7271
return
7372
}
7473

74+
ds := query.Result
75+
targetUrl, _ := url.Parse(ds.Url)
76+
if len(setting.DataProxyWhiteList) > 0 {
77+
if _, exists := setting.DataProxyWhiteList[targetUrl.Host]; !exists {
78+
c.JsonApiErr(403, "Data proxy hostname and ip are not included in whitelist", nil)
79+
return
80+
}
81+
}
82+
7583
if query.Result.Type == m.DS_CLOUDWATCH {
7684
ProxyCloudWatchDataSourceRequest(c)
7785
} else {
7886
proxyPath := c.Params("*")
79-
proxy := NewReverseProxy(&query.Result, proxyPath)
87+
proxy := NewReverseProxy(&ds, proxyPath, targetUrl)
8088
proxy.Transport = dataProxyTransport
8189
proxy.ServeHTTP(c.RW(), c.Req.Request)
8290
}

pkg/setting/setting.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ var (
7373
CookieRememberName string
7474
DisableGravatar bool
7575
EmailCodeValidMinutes int
76+
DataProxyWhiteList map[string]bool
7677

7778
// User settings
7879
AllowUserSignUp bool
@@ -378,13 +379,20 @@ func NewConfigContext(args *CommandLineArgs) {
378379
EnableGzip = server.Key("enable_gzip").MustBool(false)
379380
EnforceDomain = server.Key("enforce_domain").MustBool(false)
380381

382+
// read security settings
381383
security := Cfg.Section("security")
382384
SecretKey = security.Key("secret_key").String()
383385
LogInRememberDays = security.Key("login_remember_days").MustInt()
384386
CookieUserName = security.Key("cookie_username").String()
385387
CookieRememberName = security.Key("cookie_remember_name").String()
386388
DisableGravatar = security.Key("disable_gravatar").MustBool(true)
387389

390+
// read data source proxy white list
391+
DataProxyWhiteList = make(map[string]bool)
392+
for _, hostAndIp := range security.Key("data_source_proxy_whitelist").Strings(" ") {
393+
DataProxyWhiteList[hostAndIp] = true
394+
}
395+
388396
// admin
389397
AdminUser = security.Key("admin_user").String()
390398
AdminPassword = security.Key("admin_password").String()

0 commit comments

Comments
 (0)