← Knowledge base

OpenVPN

Is PQC enabled? — quick check

WireGuard + Rosenpass

# 1) No-dependency check — identify this machine first.
uname -a 2>/dev/null || true

# 2) Dependency check — prompt before installing anything.
if ! command -v wg >/dev/null 2>&1; then
  echo 'WireGuard tools was not found.'
  printf 'Install or enable WireGuard tools now? [y/N] '
  read answer
  case "$answer" in
    [Yy]*) echo 'Install wireguard-tools through your OS package manager, then rerun this snippet.' ;;
    *) echo 'Skipping WireGuard tools-based check.'; exit 1 ;;
  esac
fi

wg show wg0 preshared-keys
sudo journalctl -u rosenpass -n 20 --no-pager 2>/dev/null | tail -5

Expected when PQC is ON

peer:  AbCd...   psk:  XyZ...
rosenpass[1234]: handshake completed peer=...

What you'll see when PQC is OFF

peer:  AbCd...   psk:  (none)
# no rosenpass logs — tunnel is classical Curve25519 only

OpenVPN

# 1) No-dependency check — identify this machine first.
uname -a 2>/dev/null || true

# 2) Dependency check — prompt before installing anything.
if ! command -v openvpn >/dev/null 2>&1; then
  echo 'OpenVPN was not found.'
  printf 'Install or enable OpenVPN now? [y/N] '
  read answer
  case "$answer" in
    [Yy]*) echo 'Install OpenVPN 2.6+ linked against OpenSSL 3.5+, then rerun this snippet.' ;;
    *) echo 'Skipping OpenVPN-based check.'; exit 1 ;;
  esac
fi

    openvpn --version | head -2
openvpn --show-groups 2>&1 | grep -i mlkem

Expected when PQC is ON

OpenVPN 2.6.12 ... [SSL (OpenSSL)]
mlkem768

What you'll see when PQC is OFF

OpenVPN 2.5.9 ... [SSL (OpenSSL)]
# (empty) — OpenSSL ≤ 3.4 or build without ML-KEM

OpenVPN's control channel is a real TLS 1.3 handshake — so anything OpenSSL can negotiate, OpenVPN can negotiate. The data channel is a separate AEAD (AES-GCM / ChaCha20-Poly1305) keyed from the TLS exporter, so PQC at the control channel rolls cleanly into the data channel.

Server-side config

tls-version-min 1.3
tls-groups X25519MLKEM768:X25519:secp256r1
tls-cipher TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
data-ciphers AES-256-GCM:CHACHA20-POLY1305

Client-side

tls-version-min 1.3
tls-groups X25519MLKEM768:X25519:secp256r1

Verify

if ! command -v openvpn >/dev/null 2>&1; then
  echo 'OpenVPN was not found.'
  printf 'Install OpenVPN now? [y/N] '; read answer
  case "$answer" in [Yy]*) sudo apt-get update && sudo apt-get install -y openvpn ;; *) exit 1 ;; esac
fi
openvpn --version | head -2
# OpenVPN 2.6.x ... [SSL (OpenSSL)] ...
openvpn --show-groups | grep -i mlkem

Requires OpenVPN 2.6+ linked against OpenSSL 3.5+, or 3.x + oqsprovider configured in openssl.cnf.

tls-crypt-v2 + PQC

tls-crypt-v2 wraps the control channel in a static AES key. That layer is symmetric and already PQ-safe. Using it together with tls-groups X25519MLKEM768 gives you confidentiality even against a future quantum adversary that records the handshake today.

Run the check on services behind the tunnel →