6
6
"crypto/x509"
7
7
"encoding/pem"
8
8
"errors"
9
+ "fmt"
9
10
"net"
10
11
"net/http"
11
12
"os"
39
40
// PluginSecureSocksProxyServerName is a constant for the GF_SECURE_SOCKS_DATASOURCE_PROXY_SERVER_NAME
40
41
// environment variable used to specify the server name of the secure socks proxy.
41
42
PluginSecureSocksProxyServerName = "GF_SECURE_SOCKS_DATASOURCE_PROXY_SERVER_NAME"
43
+ // PluginSecureSocksProxyAllowInsecure is a constant for the GF_SECURE_SOCKS_DATASOURCE_PROXY_ALLOW_INSECURE
44
+ // environment variable used to specify if the proxy should use a TLS dialer.
45
+ PluginSecureSocksProxyAllowInsecure = "GF_SECURE_SOCKS_DATASOURCE_PROXY_ALLOW_INSECURE"
42
46
)
43
47
44
48
var (
@@ -60,11 +64,12 @@ type Client interface {
60
64
// ClientCfg contains the information needed to allow datasource connections to be
61
65
// proxied to a secure socks proxy.
62
66
type ClientCfg struct {
63
- ClientCert string
64
- ClientKey string
65
- RootCA string
66
- ProxyAddress string
67
- ServerName string
67
+ ClientCert string
68
+ ClientKey string
69
+ RootCA string
70
+ ProxyAddress string
71
+ ServerName string
72
+ AllowInsecure bool
68
73
}
69
74
70
75
// New creates a new proxy client from a given config.
@@ -119,6 +124,38 @@ func (p *cfgProxyWrapper) NewSecureSocksProxyContextDialer() (proxy.Dialer, erro
119
124
return nil , errors .New ("proxy not enabled" )
120
125
}
121
126
127
+ var dialer proxy.Dialer
128
+
129
+ if p .opts .ClientCfg .AllowInsecure {
130
+ dialer = & net.Dialer {
131
+ Timeout : p .opts .Timeouts .Timeout ,
132
+ KeepAlive : p .opts .Timeouts .KeepAlive ,
133
+ }
134
+ } else {
135
+ d , err := p .getTLSDialer ()
136
+ if err != nil {
137
+ return nil , fmt .Errorf ("instantiating tls dialer: %w" , err )
138
+ }
139
+ dialer = d
140
+ }
141
+
142
+ var auth * proxy.Auth
143
+ if p .opts .Auth != nil {
144
+ auth = & proxy.Auth {
145
+ User : p .opts .Auth .Username ,
146
+ Password : p .opts .Auth .Password ,
147
+ }
148
+ }
149
+
150
+ dialSocksProxy , err := proxy .SOCKS5 ("tcp" , p .opts .ClientCfg .ProxyAddress , auth , dialer )
151
+ if err != nil {
152
+ return nil , err
153
+ }
154
+
155
+ return newInstrumentedSocksDialer (dialSocksProxy ), nil
156
+ }
157
+
158
+ func (p * cfgProxyWrapper ) getTLSDialer () (* tls.Dialer , error ) {
122
159
certPool := x509 .NewCertPool ()
123
160
for _ , rootCAFile := range strings .Split (p .opts .ClientCfg .RootCA , " " ) {
124
161
// nolint:gosec
@@ -144,7 +181,7 @@ func (p *cfgProxyWrapper) NewSecureSocksProxyContextDialer() (proxy.Dialer, erro
144
181
return nil , err
145
182
}
146
183
147
- tlsDialer := & tls.Dialer {
184
+ return & tls.Dialer {
148
185
Config : & tls.Config {
149
186
Certificates : []tls.Certificate {cert },
150
187
ServerName : p .opts .ClientCfg .ServerName ,
@@ -155,22 +192,7 @@ func (p *cfgProxyWrapper) NewSecureSocksProxyContextDialer() (proxy.Dialer, erro
155
192
Timeout : p .opts .Timeouts .Timeout ,
156
193
KeepAlive : p .opts .Timeouts .KeepAlive ,
157
194
},
158
- }
159
-
160
- var auth * proxy.Auth
161
- if p .opts .Auth != nil {
162
- auth = & proxy.Auth {
163
- User : p .opts .Auth .Username ,
164
- Password : p .opts .Auth .Password ,
165
- }
166
- }
167
-
168
- dialSocksProxy , err := proxy .SOCKS5 ("tcp" , p .opts .ClientCfg .ProxyAddress , auth , tlsDialer )
169
- if err != nil {
170
- return nil , err
171
- }
172
-
173
- return newInstrumentedSocksDialer (dialSocksProxy ), nil
195
+ }, nil
174
196
}
175
197
176
198
// getConfigFromEnv gets the needed proxy information from the env variables that Grafana set with the values from the config ini
@@ -182,6 +204,26 @@ func getConfigFromEnv() *ClientCfg {
182
204
}
183
205
}
184
206
207
+ proxyAddress := ""
208
+ if value , ok := os .LookupEnv (PluginSecureSocksProxyProxyAddress ); ok {
209
+ proxyAddress = value
210
+ } else {
211
+ return nil
212
+ }
213
+
214
+ allowInsecure := false
215
+ if value , ok := os .LookupEnv (PluginSecureSocksProxyAllowInsecure ); ok {
216
+ allowInsecure , _ = strconv .ParseBool (value )
217
+ }
218
+
219
+ // We only need to fill these fields on insecure mode.
220
+ if allowInsecure {
221
+ return & ClientCfg {
222
+ ProxyAddress : proxyAddress ,
223
+ AllowInsecure : allowInsecure ,
224
+ }
225
+ }
226
+
185
227
clientCert := ""
186
228
if value , ok := os .LookupEnv (PluginSecureSocksProxyClientCert ); ok {
187
229
clientCert = value
@@ -203,13 +245,6 @@ func getConfigFromEnv() *ClientCfg {
203
245
return nil
204
246
}
205
247
206
- proxyAddress := ""
207
- if value , ok := os .LookupEnv (PluginSecureSocksProxyProxyAddress ); ok {
208
- proxyAddress = value
209
- } else {
210
- return nil
211
- }
212
-
213
248
serverName := ""
214
249
if value , ok := os .LookupEnv (PluginSecureSocksProxyServerName ); ok {
215
250
serverName = value
@@ -218,11 +253,12 @@ func getConfigFromEnv() *ClientCfg {
218
253
}
219
254
220
255
return & ClientCfg {
221
- ClientCert : clientCert ,
222
- ClientKey : clientKey ,
223
- RootCA : rootCA ,
224
- ProxyAddress : proxyAddress ,
225
- ServerName : serverName ,
256
+ ClientCert : clientCert ,
257
+ ClientKey : clientKey ,
258
+ RootCA : rootCA ,
259
+ ProxyAddress : proxyAddress ,
260
+ ServerName : serverName ,
261
+ AllowInsecure : false ,
226
262
}
227
263
}
228
264
0 commit comments