From 28dcff579151ecb47be2de33b5f047b9c6e1dab5 Mon Sep 17 00:00:00 2001
From: Dmytro Kozlov <kozlovdmitriyy@gmail.com>
Date: Mon, 26 Sep 2022 17:35:45 +0300
Subject: [PATCH] lib/{httpserver,netutil}: allow to define min and max TLS
 version of the http server (#3109)

* lib/{httpserver,netutil}: allow to define min and max TLS version of the http server

* lib/httpserver: added descriptions about tls supported versions

* lib/netutil: check minimal tls version, added supported tls versions to error

* wip

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
---
 README.md                             |  8 +++++
 app/vmagent/README.md                 |  2 ++
 app/vmalert/README.md                 |  2 ++
 app/vmauth/README.md                  |  2 ++
 app/vmbackup/README.md                |  2 ++
 app/vmbackupmanager/README.md         |  8 +++--
 app/vmgateway/README.md               | 10 ++++---
 app/vmrestore/README.md               |  2 ++
 docs/CHANGELOG.md                     |  1 +
 docs/Cluster-VictoriaMetrics.md       |  6 ++++
 docs/README.md                        |  2 ++
 docs/Single-server-VictoriaMetrics.md |  2 ++
 docs/vmagent.md                       |  2 ++
 docs/vmalert.md                       |  2 ++
 docs/vmauth.md                        |  2 ++
 docs/vmbackup.md                      |  2 ++
 docs/vmbackupmanager.md               |  8 +++--
 docs/vmgateway.md                     | 10 ++++---
 docs/vmrestore.md                     |  2 ++
 lib/httpserver/httpserver.go          |  6 ++--
 lib/netutil/tls.go                    | 30 +++++++++++++++++--
 lib/netutil/tls_test.go               | 42 +++++++++++++++++++++++++++
 lib/promauth/config.go                | 30 ++++++-------------
 23 files changed, 143 insertions(+), 40 deletions(-)

diff --git a/README.md b/README.md
index 35f2d80f1f..72f1cdec8a 100644
--- a/README.md
+++ b/README.md
@@ -635,6 +635,8 @@ Below is the output for `/path/to/vminsert -help`:
   -datadog.maxInsertRequestSize size
      The maximum size in bytes of a single DataDog POST request to /api/v1/series
      Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 67108864)
+  -datadog.sanitizeMetricName
+     Sanitize metric names for the ingested DataDog data to comply with DataDog behaviour described at https://docs.datadoghq.com/metrics/custom_metrics/#naming-custom-metrics (default true)
   -denyQueryTracing
      Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/#query-tracing
   -disableRerouting
@@ -771,6 +773,8 @@ Below is the output for `/path/to/vminsert -help`:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -usePromCompatibleNaming
      Whether to replace characters unsupported by Prometheus with underscores in the ingested metric names and label names. For example, foo.bar{a.b='c'} is transformed into foo_bar{a_b='c'} during data ingestion if this flag is set. See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
   -version
@@ -975,6 +979,8 @@ Below is the output for `/path/to/vmselect -help`:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
   -vmalert.proxyURL string
@@ -1135,6 +1141,8 @@ Below is the output for `/path/to/vmstorage -help`:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
   -vminsertAddr string
diff --git a/app/vmagent/README.md b/app/vmagent/README.md
index 8b136e910d..51cc9e71d4 100644
--- a/app/vmagent/README.md
+++ b/app/vmagent/README.md
@@ -1269,6 +1269,8 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -usePromCompatibleNaming
      Whether to replace characters unsupported by Prometheus with underscores in the ingested metric names and label names. For example, foo.bar{a.b='c'} is transformed into foo_bar{a_b='c'} during data ingestion if this flag is set. See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
   -version
diff --git a/app/vmalert/README.md b/app/vmalert/README.md
index ba54968273..290eb97672 100644
--- a/app/vmalert/README.md
+++ b/app/vmalert/README.md
@@ -1069,6 +1069,8 @@ The shortlist of configuration flags is the following:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/app/vmauth/README.md b/app/vmauth/README.md
index 654578347d..17113ab2eb 100644
--- a/app/vmauth/README.md
+++ b/app/vmauth/README.md
@@ -308,6 +308,8 @@ See the docs at https://docs.victoriametrics.com/vmauth.html .
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/app/vmbackup/README.md b/app/vmbackup/README.md
index 6eabbe34ad..d298ec56b1 100644
--- a/app/vmbackup/README.md
+++ b/app/vmbackup/README.md
@@ -266,6 +266,8 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/app/vmbackupmanager/README.md b/app/vmbackupmanager/README.md
index 1bf2005edb..e970a14d37 100644
--- a/app/vmbackupmanager/README.md
+++ b/app/vmbackupmanager/README.md
@@ -72,14 +72,14 @@ Backup manager launched with the following configuration:
 ```console
 export NODE_IP=192.168.0.10
 export VMSTORAGE_ENDPOINT=http://127.0.0.1:8428
-./vmbackupmanager -dst=gs://vmstorage-data/$NODE_IP -credsFilePath=credentials.json -storageDataPath=/vmstorage-data -snapshot.createURL=$VMSTORAGE_ENDPOINT/snapshot/create -eula 
+./vmbackupmanager -dst=gs://vmstorage-data/$NODE_IP -credsFilePath=credentials.json -storageDataPath=/vmstorage-data -snapshot.createURL=$VMSTORAGE_ENDPOINT/snapshot/create -eula
 ```
 
 Expected logs in vmbackupmanager:
 
 ```console
 info    lib/backup/actions/backup.go:131    server-side copied 81 out of 81 parts from GCS{bucket: "vmstorage-data", dir: "192.168.0.10//latest/"} to GCS{bucket: "vmstorage-data", dir: "192.168.0.10//weekly/2020-34/"} in 2.549833008s
-info    lib/backup/actions/backup.go:169    backed up 853315 bytes in 2.882 seconds; deleted 0 bytes; server-side copied 853315 bytes; uploaded 0 bytes 
+info    lib/backup/actions/backup.go:169    backed up 853315 bytes in 2.882 seconds; deleted 0 bytes; server-side copied 853315 bytes; uploaded 0 bytes
 ```
 
 Expected logs in vmstorage:
@@ -93,7 +93,7 @@ info    VictoriaMetrics/lib/storage/storage.go:319    deleted snapshot "/vmstora
 The result on the GCS bucket
 
 * The root folder
-  
+
   ![root](vmbackupmanager_root_folder.png)
 
 * The latest folder
@@ -265,6 +265,8 @@ vmbackupmanager performs regular backups according to the provided configs.
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/app/vmgateway/README.md b/app/vmgateway/README.md
index 74fa44f0b6..c55a4a8b76 100644
--- a/app/vmgateway/README.md
+++ b/app/vmgateway/README.md
@@ -149,7 +149,7 @@ cat << EOF > limit.yaml
 limits:
   - type: queries
     value: 100
-  - type: rows_inserted 
+  - type: rows_inserted
     value: 100000
   - type: new_series
     value: 1000
@@ -168,7 +168,7 @@ curl 'http://localhost:8431/api/v1/import/prometheus' -X POST  -d 'foo{bar="baz1
 # read metric from tenant 1:5
 curl 'http://localhost:8431/api/v1/labels' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjAxNjIwMDAwMDAsInZtX2FjY2VzcyI6eyJ0ZW5hbnRfaWQiOnsiYWNjb3VudF9pZCI6MTV9fX0.PB1_KXDKPUp-40pxOGk6lt_jt9Yq80PIMpWVJqSForQ'
 
-# check rate limit 
+# check rate limit
 ```
 
 ## Configuration
@@ -199,11 +199,11 @@ The shortlist of configuration flags include the following:
   -datasource.maxIdleConnections int
      Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. (default 100)
   -datasource.oauth2.clientID string
-     Optional OAuth2 clientID to use for -datasource.url. 
+     Optional OAuth2 clientID to use for -datasource.url.
   -datasource.oauth2.clientSecret string
      Optional OAuth2 clientSecret to use for -datasource.url.
   -datasource.oauth2.clientSecretFile string
-     Optional OAuth2 clientSecretFile to use for -datasource.url. 
+     Optional OAuth2 clientSecretFile to use for -datasource.url.
   -datasource.oauth2.scopes string
      Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'
   -datasource.oauth2.tokenUrl string
@@ -315,6 +315,8 @@ The shortlist of configuration flags include the following:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
   -write.url string
diff --git a/app/vmrestore/README.md b/app/vmrestore/README.md
index 4eecdd57d3..67793a6b9f 100644
--- a/app/vmrestore/README.md
+++ b/app/vmrestore/README.md
@@ -166,6 +166,8 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 8d83ce5275..5422e5e3c9 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -25,6 +25,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
 * FEATURE: check the correctess of raw sample timestamps stored on disk when reading them. This reduces the probability of possible silent corruption of the data stored on disk. This should help [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2998) and [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3011).
 * FEATURE: atomically delete directories with snapshots, parts and partitions at [storage level](https://docs.victoriametrics.com/#storage). Previously such directories can be left in partially deleted state when the deletion operation was interrupted by unclean shutdown. This may result in `cannot open file ...: no such file or directory` error on the next start. The probability of this error was quite high when NFS or EFS was used as persistent storage for VictoriaMetrics data. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3038).
 * FEATURE: set the `start` arg to `end - 5 minutes` if isn't passed explicitly to [/api/v1/labels](https://docs.victoriametrics.com/url-examples.html#apiv1labels) and [/api/v1/label/.../values](https://docs.victoriametrics.com/url-examples.html#apiv1labelvalues). See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3052).
+* FEATURE: allow to define the minimum TLS version to use when accepting https requests to VictoriaMetrics components if `-tls` command-line flag is set. The minimum TLS version can be set via `-tlsMinVersion` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3090).
 * FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): add `vm-native-step-interval` command line flag for `vm-native` mode. New option allows splitting the import process into chunks by time interval. This helps migrating data sets with high churn rate and provides better control over the process. See [feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2733).
 * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add `top queries` tab, which shows various stats for recently executed queries. See [these docs](https://docs.victoriametrics.com/#top-queries) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2707).
 * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add `debug` mode to the alerting rule settings for printing additional information into logs during evaluation. See `debug` param in [alerting rule config](https://docs.victoriametrics.com/vmalert.html#alerting-rules).
diff --git a/docs/Cluster-VictoriaMetrics.md b/docs/Cluster-VictoriaMetrics.md
index afbbbfc376..6f20335f38 100644
--- a/docs/Cluster-VictoriaMetrics.md
+++ b/docs/Cluster-VictoriaMetrics.md
@@ -777,6 +777,8 @@ Below is the output for `/path/to/vminsert -help`:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -usePromCompatibleNaming
      Whether to replace characters unsupported by Prometheus with underscores in the ingested metric names and label names. For example, foo.bar{a.b='c'} is transformed into foo_bar{a_b='c'} during data ingestion if this flag is set. See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
   -version
@@ -981,6 +983,8 @@ Below is the output for `/path/to/vmselect -help`:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
   -vmalert.proxyURL string
@@ -1141,6 +1145,8 @@ Below is the output for `/path/to/vmstorage -help`:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
   -vminsertAddr string
diff --git a/docs/README.md b/docs/README.md
index aa8f1487fa..fb466698a4 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2342,6 +2342,8 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -usePromCompatibleNaming
      Whether to replace characters unsupported by Prometheus with underscores in the ingested metric names and label names. For example, foo.bar{a.b='c'} is transformed into foo_bar{a_b='c'} during data ingestion if this flag is set. See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
   -version
diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md
index 0445dac267..a44e1c14b4 100644
--- a/docs/Single-server-VictoriaMetrics.md
+++ b/docs/Single-server-VictoriaMetrics.md
@@ -2346,6 +2346,8 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -usePromCompatibleNaming
      Whether to replace characters unsupported by Prometheus with underscores in the ingested metric names and label names. For example, foo.bar{a.b='c'} is transformed into foo_bar{a_b='c'} during data ingestion if this flag is set. See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
   -version
diff --git a/docs/vmagent.md b/docs/vmagent.md
index 7747e55f2f..7ef86bad42 100644
--- a/docs/vmagent.md
+++ b/docs/vmagent.md
@@ -1273,6 +1273,8 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -usePromCompatibleNaming
      Whether to replace characters unsupported by Prometheus with underscores in the ingested metric names and label names. For example, foo.bar{a.b='c'} is transformed into foo_bar{a_b='c'} during data ingestion if this flag is set. See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
   -version
diff --git a/docs/vmalert.md b/docs/vmalert.md
index bac89c8935..acc823ef50 100644
--- a/docs/vmalert.md
+++ b/docs/vmalert.md
@@ -1073,6 +1073,8 @@ The shortlist of configuration flags is the following:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/docs/vmauth.md b/docs/vmauth.md
index ae0d6d8356..7996a0d766 100644
--- a/docs/vmauth.md
+++ b/docs/vmauth.md
@@ -312,6 +312,8 @@ See the docs at https://docs.victoriametrics.com/vmauth.html .
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/docs/vmbackup.md b/docs/vmbackup.md
index cb39e4e473..2b37be4914 100644
--- a/docs/vmbackup.md
+++ b/docs/vmbackup.md
@@ -270,6 +270,8 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/docs/vmbackupmanager.md b/docs/vmbackupmanager.md
index 256bef0855..66b6ff39c4 100644
--- a/docs/vmbackupmanager.md
+++ b/docs/vmbackupmanager.md
@@ -76,14 +76,14 @@ Backup manager launched with the following configuration:
 ```console
 export NODE_IP=192.168.0.10
 export VMSTORAGE_ENDPOINT=http://127.0.0.1:8428
-./vmbackupmanager -dst=gs://vmstorage-data/$NODE_IP -credsFilePath=credentials.json -storageDataPath=/vmstorage-data -snapshot.createURL=$VMSTORAGE_ENDPOINT/snapshot/create -eula 
+./vmbackupmanager -dst=gs://vmstorage-data/$NODE_IP -credsFilePath=credentials.json -storageDataPath=/vmstorage-data -snapshot.createURL=$VMSTORAGE_ENDPOINT/snapshot/create -eula
 ```
 
 Expected logs in vmbackupmanager:
 
 ```console
 info    lib/backup/actions/backup.go:131    server-side copied 81 out of 81 parts from GCS{bucket: "vmstorage-data", dir: "192.168.0.10//latest/"} to GCS{bucket: "vmstorage-data", dir: "192.168.0.10//weekly/2020-34/"} in 2.549833008s
-info    lib/backup/actions/backup.go:169    backed up 853315 bytes in 2.882 seconds; deleted 0 bytes; server-side copied 853315 bytes; uploaded 0 bytes 
+info    lib/backup/actions/backup.go:169    backed up 853315 bytes in 2.882 seconds; deleted 0 bytes; server-side copied 853315 bytes; uploaded 0 bytes
 ```
 
 Expected logs in vmstorage:
@@ -97,7 +97,7 @@ info    VictoriaMetrics/lib/storage/storage.go:319    deleted snapshot "/vmstora
 The result on the GCS bucket
 
 * The root folder
-  
+
   ![root](vmbackupmanager_root_folder.png)
 
 * The latest folder
@@ -269,6 +269,8 @@ vmbackupmanager performs regular backups according to the provided configs.
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/docs/vmgateway.md b/docs/vmgateway.md
index ea16967c02..35179bf1d0 100644
--- a/docs/vmgateway.md
+++ b/docs/vmgateway.md
@@ -153,7 +153,7 @@ cat << EOF > limit.yaml
 limits:
   - type: queries
     value: 100
-  - type: rows_inserted 
+  - type: rows_inserted
     value: 100000
   - type: new_series
     value: 1000
@@ -172,7 +172,7 @@ curl 'http://localhost:8431/api/v1/import/prometheus' -X POST  -d 'foo{bar="baz1
 # read metric from tenant 1:5
 curl 'http://localhost:8431/api/v1/labels' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjAxNjIwMDAwMDAsInZtX2FjY2VzcyI6eyJ0ZW5hbnRfaWQiOnsiYWNjb3VudF9pZCI6MTV9fX0.PB1_KXDKPUp-40pxOGk6lt_jt9Yq80PIMpWVJqSForQ'
 
-# check rate limit 
+# check rate limit
 ```
 
 ## Configuration
@@ -203,11 +203,11 @@ The shortlist of configuration flags include the following:
   -datasource.maxIdleConnections int
      Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. (default 100)
   -datasource.oauth2.clientID string
-     Optional OAuth2 clientID to use for -datasource.url. 
+     Optional OAuth2 clientID to use for -datasource.url.
   -datasource.oauth2.clientSecret string
      Optional OAuth2 clientSecret to use for -datasource.url.
   -datasource.oauth2.clientSecretFile string
-     Optional OAuth2 clientSecretFile to use for -datasource.url. 
+     Optional OAuth2 clientSecretFile to use for -datasource.url.
   -datasource.oauth2.scopes string
      Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'
   -datasource.oauth2.tokenUrl string
@@ -319,6 +319,8 @@ The shortlist of configuration flags include the following:
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
   -write.url string
diff --git a/docs/vmrestore.md b/docs/vmrestore.md
index 43816bfd26..13e04b7b07 100644
--- a/docs/vmrestore.md
+++ b/docs/vmrestore.md
@@ -170,6 +170,8 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
      Supports an array of values separated by comma or specified via multiple flags.
   -tlsKeyFile string
      Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+     Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
   -version
      Show VictoriaMetrics version
 ```
diff --git a/lib/httpserver/httpserver.go b/lib/httpserver/httpserver.go
index f3e4617669..5beeef1e2d 100644
--- a/lib/httpserver/httpserver.go
+++ b/lib/httpserver/httpserver.go
@@ -35,6 +35,8 @@ var (
 	tlsCertFile     = flag.String("tlsCertFile", "", "Path to file with TLS certificate 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 if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated")
 	tlsCipherSuites = flagutil.NewArray("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants")
+	tlsMinVersion   = flag.String("tlsMinVersion", "", "Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. "+
+		"Supported values: TLS10, TLS11, TLS12, TLS13")
 
 	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. "+
@@ -95,9 +97,9 @@ func Serve(addr string, rh RequestHandler) {
 	logger.Infof("pprof handlers are exposed at %s://%s/debug/pprof/", scheme, hostAddr)
 	var tlsConfig *tls.Config
 	if *tlsEnable {
-		tc, err := netutil.GetServerTLSConfig(*tlsCertFile, *tlsKeyFile, *tlsCipherSuites)
+		tc, err := netutil.GetServerTLSConfig(*tlsCertFile, *tlsKeyFile, *tlsMinVersion, *tlsCipherSuites)
 		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, -tlsMinVersion=%q: %s", *tlsCertFile, *tlsKeyFile, *tlsMinVersion, err)
 		}
 		tlsConfig = tc
 	}
diff --git a/lib/netutil/tls.go b/lib/netutil/tls.go
index 81f14d9456..e1a8864487 100644
--- a/lib/netutil/tls.go
+++ b/lib/netutil/tls.go
@@ -10,7 +10,7 @@ import (
 )
 
 // GetServerTLSConfig returns TLS config for the server.
-func GetServerTLSConfig(tlsCertFile, tlsKeyFile string, tlsCipherSuites []string) (*tls.Config, error) {
+func GetServerTLSConfig(tlsCertFile, tlsKeyFile, minTLSVersion string, tlsCipherSuites []string) (*tls.Config, error) {
 	var certLock sync.Mutex
 	var certDeadline uint64
 	var cert *tls.Certificate
@@ -22,10 +22,15 @@ func GetServerTLSConfig(tlsCertFile, tlsKeyFile string, tlsCipherSuites []string
 	if err != nil {
 		return nil, fmt.Errorf("cannot use TLS cipher suites from tlsCipherSuites=%q: %w", tlsCipherSuites, err)
 	}
+	minVersion, err := ParseTLSVersion(minTLSVersion)
+	if err != nil {
+		return nil, fmt.Errorf("cannnot use TLS min version from minTLSVersion=%q. Supported TLS versions (TLS10, TLS11, TLS12, TLS13): %w", minTLSVersion, err)
+	}
 	cert = &c
 	cfg := &tls.Config{
-		MinVersion:               tls.VersionTLS12,
-		PreferServerCipherSuites: true,
+		MinVersion: minVersion,
+		// Do not set MaxVersion, since this has no sense from security PoV.
+		// This can only result in lower security level if improperly set.
 		GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
 			certLock.Lock()
 			defer certLock.Unlock()
@@ -63,3 +68,22 @@ func cipherSuitesFromNames(cipherSuiteNames []string) ([]uint16, error) {
 	}
 	return cipherSuites, nil
 }
+
+// ParseTLSVersion returns tls version from the given string s.
+func ParseTLSVersion(s string) (uint16, error) {
+	switch strings.ToUpper(s) {
+	case "":
+		// Special case - use default TLS version provided by tls package.
+		return 0, nil
+	case "TLS13":
+		return tls.VersionTLS13, nil
+	case "TLS12":
+		return tls.VersionTLS12, nil
+	case "TLS11":
+		return tls.VersionTLS11, nil
+	case "TLS10":
+		return tls.VersionTLS10, nil
+	default:
+		return 0, fmt.Errorf("unsupported TLS version %q", s)
+	}
+}
diff --git a/lib/netutil/tls_test.go b/lib/netutil/tls_test.go
index 3e636a151f..2332e9b489 100644
--- a/lib/netutil/tls_test.go
+++ b/lib/netutil/tls_test.go
@@ -1,6 +1,7 @@
 package netutil
 
 import (
+	"crypto/tls"
 	"reflect"
 	"testing"
 )
@@ -76,3 +77,44 @@ func TestCipherSuitesFromNames(t *testing.T) {
 		})
 	}
 }
+
+func TestParseTLSVersionSuccess(t *testing.T) {
+	f := func(s string, want uint16) {
+		t.Helper()
+		got, err := ParseTLSVersion(s)
+		if err != nil {
+			t.Fatalf("unexpected error for ParseTLSVersion(%q): %s", s, err)
+		}
+		if got != want {
+			t.Fatalf("unexpected value got from ParseTLSVersion(%q); got %d; want %d", s, got, want)
+		}
+	}
+	// lowercase tlsName
+	f("tls10", tls.VersionTLS10)
+	f("tls11", tls.VersionTLS11)
+	f("tls12", tls.VersionTLS12)
+	f("tls13", tls.VersionTLS13)
+	// uppercase tlsName
+	f("TLS10", tls.VersionTLS10)
+	f("TLS11", tls.VersionTLS11)
+	f("TLS12", tls.VersionTLS12)
+	f("TLS13", tls.VersionTLS13)
+	// empty tlsName
+	f("", 0)
+}
+
+func TestParseTLSVersionFailure(t *testing.T) {
+	f := func(s string) {
+		t.Helper()
+		_, err := ParseTLSVersion(s)
+		if err == nil {
+			t.Fatalf("expecting non-nil error for ParseTLSVersion(%q)", s)
+		}
+	}
+	// incorrect tlsName
+	f("123")
+	// incorrect tlsName with correct prefix
+	f("TLS1")
+	// incorrect tls version in tlsName
+	f("TLS14")
+}
diff --git a/lib/promauth/config.go b/lib/promauth/config.go
index cef24202ad..3da9a66971 100644
--- a/lib/promauth/config.go
+++ b/lib/promauth/config.go
@@ -15,6 +15,7 @@ import (
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
+	"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
 	"github.com/VictoriaMetrics/fasthttp"
 	"github.com/cespare/xxhash/v2"
 	"golang.org/x/oauth2"
@@ -79,6 +80,8 @@ type TLSConfig struct {
 	ServerName         string `yaml:"server_name,omitempty"`
 	InsecureSkipVerify bool   `yaml:"insecure_skip_verify,omitempty"`
 	MinVersion         string `yaml:"min_version,omitempty"`
+	// Do not define MaxVersion field (max_version), since this has no sense from security PoV.
+	// This can only result in lower security level if improperly set.
 }
 
 // String returns human-readable representation of tc
@@ -399,6 +402,8 @@ func (ac *Config) NewTLSConfig() *tls.Config {
 	tlsCfg.ServerName = ac.TLSServerName
 	tlsCfg.InsecureSkipVerify = ac.TLSInsecureSkipVerify
 	tlsCfg.MinVersion = ac.TLSMinVersion
+	// Do not set tlsCfg.MaxVersion, since this has no sense from security PoV.
+	// This can only result in lower security level if improperly set.
 	return tlsCfg
 }
 
@@ -713,27 +718,10 @@ func (tctx *tlsContext) initFromTLSConfig(baseDir string, tc *TLSConfig) error {
 			return fmt.Errorf("cannot parse data from `ca_file` %q", tc.CAFile)
 		}
 	}
-	if tc.MinVersion != "" {
-		v, err := parseTLSVersion(tc.MinVersion)
-		if err != nil {
-			return fmt.Errorf("cannot parse `min_version`: %w", err)
-		}
-		tctx.minVersion = v
+	v, err := netutil.ParseTLSVersion(tc.MinVersion)
+	if err != nil {
+		return fmt.Errorf("cannot parse `min_version`: %w", err)
 	}
+	tctx.minVersion = v
 	return nil
 }
-
-func parseTLSVersion(s string) (uint16, error) {
-	switch strings.ToUpper(s) {
-	case "TLS13":
-		return tls.VersionTLS13, nil
-	case "TLS12":
-		return tls.VersionTLS12, nil
-	case "TLS11":
-		return tls.VersionTLS11, nil
-	case "TLS10":
-		return tls.VersionTLS10, nil
-	default:
-		return 0, fmt.Errorf("unsupported TLS version %q", s)
-	}
-}