Skip to content

Commit 2624613

Browse files
committed
logcli: add --proxy-url flag for http/https proxy support
Add `--proxy-url` flag to `logcli` to support connecting to Loki instances running behind either HTTP or HTTPS CONNECT-style proxies. Examples: http proxy: ``` logcli \ --addr="http://loki-distributed-querier.loki.svc.cluster.local.:3100/" \ --proxy-url "http://envoy.dom.tld" \ query '{app"foo"}' ``` https proxy with mTLS auth: ``` logcli \ --addr="https://loki-distributed-querier.loki.svc.cluster.local.:3100/" \ --proxy-url "https://envoy.dom.tld" \ --cert tls.crt \ --key tls.key \ --ca-cert ca.crt \ query '{app"foo"}' ``` Note that tail (`-f`) support and https proxies only works with a fork of the `gorilla/websocket` lib. There are open PRs that promise to add support for https proxies such as: gorilla/websocket#740 Add the following to `go.mod` to use the fork with https support: ``` replace github.com/gorilla/websocket v1.4.2 => github.com/philipatl/websocket v1.4.3-0.20211206152948-d16969baa130 ```
1 parent 7b1ca8d commit 2624613

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

cmd/logcli/main.go

+8
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ func newQueryClient(app *kingpin.Application) client.Client {
224224

225225
// extract host
226226
addressAction := func(c *kingpin.ParseContext) error {
227+
// If a proxy is to be used do not set TLS ServerName. In the case of HTTPS proxy this ensures
228+
// the http client validates both the proxy's cert and the cert used by loki behind the proxy
229+
// using the ServerName's from the provided --addr and --proxy-url flags.
230+
if client.ProxyURL != "" {
231+
return nil
232+
}
233+
227234
u, err := url.Parse(client.Address)
228235
if err != nil {
229236
return err
@@ -245,6 +252,7 @@ func newQueryClient(app *kingpin.Application) client.Client {
245252
app.Flag("bearer-token-file", "adds the Authorization header to API requests for authentication purposes. Can also be set using LOKI_BEARER_TOKEN_FILE env var.").Default("").Envar("LOKI_BEARER_TOKEN_FILE").StringVar(&client.BearerTokenFile)
246253
app.Flag("retries", "How many times to retry each query when getting an error response from Loki. Can also be set using LOKI_CLIENT_RETRIES").Default("0").Envar("LOKI_CLIENT_RETRIES").IntVar(&client.Retries)
247254
app.Flag("auth-header", "The authorization header used. Can also be set using LOKI_AUTH_HEADER").Default("Authorization").Envar("LOKI_AUTH_HEADER").StringVar(&client.AuthHeader)
255+
app.Flag("proxy-url", "The http or https proxy to use when making requests. Can also be set using LOKI_HTTP_PROXY_URL env var.").Default("").Envar("LOKI_HTTP_PROXY_URL").StringVar(&client.ProxyURL)
248256

249257
return client
250258
}

pkg/logcli/client/client.go

+15
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ type DefaultClient struct {
6060
Retries int
6161
QueryTags string
6262
AuthHeader string
63+
ProxyURL string
6364
}
6465

6566
// Query uses the /api/v1/query endpoint to execute an instant query
@@ -191,6 +192,14 @@ func (c *DefaultClient) doRequest(path, query string, quiet bool, out interface{
191192
TLSConfig: c.TLSConfig,
192193
}
193194

195+
if c.ProxyURL != "" {
196+
prox, err := url.Parse(c.ProxyURL)
197+
if err != nil {
198+
return err
199+
}
200+
clientConfig.ProxyURL = config.URL{URL: prox}
201+
}
202+
194203
client, err := config.NewClientFromConfig(clientConfig, "promtail", config.WithHTTP2Disabled())
195204
if err != nil {
196205
return err
@@ -315,6 +324,12 @@ func (c *DefaultClient) wsConnect(path, query string, quiet bool) (*websocket.Co
315324
TLSClientConfig: tlsConfig,
316325
}
317326

327+
if c.ProxyURL != "" {
328+
ws.Proxy = func(req *http.Request) (*url.URL, error) {
329+
return url.Parse(c.ProxyURL)
330+
}
331+
}
332+
318333
conn, resp, err := ws.Dial(us, h)
319334
if err != nil {
320335
if resp == nil {

0 commit comments

Comments
 (0)