From 137f7e5014cdc93bb40d20d0e7720112fec7816e Mon Sep 17 00:00:00 2001 From: "Ethan J. Gallant" Date: Thu, 9 Mar 2023 14:32:25 -0400 Subject: [PATCH 01/10] Fix Nil pointers in WebSystemdSocket Signed-off-by: Ethan J. Gallant Co-authored-by: William Van Hevelingen Co-authored-by: Stephanie Palis <35511514+stephpalis@users.noreply.github.com> change to var --- web/tls_config.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/tls_config.go b/web/tls_config.go index 47bbca174..b20fed524 100644 --- a/web/tls_config.go +++ b/web/tls_config.go @@ -33,6 +33,7 @@ import ( var ( errNoTLSConfig = errors.New("TLS config is not present") + ErrNoListeners = errors.New("no web listen address or systemd socket flag specified") ) type Config struct { @@ -203,7 +204,11 @@ func ServeMultiple(listeners []net.Listener, server *http.Server, flags *FlagCon // WebSystemdSocket in the FlagConfig is true. The FlagConfig is also passed on // to ServeMultiple. func ListenAndServe(server *http.Server, flags *FlagConfig, logger log.Logger) error { - if *flags.WebSystemdSocket { + if flags.WebSystemdSocket == nil && (flags.WebListenAddresses == nil || len(*flags.WebListenAddresses) == 0) { + return ErrNoListeners + } + + if flags.WebSystemdSocket != nil && *flags.WebSystemdSocket { level.Info(logger).Log("msg", "Listening on systemd activated listeners instead of port listeners.") listeners, err := activation.Listeners() if err != nil { @@ -214,6 +219,7 @@ func ListenAndServe(server *http.Server, flags *FlagConfig, logger log.Logger) e } return ServeMultiple(listeners, server, flags, logger) } + listeners := make([]net.Listener, 0, len(*flags.WebListenAddresses)) for _, address := range *flags.WebListenAddresses { listener, err := net.Listen("tcp", address) From 392e735f6f5f7b20c1f0fc82eb1d4ccf6ffe57d2 Mon Sep 17 00:00:00 2001 From: SuperQ Date: Tue, 21 Mar 2023 08:19:34 +0100 Subject: [PATCH 02/10] Add a Content-Type header to the landing page Set the landing page Content-Type header to HTML. Signed-off-by: SuperQ --- web/landing_page.go | 1 + 1 file changed, 1 insertion(+) diff --git a/web/landing_page.go b/web/landing_page.go index f0747ac36..61e21283e 100644 --- a/web/landing_page.go +++ b/web/landing_page.go @@ -78,5 +78,6 @@ func NewLandingPage(c LandingConfig) (*LandingPageHandler, error) { } func (h *LandingPageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "text/html; charset=UTF-8") w.Write(h.landingPage) } From 3016db3a7ec3fdf5bc1e6a4a51ff124d0beeecf4 Mon Sep 17 00:00:00 2001 From: prombot Date: Tue, 21 Mar 2023 17:51:07 +0000 Subject: [PATCH 03/10] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Makefile.common b/Makefile.common index 6d8007c95..b111d2562 100644 --- a/Makefile.common +++ b/Makefile.common @@ -91,6 +91,8 @@ BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) +SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG)) + ifeq ($(GOHOSTARCH),amd64) ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) # Only supported on amd64 @@ -205,7 +207,7 @@ common-tarball: promu .PHONY: common-docker $(BUILD_DOCKER_ARCHS) common-docker: $(BUILD_DOCKER_ARCHS) $(BUILD_DOCKER_ARCHS): common-docker-%: - docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \ + docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \ -f $(DOCKERFILE_PATH) \ --build-arg ARCH="$*" \ --build-arg OS="linux" \ @@ -214,19 +216,19 @@ $(BUILD_DOCKER_ARCHS): common-docker-%: .PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) common-docker-publish: $(PUBLISH_DOCKER_ARCHS) $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: - docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" + docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) .PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) common-docker-tag-latest: $(TAG_DOCKER_ARCHS) $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" .PHONY: common-docker-manifest common-docker-manifest: - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(DOCKER_IMAGE_TAG)) - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" + DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG)) + DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" .PHONY: promu promu: $(PROMU) From 9165b70cac72ecd997e830c3c612ac1b0ef4b5bf Mon Sep 17 00:00:00 2001 From: SuperQ Date: Sat, 25 Mar 2023 12:36:14 +0100 Subject: [PATCH 04/10] Add a POST form to the landing page Add configuration to the landing page generator to allow a POST form. * Reduce header font size. Signed-off-by: SuperQ --- web/landing_page.css | 6 +++++- web/landing_page.go | 26 ++++++++++++++++++++++++++ web/landing_page.html | 10 ++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/web/landing_page.css b/web/landing_page.css index cc939eaf8..748c821ab 100644 --- a/web/landing_page.css +++ b/web/landing_page.css @@ -5,9 +5,13 @@ body { header { background-color: {{.HeaderColor}}; color: #fff; - font-size: 2rem; + font-size: 1rem; padding: 1rem; } main { padding: 1rem; } +label { + display: inline-block; + width: {{.Form.Width}}em; +} diff --git a/web/landing_page.go b/web/landing_page.go index 61e21283e..c755372ce 100644 --- a/web/landing_page.go +++ b/web/landing_page.go @@ -31,10 +31,27 @@ type LandingConfig struct { CSS string // CSS style tag for the landing page. Name string // The name of the exporter, generally suffixed by _exporter. Description string // A short description about the exporter. + Form LandingForm // A POST form. Links []LandingLinks // Links displayed on the landing page. Version string // The version displayed. } +// LandingForm provides a configuration struct for creating a POST form on the landing page. +type LandingForm struct { + Action string + Inputs []LandingFormInput + Width float64 +} + +// LandingFormInput represents a single form input field. +type LandingFormInput struct { + Label string + Type string + Name string + Placeholder string + Value string +} + type LandingLinks struct { Address string // The URL the link points to. Text string // The text of the link. @@ -54,6 +71,15 @@ var ( func NewLandingPage(c LandingConfig) (*LandingPageHandler, error) { var buf bytes.Buffer + + length := 0 + for _, input := range c.Form.Inputs { + inputLength := len(input.Label) + if inputLength > length { + length = inputLength + } + } + c.Form.Width = (float64(length) + 1) / 2 if c.CSS == "" { if c.HeaderColor == "" { // Default to Prometheus orange. diff --git a/web/landing_page.html b/web/landing_page.html index 68c401702..bc67d7597 100644 --- a/web/landing_page.html +++ b/web/landing_page.html @@ -19,6 +19,16 @@

{{.Name}}

{{ end }} + {{ if .Form.Action }} +
+
+ {{ range .Form.Inputs }} +  
+ {{ end }} + +
+
+ {{ end }} From feef77d7181171c454d163b6d5d8394268963534 Mon Sep 17 00:00:00 2001 From: Daniel Ruggeri Date: Sat, 25 Mar 2023 08:05:27 -0500 Subject: [PATCH 05/10] Refer user to doco from help message Signed-off-by: Daniel Ruggeri --- web/kingpinflag/flag.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/kingpinflag/flag.go b/web/kingpinflag/flag.go index 1434e4bf7..ce6850ff7 100644 --- a/web/kingpinflag/flag.go +++ b/web/kingpinflag/flag.go @@ -38,7 +38,7 @@ func AddFlags(a *kingpin.Application, defaultAddress string) *web.FlagConfig { WebSystemdSocket: systemdSocket, WebConfigFile: a.Flag( "web.config.file", - "[EXPERIMENTAL] Path to configuration file that can enable TLS or authentication.", + "[EXPERIMENTAL] Path to configuration file that can enable TLS or authentication. See: https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md", ).Default("").String(), } return &flags From f213b7f87b64e79e5a8092f30b870203a698d770 Mon Sep 17 00:00:00 2001 From: SuperQ Date: Thu, 30 Mar 2023 07:56:31 +0200 Subject: [PATCH 06/10] Add generic customization to landing page Allow generic additional HTML or CSS to be added to the landing page output. * Fix broken placeholder template. Signed-off-by: SuperQ --- web/landing_page.css | 1 + web/landing_page.go | 2 ++ web/landing_page.html | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/web/landing_page.css b/web/landing_page.css index 748c821ab..260bc8a09 100644 --- a/web/landing_page.css +++ b/web/landing_page.css @@ -15,3 +15,4 @@ label { display: inline-block; width: {{.Form.Width}}em; } +{{.ExtraCSS}} diff --git a/web/landing_page.go b/web/landing_page.go index c755372ce..68266213e 100644 --- a/web/landing_page.go +++ b/web/landing_page.go @@ -33,6 +33,8 @@ type LandingConfig struct { Description string // A short description about the exporter. Form LandingForm // A POST form. Links []LandingLinks // Links displayed on the landing page. + ExtraHTML string // Additional HTML to be embedded. + ExtraCSS string // Additional CSS to be embedded. Version string // The version displayed. } diff --git a/web/landing_page.html b/web/landing_page.html index bc67d7597..4f2e18177 100644 --- a/web/landing_page.html +++ b/web/landing_page.html @@ -23,12 +23,13 @@

{{.Name}}

{{ range .Form.Inputs }} -  
+  
{{ end }}
{{ end }} + {{ .ExtraHTML }} From 906c2817186d93c28b28fad78a048f58b80c88e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Apr 2023 08:59:41 +0000 Subject: [PATCH 07/10] Bump github.com/prometheus/common from 0.41.0 to 0.42.0 Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.41.0 to 0.42.0. - [Release notes](https://github.com/prometheus/common/releases) - [Commits](https://github.com/prometheus/common/compare/v0.41.0...v0.42.0) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 626bacb9b..6ecc03542 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/alecthomas/kingpin/v2 v2.3.2 github.com/coreos/go-systemd/v22 v22.5.0 github.com/go-kit/log v0.2.1 - github.com/prometheus/common v0.41.0 + github.com/prometheus/common v0.42.0 golang.org/x/crypto v0.7.0 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 58e45b59d..84852cd51 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,8 @@ github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.41.0 h1:npo01n6vUlRViIj5fgwiK8vlNIh8bnoxqh3gypKsyAw= -github.com/prometheus/common v0.41.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= From 47811e7ccd676a8580789ad68728f83f9eec58c0 Mon Sep 17 00:00:00 2001 From: Chris Hodges Date: Fri, 7 Apr 2023 08:01:33 -0500 Subject: [PATCH 08/10] Client TLS: Add option to require a specific DNS name in Subject Alternate Name (#126) Signed-off-by: saroshali-dbx Signed-off-by: chodges15 Co-authored-by: saroshali-dbx Co-authored-by: Chris Hodges Co-authored-by: chodges15 --- docs/web-configuration.md | 9 ++++- web/testdata/client2_selfsigned.key | 8 ++--- web/testdata/client2_selfsigned.pem | 20 +++++------ .../web_config_auth_client_san.bad.yaml | 7 ++++ .../web_config_auth_client_san.good.yaml | 9 +++++ web/tls_config.go | 36 +++++++++++++++++++ web/tls_config_test.go | 15 ++++++++ 7 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 web/testdata/web_config_auth_client_san.bad.yaml create mode 100644 web/testdata/web_config_auth_client_san.good.yaml diff --git a/docs/web-configuration.md b/docs/web-configuration.md index e461ffd8e..4042fd0af 100644 --- a/docs/web-configuration.md +++ b/docs/web-configuration.md @@ -37,7 +37,14 @@ tls_server_config: # CA certificate for client certificate authentication to the server. [ client_ca_file: ] - + + # Verify that the client certificate has a Subject Alternate Name (SAN) + # which is an exact match to an entry in this list, else terminate the + # connection. SAN match can be one or multiple of the following: DNS, + # IP, e-mail, or URI address from https://pkg.go.dev/crypto/x509#Certificate. + [ client_allowed_sans: + [ - ] ] + # Minimum TLS version that is acceptable. [ min_version: | default = "TLS12" ] diff --git a/web/testdata/client2_selfsigned.key b/web/testdata/client2_selfsigned.key index d4dad2556..885a41a0f 100644 --- a/web/testdata/client2_selfsigned.key +++ b/web/testdata/client2_selfsigned.key @@ -1,6 +1,6 @@ -----BEGIN PRIVATE KEY----- -MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8CYtAwKp1uLWXLXFE -Ue2Bz6PijwHZcL7jAxtlk2dbW0GlRQ+rcalHCcnExIIKAAehZANiAATlPRxDnbJb -Zq9u+jh7DyEJumQZFqjIDFdFxfHtI6hwyMtlL6FIwpqn3z4uXs2wx6/NsD4XOChy -j/tXXKCHS/22+51TivjGA53c9bLgc4dK/uJJNSivp0kymbtA5vgKzJE= +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCgZCrQEAUVqznwKRvu +dwwi8wutaRaHHHWDd/IpjJopLhcdvONT7Fv57X0foCvmYFOhZANiAAR/zAKpT17i +U9lmokwDicnziss91+vKhQjy2q4EAe1p7jJ9c/fPofP3Zd09pLhkAUONMu0myXjk +piLE1vvL121tWg3E3F0MLjLBqiSWqSkEZjQj0YSk3NoGWX/gMgm8ZyA= -----END PRIVATE KEY----- diff --git a/web/testdata/client2_selfsigned.pem b/web/testdata/client2_selfsigned.pem index 2bd61a7ab..be1426c4a 100644 --- a/web/testdata/client2_selfsigned.pem +++ b/web/testdata/client2_selfsigned.pem @@ -1,12 +1,12 @@ -----BEGIN CERTIFICATE----- -MIIByjCCAU+gAwIBAgIUYcG9p4RzCRdvUGa9BWvc6rB/wMYwCgYIKoZIzj0EAwIw -EDEOMAwGA1UEAwwFdGVzdDIwIBcNMjEwODIwMTUzMjE4WhgPMjEyMTA3MjcxNTMy -MThaMBAxDjAMBgNVBAMMBXRlc3QyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE5T0c -Q52yW2avbvo4ew8hCbpkGRaoyAxXRcXx7SOocMjLZS+hSMKap98+Ll7NsMevzbA+ -Fzgoco/7V1ygh0v9tvudU4r4xgOd3PWy4HOHSv7iSTUor6dJMpm7QOb4CsyRo2gw -ZjAdBgNVHQ4EFgQUWpsZ2aWo6WEI2LiNQXoWKYr0rlkwHwYDVR0jBBgwFoAUWpsZ -2aWo6WEI2LiNQXoWKYr0rlkwDwYDVR0TAQH/BAUwAwEB/zATBgNVHSUEDDAKBggr -BgEFBQcDAjAKBggqhkjOPQQDAgNpADBmAjEA/Mv4OjCqVw8PzxQW4FJmZNyJB4ps -xkAUBRpDy75n64ICsWKX/Mille0bo+C8d63JAjEA3IH/y1O4oyCaawNpibfcwSZK -7ND9Z+WTJi50EumXUWKirmb/V59ToH5nc10x7NDX +MIIB3DCCAWGgAwIBAgIUJVN8KehL1MmccvLb/mHthSMfnnswCgYIKoZIzj0EAwIw +EDEOMAwGA1UEAwwFdGVzdDMwIBcNMjMwMTEwMTgxMTAwWhgPMjEyMjEyMTcxODEx +MDBaMBAxDjAMBgNVBAMMBXRlc3QzMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEf8wC +qU9e4lPZZqJMA4nJ84rLPdfryoUI8tquBAHtae4yfXP3z6Hz92XdPaS4ZAFDjTLt +Jsl45KYixNb7y9dtbVoNxNxdDC4ywaoklqkpBGY0I9GEpNzaBll/4DIJvGcgo3ow +eDAdBgNVHQ4EFgQUvyvu/TnJyRS7OGdujTbWM/W07yMwHwYDVR0jBBgwFoAUvyvu +/TnJyRS7OGdujTbWM/W07yMwDwYDVR0TAQH/BAUwAwEB/zAQBgNVHREECTAHggV0 +ZXN0MzATBgNVHSUEDDAKBggrBgEFBQcDAjAKBggqhkjOPQQDAgNpADBmAjEAt7HK +knE2MzwZ2B2dgn1/q3ikWDiO20Hbd97jo3tmv87FcF2vMqqJpHjcldJqplfsAjEA +sfAz49y6Sf6LNlNS+Fc/lbOOwcrlzC+J5GJ8OmNoQPsvvDvhzGbwFiVw1M2uMqtG -----END CERTIFICATE----- diff --git a/web/testdata/web_config_auth_client_san.bad.yaml b/web/testdata/web_config_auth_client_san.bad.yaml new file mode 100644 index 000000000..3b0d91897 --- /dev/null +++ b/web/testdata/web_config_auth_client_san.bad.yaml @@ -0,0 +1,7 @@ +tls_server_config: + cert_file: "server.crt" + key_file: "server.key" + client_auth_type: "RequireAndVerifyClientCert" + client_ca_file: "client2_selfsigned.pem" + client_allowed_sans: + - "bad" diff --git a/web/testdata/web_config_auth_client_san.good.yaml b/web/testdata/web_config_auth_client_san.good.yaml new file mode 100644 index 000000000..88eaad1ea --- /dev/null +++ b/web/testdata/web_config_auth_client_san.good.yaml @@ -0,0 +1,9 @@ +tls_server_config: + cert_file: "server.crt" + key_file: "server.key" + client_auth_type: "RequireAndVerifyClientCert" + client_ca_file: "client2_selfsigned.pem" + client_allowed_sans: + - "one" + - "test3" + - "two" diff --git a/web/tls_config.go b/web/tls_config.go index b20fed524..4ef31a3f9 100644 --- a/web/tls_config.go +++ b/web/tls_config.go @@ -52,6 +52,7 @@ type TLSConfig struct { MinVersion TLSVersion `yaml:"min_version"` MaxVersion TLSVersion `yaml:"max_version"` PreferServerCipherSuites bool `yaml:"prefer_server_cipher_suites"` + ClientAllowedSans []string `yaml:"client_allowed_sans"` } type FlagConfig struct { @@ -67,6 +68,36 @@ func (t *TLSConfig) SetDirectory(dir string) { t.ClientCAs = config_util.JoinDir(dir, t.ClientCAs) } +// VerifyPeerCertificate will check the SAN entries of the client cert if there is configuration for it +func (t *TLSConfig) VerifyPeerCertificate(rawCerts [][]byte, _ [][]*x509.Certificate) error { + // sender cert comes first, see https://www.rfc-editor.org/rfc/rfc5246#section-7.4.2 + cert, err := x509.ParseCertificate(rawCerts[0]) + if err != nil { + return fmt.Errorf("error parsing client certificate: %s", err) + } + + // Build up a slice of strings with all Subject Alternate Name values + sanValues := append(cert.DNSNames, cert.EmailAddresses...) + + for _, ip := range cert.IPAddresses { + sanValues = append(sanValues, ip.String()) + } + + for _, uri := range cert.URIs { + sanValues = append(sanValues, uri.String()) + } + + for _, sanValue := range sanValues { + for _, allowedSan := range t.ClientAllowedSans { + if sanValue == allowedSan { + return nil + } + } + } + + return fmt.Errorf("could not find allowed SANs in client cert, found: %v", t.ClientAllowedSans) +} + type HTTPConfig struct { HTTP2 bool `yaml:"http2"` Header map[string]string `yaml:"headers,omitempty"` @@ -164,6 +195,11 @@ func ConfigToTLSConfig(c *TLSConfig) (*tls.Config, error) { cfg.ClientCAs = clientCAPool } + if c.ClientAllowedSans != nil { + // verify that the client cert contains an allowed SAN + cfg.VerifyPeerCertificate = c.VerifyPeerCertificate + } + switch c.ClientAuth { case "RequestClientCert": cfg.ClientAuth = tls.RequestClientCert diff --git a/web/tls_config_test.go b/web/tls_config_test.go index ceb7f9b20..b24793387 100644 --- a/web/tls_config_test.go +++ b/web/tls_config_test.go @@ -67,6 +67,7 @@ var ( "Bad certificate": regexp.MustCompile(`bad certificate`), "Invalid value": regexp.MustCompile(`invalid value for`), "Invalid header": regexp.MustCompile(`HTTP header ".*" can not be configured`), + "Invalid client cert": regexp.MustCompile(`bad certificate`), } ) @@ -347,6 +348,20 @@ func TestServerBehaviour(t *testing.T) { ClientCertificate: "client2_selfsigned", ExpectedError: ErrorMap["Bad certificate"], }, + { + Name: `valid tls config yml and tls client with VerifyPeerCertificate (present good SAN DNS entry)`, + YAMLConfigPath: "testdata/web_config_auth_client_san.good.yaml", + UseTLSClient: true, + ClientCertificate: "client2_selfsigned", + ExpectedError: nil, + }, + { + Name: `valid tls config yml and tls client with VerifyPeerCertificate (present invalid SAN DNS entries)`, + YAMLConfigPath: "testdata/web_config_auth_client_san.bad.yaml", + UseTLSClient: true, + ClientCertificate: "client2_selfsigned", + ExpectedError: ErrorMap["Invalid client cert"], + }, } for _, testInputs := range testTables { t.Run(testInputs.Name, testInputs.Test) From 3791ec9784d5322e5b8041a69d94f5fe20cbcc95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 08:58:19 +0000 Subject: [PATCH 09/10] Bump golang.org/x/crypto from 0.7.0 to 0.8.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.7.0 to 0.8.0. - [Release notes](https://github.com/golang/crypto/releases) - [Commits](https://github.com/golang/crypto/compare/v0.7.0...v0.8.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 6ecc03542..29f799964 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 github.com/go-kit/log v0.2.1 github.com/prometheus/common v0.42.0 - golang.org/x/crypto v0.7.0 + golang.org/x/crypto v0.8.0 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -26,10 +26,10 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.9.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect ) diff --git a/go.sum b/go.sum index 84852cd51..549ead4e1 100644 --- a/go.sum +++ b/go.sum @@ -53,23 +53,23 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= From 3df73726ec6949056d31d1d477ac4a2f06134797 Mon Sep 17 00:00:00 2001 From: SuperQ Date: Mon, 1 May 2023 17:32:03 +0200 Subject: [PATCH 10/10] Release 0.10.0 * [FEATURE] Client TLS: Add option to require a specific Subject Alternate Names #126 * [FEATURE] Add a POST form to the landing page #144 * [FEATURE] Add generic customization to landing page #146 * [ENHANCEMENT] Add a Content-Type header to the landing page #142 * [BUGFIX] Fix Nil pointer references for WebSystemdSocket #127 Signed-off-by: SuperQ --- CHANGELOG.md | 8 ++++++++ VERSION | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7434800a6..0b229de10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.10.0 / 2023-05-01 + +* [FEATURE] Client TLS: Add option to require a specific Subject Alternate Names #126 +* [FEATURE] Add a POST form to the landing page #144 +* [FEATURE] Add generic customization to landing page #146 +* [ENHANCEMENT] Add a Content-Type header to the landing page #142 +* [BUGFIX] Fix Nil pointer references for WebSystemdSocket #127 + ## 0.9.1 / 2023-03-08 * [BUGFIX] Landing page: Use HTML5 and Semantic HTML tags #138 diff --git a/VERSION b/VERSION index f374f6662..78bc1abd1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.1 +0.10.0