mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-02-09 15:27:11 +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: 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: 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: 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.
|
* 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
|
* 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.
|
// NewTLSConfig returns new TLS config for the given ac.
|
||||||
func (ac *Config) NewTLSConfig() *tls.Config {
|
func (ac *Config) NewTLSConfig() *tls.Config {
|
||||||
tlsCfg := &tls.Config{
|
tlsCfg := &tls.Config{
|
||||||
RootCAs: ac.TLSRootCA,
|
|
||||||
ClientSessionCache: tls.NewLRUClientSessionCache(0),
|
ClientSessionCache: tls.NewLRUClientSessionCache(0),
|
||||||
}
|
}
|
||||||
|
if ac == nil {
|
||||||
|
return tlsCfg
|
||||||
|
}
|
||||||
if ac.TLSCertificate != nil {
|
if ac.TLSCertificate != nil {
|
||||||
// Do not set tlsCfg.GetClientCertificate, since tlsCfg.Certificates should work OK.
|
// Do not set tlsCfg.GetClientCertificate, since tlsCfg.Certificates should work OK.
|
||||||
tlsCfg.Certificates = []tls.Certificate{*ac.TLSCertificate}
|
tlsCfg.Certificates = []tls.Certificate{*ac.TLSCertificate}
|
||||||
}
|
}
|
||||||
|
tlsCfg.RootCAs = ac.TLSRootCA
|
||||||
tlsCfg.ServerName = ac.TLSServerName
|
tlsCfg.ServerName = ac.TLSServerName
|
||||||
tlsCfg.InsecureSkipVerify = ac.TLSInsecureSkipVerify
|
tlsCfg.InsecureSkipVerify = ac.TLSInsecureSkipVerify
|
||||||
return tlsCfg
|
return tlsCfg
|
||||||
|
|
|
@ -57,7 +57,7 @@ func newClient(sw *ScrapeWork) *client {
|
||||||
requestURI := string(u.RequestURI())
|
requestURI := string(u.RequestURI())
|
||||||
isTLS := string(u.Scheme()) == "https"
|
isTLS := string(u.Scheme()) == "https"
|
||||||
var tlsCfg *tls.Config
|
var tlsCfg *tls.Config
|
||||||
if sw.AuthConfig != nil {
|
if isTLS {
|
||||||
tlsCfg = sw.AuthConfig.NewTLSConfig()
|
tlsCfg = sw.AuthConfig.NewTLSConfig()
|
||||||
}
|
}
|
||||||
if !strings.Contains(host, ":") {
|
if !strings.Contains(host, ":") {
|
||||||
|
@ -67,7 +67,7 @@ func newClient(sw *ScrapeWork) *client {
|
||||||
host += ":443"
|
host += ":443"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dialFunc, err := newStatDialFunc(sw.ProxyURL, tlsCfg)
|
dialFunc, err := newStatDialFunc(sw.ProxyURL, sw.AuthConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot create dial func: %s", err)
|
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())
|
hostPort := string(u.Host())
|
||||||
isTLS := string(u.Scheme()) == "https"
|
isTLS := string(u.Scheme()) == "https"
|
||||||
if ac != nil {
|
if isTLS {
|
||||||
tlsCfg = ac.NewTLSConfig()
|
tlsCfg = ac.NewTLSConfig()
|
||||||
}
|
}
|
||||||
if !strings.Contains(hostPort, ":") {
|
if !strings.Contains(hostPort, ":") {
|
||||||
|
@ -77,7 +77,7 @@ func NewClient(apiServer string, ac *promauth.Config, proxyURL proxy.URL) (*Clie
|
||||||
hostPort = net.JoinHostPort(hostPort, port)
|
hostPort = net.JoinHostPort(hostPort, port)
|
||||||
}
|
}
|
||||||
if dialFunc == nil {
|
if dialFunc == nil {
|
||||||
dialFunc, err = proxyURL.NewDialFunc(tlsCfg)
|
dialFunc, err = proxyURL.NewDialFunc(ac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package promscrape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -10,6 +9,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
|
||||||
"github.com/VictoriaMetrics/fasthttp"
|
"github.com/VictoriaMetrics/fasthttp"
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"github.com/VictoriaMetrics/metrics"
|
||||||
|
@ -49,8 +49,8 @@ var (
|
||||||
stdDialerOnce sync.Once
|
stdDialerOnce sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
func newStatDialFunc(proxyURL proxy.URL, tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
func newStatDialFunc(proxyURL proxy.URL, ac *promauth.Config) (fasthttp.DialFunc, error) {
|
||||||
dialFunc, err := proxyURL.NewDialFunc(tlsConfig)
|
dialFunc, err := proxyURL.NewDialFunc(ac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||||
"github.com/VictoriaMetrics/fasthttp"
|
"github.com/VictoriaMetrics/fasthttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,8 +50,8 @@ func (u *URL) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDialFunc returns dial func for the given pu and tlsConfig.
|
// NewDialFunc returns dial func for the given u and ac.
|
||||||
func (u *URL) NewDialFunc(tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
func (u *URL) NewDialFunc(ac *promauth.Config) (fasthttp.DialFunc, error) {
|
||||||
if u == nil || u.url == nil {
|
if u == nil || u.url == nil {
|
||||||
return defaultDialFunc, 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" {
|
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)
|
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
|
var authHeader string
|
||||||
|
if ac != nil {
|
||||||
|
authHeader = ac.Authorization
|
||||||
|
}
|
||||||
if pu.User != nil && len(pu.User.Username()) > 0 {
|
if pu.User != nil && len(pu.User.Username()) > 0 {
|
||||||
userPasswordEncoded := base64.StdEncoding.EncodeToString([]byte(pu.User.String()))
|
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) {
|
dialFunc := func(addr string) (net.Conn, error) {
|
||||||
proxyConn, err := defaultDialFunc(pu.Host)
|
proxyConn, err := defaultDialFunc(proxyAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot connect to proxy %q: %w", pu, err)
|
return nil, fmt.Errorf("cannot connect to proxy %q: %w", pu, err)
|
||||||
}
|
}
|
||||||
if pu.Scheme == "https" {
|
if isTLS {
|
||||||
proxyConn = tls.Client(proxyConn, tlsConfig)
|
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)
|
conn, err := sendConnectRequest(proxyConn, addr, authHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -80,6 +96,25 @@ func (u *URL) NewDialFunc(tlsConfig *tls.Config) (fasthttp.DialFunc, error) {
|
||||||
return dialFunc, nil
|
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) {
|
func defaultDialFunc(addr string) (net.Conn, error) {
|
||||||
network := "tcp4"
|
network := "tcp4"
|
||||||
if netutil.TCP6Enabled() {
|
if netutil.TCP6Enabled() {
|
||||||
|
|
Loading…
Reference in a new issue