TLS


https://docs.victoriametrics.com/victoriametrics/
https://docs.victoriametrics.com/victoriametrics/data-ingestion/
https://docs.victoriametrics.com/victoriametrics/vmauth/
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write

1. Important Points#

VictoriaMetrics TLS paths:
    inbound:
        HTTPS at -httpListenAddr with -tls

    ingestion:
        Prometheus / vmagent remote_write to HTTPS endpoint

    query:
        Grafana / app clients query HTTPS API

recommended:
    expose VictoriaMetrics through private network or vmauth
    enable HTTPS when crossing network boundary
    use mTLS only when client certificate lifecycle is mature

2. Server TLS#

single-node#

victoria-metrics \
  -httpListenAddr=:8428 \
  -tls \
  -tlsCertFile=/etc/victoriametrics/tls/server.crt \
  -tlsKeyFile=/etc/victoriametrics/tls/server.key \
  -tlsMinVersion=TLS12

mTLS#

victoria-metrics \
  -httpListenAddr=:8428 \
  -tls \
  -tlsCertFile=/etc/victoriametrics/tls/server.crt \
  -tlsKeyFile=/etc/victoriametrics/tls/server.key \
  -mtls \
  -mtlsCAFile=/etc/victoriametrics/tls/client-ca.crt
note:
    mTLS flags may depend on VictoriaMetrics edition/component
    verify against the exact component flags before production rollout

3. Client Configuration#

Prometheus remote_write#

remote_write:
  - url: https://victoriametrics.example.com/api/v1/write
    tls_config:
      ca_file: /etc/prometheus/ca/company-ca.pem
      server_name: victoriametrics.example.com
      min_version: TLS12

vmagent#

vmagent \
  -promscrape.config=/etc/vmagent/prometheus.yml \
  -remoteWrite.url=https://victoriametrics.example.com/api/v1/write \
  -remoteWrite.tlsCAFile=/etc/vmagent/ca/company-ca.pem

verify query API#

curl --cacert /etc/ssl/company-ca.pem \
  'https://victoriametrics.example.com/api/v1/query?query=up'

4. Java#

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class VictoriaMetricsTlsExample {
  public static void main(String[] args) throws Exception {
    // Import company CA into JVM truststore, or use javax.net.ssl.trustStore.
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://victoriametrics.example.com/api/v1/query?query=up"))
        .GET()
        .build();

    HttpResponse<String> response = HttpClient.newHttpClient()
        .send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.body());
  }
}

5. Python#

pip install requests
import requests

resp = requests.get(
    "https://victoriametrics.example.com/api/v1/query",
    params={"query": "up"},
    verify="/etc/ssl/company-ca.pem",
    timeout=5,
)
resp.raise_for_status()
print(resp.json())

6. Go#

package main

import (
	"crypto/tls"
	"crypto/x509"
	"io"
	"net/http"
	"os"
)

func main() {
	ca, _ := os.ReadFile("/etc/ssl/company-ca.pem")
	pool := x509.NewCertPool()
	pool.AppendCertsFromPEM(ca)

	client := &http.Client{Transport: &http.Transport{
		TLSClientConfig: &tls.Config{RootCAs: pool, MinVersion: tls.VersionTLS12},
	}}

	resp, err := client.Get("https://victoriametrics.example.com/api/v1/query?query=up")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	println(string(body))
}

7. Node.js#

import fs from "node:fs";
import https from "node:https";

const options = {
  hostname: "victoriametrics.example.com",
  path: "/api/v1/query?query=up",
  method: "GET",
  ca: fs.readFileSync("/etc/ssl/company-ca.pem"),
  minVersion: "TLSv1.2",
  rejectUnauthorized: true
};

const req = https.request(options, (res) => {
  let body = "";
  res.on("data", (chunk) => {
    body += chunk;
  });
  res.on("end", () => {
    console.log(JSON.parse(body));
  });
});

req.on("error", (err) => {
  throw err;
});
req.end();

8. Production Checklist#

server:
    -tls enabled when endpoint crosses trust boundary
    cert/key files mounted read-only
    vmauth considered for public or multi-tenant access
    HSTS header considered at edge/proxy

client:
    remote_write uses https
    tls_config.ca_file configured
    insecure_skip_verify=false
    server_name matches certificate

operations:
    cert expiry monitored
    cert rotation tested
    remote_write failures alerted