mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/proxy: set missing ServerName in TLS config for proxy_url
.
While at it, allow setting Proxy-Authorization for `proxy_url` via `basic_auth` and `bearer_token` configs.
This commit is contained in:
parent
ad34f42467
commit
36fd007247
6 changed files with 53 additions and 14 deletions
|
@ -14,6 +14,7 @@
|
|||
* BUGFIX: vmagent: prevent from high CPU usage bug during failing scrapes with small `scrape_timeout` (less than a few seconds).
|
||||
* BUGFIX: vmagent: reduce memory usage when Kubernetes service discovery is used in big number of distinct scrape config jobs by sharing Kubernetes object cache. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1113
|
||||
* BUGFIX: vmagent: apply `sample_limit` only after `metric_relabel_configs` are applied as Prometheus does. Previously the `sample_limit` was applied before metrics relabeling.
|
||||
* BUGFIX: vmagent: properly apply `tls_config`, `basic_auth` and `bearer_token` to proxy connections if `proxy_url` option is set. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1116
|
||||
* BUGFUX: avoid `duplicate time series` error if `prometheus_buckets()` covers a time range with distinct set of buckets.
|
||||
* BUGFIX: prevent exponent overflow when processing extremely small values close to zero such as `2.964393875E-314`. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1114
|
||||
|
||||
|
|
|
@ -65,13 +65,16 @@ func (ac *Config) tlsCertificateString() string {
|
|||
// NewTLSConfig returns new TLS config for the given ac.
|
||||
func (ac *Config) NewTLSConfig() *tls.Config {
|
||||
tlsCfg := &tls.Config{
|
||||
RootCAs: ac.TLSRootCA,
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(0),
|
||||
}
|
||||
if ac == nil {
|
||||
return tlsCfg
|
||||
}
|
||||
if ac.TLSCertificate != nil {
|
||||
// Do not set tlsCfg.GetClientCertificate, since tlsCfg.Certificates should work OK.
|
||||
tlsCfg.Certificates = []tls.Certificate{*ac.TLSCertificate}
|
||||
}
|
||||
tlsCfg.RootCAs = ac.TLSRootCA
|
||||
tlsCfg.ServerName = ac.TLSServerName
|
||||
tlsCfg.InsecureSkipVerify = ac.TLSInsecureSkipVerify
|
||||
return tlsCfg
|
||||
|
|
|
@ -57,7 +57,7 @@ func newClient(sw *ScrapeWork) *client {
|
|||
requestURI := string(u.RequestURI())
|
||||
isTLS := string(u.Scheme()) == "https"
|
||||
var tlsCfg *tls.Config
|
||||
if sw.AuthConfig != nil {
|
||||
if isTLS {
|
||||
tlsCfg = sw.AuthConfig.NewTLSConfig()
|
||||
}
|
||||
if !strings.Contains(host, ":") {
|
||||
|
@ -67,7 +67,7 @@ func newClient(sw *ScrapeWork) *client {
|
|||
host += ":443"
|
||||
}
|
||||
}
|
||||
dialFunc, err := newStatDialFunc(sw.ProxyURL, tlsCfg)
|
||||
dialFunc, err := newStatDialFunc(sw.ProxyURL, sw.AuthConfig)
|
||||
if err != nil {
|
||||
logger.Fatalf("cannot create dial func: %s", err)
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ func NewClient(apiServer string, ac *promauth.Config, proxyURL proxy.URL) (*Clie
|
|||
|
||||
hostPort := string(u.Host())
|
||||
isTLS := string(u.Scheme()) == "https"
|
||||
if ac != nil {
|
||||
if isTLS {
|
||||
tlsCfg = ac.NewTLSConfig()
|
||||
}
|
||||
if !strings.Contains(hostPort, ":") {
|
||||
|
@ -77,7 +77,7 @@ func NewClient(apiServer string, ac *promauth.Config, proxyURL proxy.URL) (*Clie
|
|||
hostPort = net.JoinHostPort(hostPort, port)
|
||||
}
|
||||
if dialFunc == nil {
|
||||
dialFunc, err = proxyURL.NewDialFunc(tlsCfg)
|
||||
dialFunc, err = proxyURL.NewDialFunc(ac)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package promscrape
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
@ -10,6 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
|
||||
"github.com/VictoriaMetrics/fasthttp"
|
||||
"github.com/VictoriaMetrics/metrics"
|
||||
|
@ -49,8 +49,8 @@ var (
|
|||
stdDialerOnce sync.Once
|
||||
)
|
||||
|
||||
func newStatDialFunc(proxyURL proxy.URL, tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
||||
dialFunc, err := proxyURL.NewDialFunc(tlsConfig)
|
||||
func newStatDialFunc(proxyURL proxy.URL, ac *promauth.Config) (fasthttp.DialFunc, error) {
|
||||
dialFunc, err := proxyURL.NewDialFunc(ac)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -7,9 +7,11 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||
"github.com/VictoriaMetrics/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -48,8 +50,8 @@ func (u *URL) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// NewDialFunc returns dial func for the given pu and tlsConfig.
|
||||
func (u *URL) NewDialFunc(tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
||||
// NewDialFunc returns dial func for the given u and ac.
|
||||
func (u *URL) NewDialFunc(ac *promauth.Config) (fasthttp.DialFunc, error) {
|
||||
if u == nil || u.url == nil {
|
||||
return defaultDialFunc, nil
|
||||
}
|
||||
|
@ -57,18 +59,32 @@ func (u *URL) NewDialFunc(tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
|||
if pu.Scheme != "http" && pu.Scheme != "https" {
|
||||
return nil, fmt.Errorf("unknown scheme=%q for proxy_url=%q, must be http or https", pu.Scheme, pu)
|
||||
}
|
||||
isTLS := pu.Scheme == "https"
|
||||
proxyAddr := addMissingPort(pu.Host, isTLS)
|
||||
var authHeader string
|
||||
if ac != nil {
|
||||
authHeader = ac.Authorization
|
||||
}
|
||||
if pu.User != nil && len(pu.User.Username()) > 0 {
|
||||
userPasswordEncoded := base64.StdEncoding.EncodeToString([]byte(pu.User.String()))
|
||||
authHeader = "Proxy-Authorization: Basic " + userPasswordEncoded + "\r\n"
|
||||
authHeader = "Basic " + userPasswordEncoded
|
||||
}
|
||||
if authHeader != "" {
|
||||
authHeader = "Proxy-Authorization: " + authHeader + "\r\n"
|
||||
}
|
||||
tlsCfg := ac.NewTLSConfig()
|
||||
dialFunc := func(addr string) (net.Conn, error) {
|
||||
proxyConn, err := defaultDialFunc(pu.Host)
|
||||
proxyConn, err := defaultDialFunc(proxyAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot connect to proxy %q: %w", pu, err)
|
||||
}
|
||||
if pu.Scheme == "https" {
|
||||
proxyConn = tls.Client(proxyConn, tlsConfig)
|
||||
if isTLS {
|
||||
tlsCfgLocal := tlsCfg
|
||||
if !tlsCfgLocal.InsecureSkipVerify && tlsCfgLocal.ServerName == "" {
|
||||
tlsCfgLocal = tlsCfgLocal.Clone()
|
||||
tlsCfgLocal.ServerName = tlsServerName(addr)
|
||||
}
|
||||
proxyConn = tls.Client(proxyConn, tlsCfgLocal)
|
||||
}
|
||||
conn, err := sendConnectRequest(proxyConn, addr, authHeader)
|
||||
if err != nil {
|
||||
|
@ -80,6 +96,25 @@ func (u *URL) NewDialFunc(tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
|||
return dialFunc, nil
|
||||
}
|
||||
|
||||
func addMissingPort(addr string, isTLS bool) string {
|
||||
if strings.IndexByte(addr, ':') >= 0 {
|
||||
return addr
|
||||
}
|
||||
port := "80"
|
||||
if isTLS {
|
||||
port = "443"
|
||||
}
|
||||
return addr + ":" + port
|
||||
}
|
||||
|
||||
func tlsServerName(addr string) string {
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return addr
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
func defaultDialFunc(addr string) (net.Conn, error) {
|
||||
network := "tcp4"
|
||||
if netutil.TCP6Enabled() {
|
||||
|
|
Loading…
Reference in a new issue