Skip to main content
Mole securing connections

TLS and Mutual TLS

Secure your mesh with TLS encryption and mutual authentication.

TLS Basics

All Muti Metroo peer connections use TLS 1.3:

  • Encryption: AES-256-GCM or ChaCha20-Poly1305
  • Key Exchange: ECDHE with X25519 or P-256
  • Authentication: ECDSA certificates (EC-only, RSA not supported)
  • Forward Secrecy: New keys per session

Global TLS Configuration

TLS is configured once in the global tls: section and automatically used by all listeners and peer connections:

tls:
ca: "./certs/ca.crt" # CA for verifying peers and clients
cert: "./certs/agent.crt" # Agent's identity certificate
key: "./certs/agent.key" # Agent's private key
mtls: true # Enable mutual TLS on listeners

Server Authentication (TLS)

Basic TLS validates the server's certificate. With mtls: false, listeners accept any connecting peer:

tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: false # Don't require client certs

listeners:
- transport: quic
address: "0.0.0.0:4433"

peers:
- id: "abc123..."
transport: quic
address: "peer.example.com:4433"
# Uses global CA to validate server, global cert as client cert

What This Provides

  • Server identity verified
  • Client can trust it's connecting to the right agent
  • Traffic encrypted
  • Peers still present certificates (using global cert)

What This Does NOT Provide

  • No mandatory validation of client identity on listeners
  • Any client can connect (if they can reach the port)

Mutual TLS (mTLS)

mTLS requires both sides to present valid certificates. Enable it globally:

tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true # Require client certs on listeners

With mTLS enabled:

  • Listeners require connecting peers to present valid certificates
  • The global CA is used to verify client certificates
  • Peers automatically use the global agent certificate as their client certificate

What mTLS Provides

  • Mutual authentication (both sides verified)
  • Only authorized peers can connect
  • Strong defense against unauthorized access
  • Certificate-based access control

EC-Only Certificates

Important: Muti Metroo only accepts EC (Elliptic Curve) certificates. RSA certificates are rejected.

# Generate EC certificates using the CLI
muti-metroo cert ca -n "My Mesh CA" -o ./certs
muti-metroo cert agent -n "agent-1" \
--ca ./certs/ca.crt \
--ca-key ./certs/ca.key \
-o ./certs

The only exception is WebSocket connections through a proxy - external servers may use any certificate type since mTLS is not available through proxies.

Certificate Types

CA Certificate

Signs all other certificates. Never share the private key:

muti-metroo cert ca -n "My Mesh CA" -o ./certs

# Files created:
# ./certs/ca.crt - Share with all agents
# ./certs/ca.key - KEEP SECRET!

Agent Certificate

Used for both server and client authentication:

muti-metroo cert agent -n "agent-1" \
--ca ./certs/ca.crt \
--ca-key ./certs/ca.key \
--dns "agent1.example.com" \
--ip "192.168.1.10" \
-o ./certs

Features:

  • Extended Key Usage: Server Authentication, Client Authentication
  • Used by listeners for server TLS
  • Used by peers as client certificate for mTLS

Configuration Examples

Development (mTLS Disabled)

tls:
ca: "./dev-certs/ca.crt"
cert: "./dev-certs/agent.crt"
key: "./dev-certs/agent.key"
mtls: false # Disable for easier development

listeners:
- transport: quic
address: "0.0.0.0:4433"

Production (Full mTLS)

tls:
ca: "/etc/muti-metroo/certs/ca.crt"
cert: "/etc/muti-metroo/certs/agent.crt"
key: "/etc/muti-metroo/certs/agent.key"
mtls: true

listeners:
- transport: quic
address: "0.0.0.0:4433"

peers:
- id: "abc123..."
transport: quic
address: "peer.example.com:4433"

Per-Listener Override

Disable mTLS for a specific listener:

tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true # Global default

listeners:
# Uses global mTLS setting
- transport: quic
address: "0.0.0.0:4433"

# Override: disable mTLS for this listener
- transport: h2
address: "0.0.0.0:8443"
tls:
mtls: false

Kubernetes (Inline Certs)

tls:
ca_pem: "${CA_CRT}"
cert_pem: "${TLS_CRT}"
key_pem: "${TLS_KEY}"
mtls: true

listeners:
- transport: quic
address: "0.0.0.0:4433"

Certificate Validation

What's Validated

  1. Certificate signature (signed by trusted CA)
  2. Validity period (not expired, not future)
  3. Subject Alternative Names (hostname/IP matches)
  4. Key usage (appropriate for server/client)
  5. Key type (must be ECDSA)

Peer ID Validation

In addition to TLS, Muti Metroo validates the peer's Agent ID:

peers:
- id: "abc123def456..." # Expected Agent ID

This provides defense-in-depth: even if an attacker has a valid certificate, they must also have the correct Agent ID.

Troubleshooting

Certificate Not Trusted

Error: x509: certificate signed by unknown authority
  • Verify CA certificate is correct
  • Check CA was used to sign the certificate:
    openssl verify -CAfile ca.crt agent.crt

Certificate Expired

Error: x509: certificate has expired
  • Check expiration:
    openssl x509 -enddate -noout -in agent.crt
  • Generate new certificate

Name Mismatch

Error: x509: certificate is valid for agent1.example.com, not agent2.example.com
  • Use correct hostname in peer address
  • Generate certificate with correct SANs

RSA Certificate Rejected

Error: certificate must use ECDSA, got RSA
  • Muti Metroo only accepts EC certificates
  • Regenerate using ECDSA:
    muti-metroo cert agent -n "agent-1" \
    --ca ./certs/ca.crt \
    --ca-key ./certs/ca.key \
    -o ./certs

Client Certificate Required

Error: tls: client didn't provide a certificate
  • The listener has mTLS enabled
  • Connecting peer must have a valid certificate configured
  • Check global tls.cert and tls.key are set

Best Practices

  1. Always use mTLS in production
  2. Use EC certificates only (RSA is not supported)
  3. Protect CA private key (HSM, vault, or encrypted storage)
  4. Use short certificate validity (90-365 days)
  5. Automate certificate rotation
  6. Include all necessary SANs when generating certs
  7. Monitor certificate expiration
  8. Revoke compromised certificates immediately

Next Steps