From 7e4bdf31ba05864b3f306ea588795b7a935f598e Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Sat, 16 Apr 2022 15:27:21 +0300 Subject: [PATCH] lib/httpserver: follow up after def0032c7d6b60da6b3a343d94fc977d4e095a68 --- README.md | 5 ++-- docs/CHANGELOG.md | 1 + docs/README.md | 3 +++ docs/Single-server-VictoriaMetrics.md | 3 +++ lib/httpserver/httpserver.go | 38 +++++++++++++-------------- lib/httpserver/httpserver_test.go | 6 ++--- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index eeb767936..0b9632738 100644 --- a/README.md +++ b/README.md @@ -1923,8 +1923,9 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated -tlsKeyFile string Path to file with TLS key. Used only if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated - -tlsCipherSuites - Cipher suites names for TLS encryption. For example, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA. Used only if -tls flag is set + -tlsCipherSuites array + Optional list of TLS cipher suites for incoming requests over HTTPS if -tls flag is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants + Supports an array of values separated by comma or specified via multiple flags. -version Show VictoriaMetrics version ``` diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index afa5d3dec..75b36cfa4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,6 +16,7 @@ The following tip changes can be tested by building VictoriaMetrics components f ## tip * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add support for DNS-based discovery for notifiers in the same way as Prometheus does. See [these docs](https://docs.victoriametrics.com/vmalert.html#notifier-configuration-file) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2460). +* FEATURE: allow specifying TLS cipher suites for incoming https requests via `-tlsCipherSuites` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2404). * BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): return non-zero exit code on error. This allows handling `vmctl` errors in shell scripts. Previously `vmctl` was returning 0 exit code on error. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2322). * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly show `scrape_timeout` and `scrape_interval` options at `http://vmagent:8429/config` page. Previously these options weren't displayed even if they were set in `-promscrape.config`. diff --git a/docs/README.md b/docs/README.md index e3cbf9d6e..0b9632738 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1923,6 +1923,9 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated -tlsKeyFile string Path to file with TLS key. Used only if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated + -tlsCipherSuites array + Optional list of TLS cipher suites for incoming requests over HTTPS if -tls flag is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants + Supports an array of values separated by comma or specified via multiple flags. -version Show VictoriaMetrics version ``` diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md index e3393b08b..936006aac 100644 --- a/docs/Single-server-VictoriaMetrics.md +++ b/docs/Single-server-VictoriaMetrics.md @@ -1927,6 +1927,9 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated -tlsKeyFile string Path to file with TLS key. Used only if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated + -tlsCipherSuites array + Optional list of TLS cipher suites for incoming requests over HTTPS if -tls flag is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants + Supports an array of values separated by comma or specified via multiple flags. -version Show VictoriaMetrics version ``` diff --git a/lib/httpserver/httpserver.go b/lib/httpserver/httpserver.go index f343ef724..6497057e7 100644 --- a/lib/httpserver/httpserver.go +++ b/lib/httpserver/httpserver.go @@ -33,7 +33,7 @@ var ( tlsEnable = flag.Bool("tls", false, "Whether to enable TLS (aka HTTPS) for incoming requests. -tlsCertFile and -tlsKeyFile must be set if -tls is set") tlsCertFile = flag.String("tlsCertFile", "", "Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated") tlsKeyFile = flag.String("tlsKeyFile", "", "Path to file with TLS key. Used only if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated") - tlsCipherSuites = flagutil.NewArray("tlsCipherSuites", "Cipher suites names for TLS encryption. For example, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA. Used only if -tls flag is set") + tlsCipherSuites = flagutil.NewArray("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls flag is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants") pathPrefix = flag.String("http.pathPrefix", "", "An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, "+ "then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. "+ @@ -101,17 +101,13 @@ func Serve(addr string, rh RequestHandler) { var certLock sync.Mutex var certDeadline uint64 var cert *tls.Certificate - var cipherSuites []uint16 c, err := tls.LoadX509KeyPair(*tlsCertFile, *tlsKeyFile) if err != nil { - logger.Fatalf("cannot load TLS cert from tlsCertFile=%q, tlsKeyFile=%q: %s", *tlsCertFile, *tlsKeyFile, err) + logger.Fatalf("cannot load TLS cert from -tlsCertFile=%q, -tlsKeyFile=%q: %s", *tlsCertFile, *tlsKeyFile, err) } - if len(*tlsCipherSuites) != 0 { - collectedCipherSuites, err := collectCipherSuites(*tlsCipherSuites) - if err != nil { - logger.Fatalf("cannot use TLS cipher suites from tlsCipherSuites=%q: %s", *tlsCipherSuites, err) - } - cipherSuites = collectedCipherSuites + cipherSuites, err := cipherSuitesFromNames(*tlsCipherSuites) + if err != nil { + logger.Fatalf("cannot use TLS cipher suites from -tlsCipherSuites=%q: %s", *tlsCipherSuites, err) } cert = &c cfg := &tls.Config{ @@ -123,7 +119,7 @@ func Serve(addr string, rh RequestHandler) { if fasttime.UnixTimestamp() > certDeadline { c, err = tls.LoadX509KeyPair(*tlsCertFile, *tlsKeyFile) if err != nil { - return nil, fmt.Errorf("cannot load TLS cert from tlsCertFile=%q, tlsKeyFile=%q: %w", *tlsCertFile, *tlsKeyFile, err) + return nil, fmt.Errorf("cannot load TLS cert from -tlsCertFile=%q, -tlsKeyFile=%q: %w", *tlsCertFile, *tlsKeyFile, err) } certDeadline = fasttime.UnixTimestamp() + 1 cert = &c @@ -698,18 +694,20 @@ func GetRequestURI(r *http.Request) string { return requestURI + delimiter + queryArgs } -func collectCipherSuites(definedCipherSuites []string) ([]uint16, error) { - var cipherSuites []uint16 - - supportedCipherSuites := tls.CipherSuites() - supportedCipherSuitesMap := make(map[string]uint16, len(supportedCipherSuites)) - for _, scf := range supportedCipherSuites { - supportedCipherSuitesMap[strings.ToLower(scf.Name)] = scf.ID +func cipherSuitesFromNames(cipherSuiteNames []string) ([]uint16, error) { + if len(cipherSuiteNames) == 0 { + return nil, nil } - for _, gotSuite := range definedCipherSuites { - id, ok := supportedCipherSuitesMap[strings.ToLower(gotSuite)] + css := tls.CipherSuites() + cssMap := make(map[string]uint16, len(css)) + for _, cs := range css { + cssMap[strings.ToLower(cs.Name)] = cs.ID + } + cipherSuites := make([]uint16, 0, len(cipherSuiteNames)) + for _, name := range cipherSuiteNames { + id, ok := cssMap[strings.ToLower(name)] if !ok { - return nil, fmt.Errorf("got unsupported cipher suite name: %s", gotSuite) + return nil, fmt.Errorf("unsupported TLS cipher suite name: %s", name) } cipherSuites = append(cipherSuites, id) } diff --git a/lib/httpserver/httpserver_test.go b/lib/httpserver/httpserver_test.go index b87ec49f1..46d10cda8 100644 --- a/lib/httpserver/httpserver_test.go +++ b/lib/httpserver/httpserver_test.go @@ -5,7 +5,7 @@ import ( "testing" ) -func Test_validateCipherSuites(t *testing.T) { +func TestCipherSuitesFromNames(t *testing.T) { type args struct { definedCipherSuites []string } @@ -65,9 +65,9 @@ func Test_validateCipherSuites(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := collectCipherSuites(tt.args.definedCipherSuites) + got, err := cipherSuitesFromNames(tt.args.definedCipherSuites) if (err != nil) != tt.wantErr { - t.Errorf("collectCipherSuites() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("cipherSuitesFromNames() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) {