Ignore cacert for internal requests if not configured (#8099)

* ignore cert verification if not configured

* also ignore hostnames

* script for manually testing tls clsuter
This commit is contained in:
Andrey Vasnetsov
2026-02-12 10:59:38 +01:00
committed by timvisee
parent 971c6a3a8a
commit 7e1a8325dc
5 changed files with 201 additions and 0 deletions

View File

@@ -87,6 +87,14 @@ fn https_client(
);
}
}
} else if !verify_https_client_certificate {
// If ca_cert is not provided, and we are not verifying client certificate,
// there is no way to verify https connection.
//
// So we have to disable certificate verification in order to be able to connect to the server.
builder = builder
.danger_accept_invalid_certs(true)
.danger_accept_invalid_hostnames(true);
}
if verify_https_client_certificate {

View File

@@ -0,0 +1,23 @@
[req]
default_bits = 2048
encrypt_key = no
default_md = sha256
prompt = no
utf8 = yes
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
C = US
ST = State
L = City
O = Org
CN = qdrant
[v3_req]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Run once to generate TLS certificates for the local cluster.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CERT_DIR="$SCRIPT_DIR/cert"
CERT_CFG="$SCRIPT_DIR/cert.cfg"
mkdir -p "$CERT_DIR"
# CA
openssl req \
-new -newkey rsa:2048 -days 3650 -nodes -x509 \
-subj "/C=US/ST=State/L=City/O=Qdrant" \
-addext "keyUsage = critical, keyCertSign, cRLSign" \
-addext "basicConstraints = critical, CA:TRUE" \
-keyout "$CERT_DIR/cakey.pem" \
-out "$CERT_DIR/cacert.pem"
# Server key + CSR + signed cert
openssl genrsa -out "$CERT_DIR/key.pem" 2048
chmod 644 "$CERT_DIR/key.pem"
openssl req \
-new -key "$CERT_DIR/key.pem" \
-out "$CERT_DIR/cert.csr" \
-config "$CERT_CFG"
openssl x509 \
-req -days 3650 \
-in "$CERT_DIR/cert.csr" \
-CA "$CERT_DIR/cacert.pem" \
-CAkey "$CERT_DIR/cakey.pem" \
-CAcreateserial \
-extensions v3_req \
-extfile "$CERT_CFG" \
-out "$CERT_DIR/cert.pem"
echo "Certificates generated in $CERT_DIR"

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env bash
# Launches a 3-node Qdrant cluster with TLS on localhost.
# Run gen_certs.sh first (once) to create certificates.
#
# Node 1 (leader): HTTP 6333, gRPC 6334, P2P 6335
# Node 2: HTTP 6343, gRPC 6344, P2P 6345
# Node 3: HTTP 6353, gRPC 6354, P2P 6355
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
CERT_DIR="$SCRIPT_DIR/cert"
CONFIG_FILE="$SCRIPT_DIR/tls_config.yaml"
WORK_DIR="$SCRIPT_DIR/work"
BINARY="$PROJECT_ROOT/target/debug/qdrant"
if [[ ! -f "$CERT_DIR/cert.pem" ]]; then
echo "Certificates not found. Run gen_certs.sh first." >&2
exit 1
fi
PIDS=()
cleanup() {
echo ""
echo "Stopping all nodes..."
for pid in "${PIDS[@]}"; do
kill "$pid" 2>/dev/null || true
done
wait
echo "All nodes stopped."
}
trap cleanup EXIT INT TERM
# Build
echo "Building qdrant..."
cargo build --no-default-features --bin qdrant --manifest-path "$PROJECT_ROOT/Cargo.toml"
# Prepare per-node dirs with tls symlink
for i in 1 2 3; do
mkdir -p "$WORK_DIR/node$i/storage"
ln -sfn "$CERT_DIR" "$WORK_DIR/node$i/tls"
done
launch() {
local name=$1 http=$2 grpc=$3 p2p=$4; shift 4
echo "Starting $name (HTTP=$http gRPC=$grpc P2P=$p2p)..."
cd "$WORK_DIR/$name"
QDRANT__LOG_LEVEL="debug,raft=info,hyper=info,wal=info,h2=info,tower=info,rustls=info" \
QDRANT__SERVICE__HTTP_PORT="$http" \
QDRANT__SERVICE__GRPC_PORT="$grpc" \
QDRANT__SERVICE__STATIC_CONTENT_DIR="$PROJECT_ROOT/static" \
QDRANT__CLUSTER__P2P__PORT="$p2p" \
QDRANT__STORAGE__STORAGE_PATH="$WORK_DIR/$name/storage" \
QDRANT__STORAGE__HNSW_INDEX__MAX_INDEXING_THREADS=1 \
QDRANT_NUM_CPUS=1 \
"$BINARY" --config-path "$CONFIG_FILE" --disable-telemetry "$@" \
> "$WORK_DIR/$name/$name.log" 2>&1 &
PIDS+=($!)
}
wait_ready() {
local name=$1 port=$2
for _ in $(seq 1 30); do
if curl -sf --cacert "$CERT_DIR/cacert.pem" "https://localhost:$port/readyz" >/dev/null 2>&1; then
echo "$name is ready."
return
fi
sleep 1
done
echo "WARNING: $name did not become ready within 30s"
}
launch node1 6333 6334 6335 --uri "https://localhost:6335"
wait_ready node1 6333
launch node2 6343 6344 6345 --bootstrap "https://localhost:6335" --uri "https://localhost:6345"
launch node3 6353 6354 6355 --bootstrap "https://localhost:6335" --uri "https://localhost:6355"
wait_ready node2 6343
wait_ready node3 6353
echo ""
echo "=== 3-node TLS cluster is running ==="
echo " Node 1: https://localhost:6333"
echo " Node 2: https://localhost:6343"
echo " Node 3: https://localhost:6353"
echo ""
echo " curl --cacert $CERT_DIR/cacert.pem https://localhost:6333/cluster"
echo ""
echo "Press Ctrl+C to stop."
wait

View File

@@ -0,0 +1,32 @@
log_level: INFO
service:
# Use TLS for client communication
enable_tls: true
# Check user HTTPS client certificate against CA file specified in tls config
verify_https_client_certificate: false
cluster:
# Use `enabled: true` to run Qdrant in distributed deployment mode
enabled: true
# Configuration of the inter-cluster communication
p2p:
# Use mTLS for internal communication between peers
enable_tls: false
# Set to true to prevent service from sending usage statistics to the developers.
# Read more: https://qdrant.tech/documentation/guides/telemetry
telemetry_disabled: true
# TLS settings - paths are set via environment variables in the launch script
tls:
# Certificate chain file
cert: ./tls/cert.pem
# Private key file
key: ./tls/key.pem
# CA certificate
ca_cert: ./tls/cacert.pem