Complete guide to certificate generation, caching, and management for HTTPS interception.
The Rust Forward Proxy includes a sophisticated certificate management system that enables:
- 🔧 Automatic Certificate Generation - Dynamic domain certificates for any HTTPS site
- ⚡ High-Performance Caching - Memory & Redis backends for 25-30x speed improvement
- 🏢 Multiple CA Support - rootCA and Securly CA certificate modes
- 🛡️ Production Security - CA signing, validation, and secure storage
# Generate root CA certificate for browser installation
make setup-ca
# Start proxy with certificate generation
make dev
# Configure browser proxy: 127.0.0.1:8080
# Install ca-certs/rootCA.crt in browser
# Browse to https://httpbin.org/get
# HTTPS content now visible in proxy logs!# Place Securly certificates in ca-certs/
# securly_ca.crt and securly_ca.key (if available)
# Start with Securly CA
CERT=securly make dev
# or
make dev-securlyPerfect for development and testing.
make devWhat it uses:
- ✅
ca-certs/rootCA.crt- Root CA certificate (install in browser) - ✅
ca-certs/rootCA.key- Root CA private key (for signing domain certs)
Generated automatically if missing:
- Organization: "Rust Forward Proxy"
- Common Name: "Rust Proxy Root CA"
- Validity: 365 days
For enterprise environments with Securly infrastructure.
CERT=securly make devWhat it uses:
- ✅
ca-certs/securly_ca.crt- Securly CA certificate ⚠️ ca-certs/securly_ca.key- Securly private key (usually not available)
Fallback behavior:
- Without private key: Falls back to self-signed certificates
- Browser warnings expected (install securly_ca.crt to minimize)
Use your own certificate authority.
TLS_CA_CERT_PATH=/path/to/ca.crt TLS_CA_KEY_PATH=/path/to/ca.key make devHTTPS Request for domain.com
↓
[Check Certificate Cache]
↓
Cache Miss → [Generate New Certificate]
↓
[Load CA Certificate & Key]
↓
[Create Domain Certificate]
• Subject: CN=domain.com
• Issuer: Root CA
• Extensions: DNS:domain.com
• Validity: 24 hours
↓
[Sign with CA Private Key]
↓
[Cache Certificate (24h TTL)]
↓
[Return for TLS Handshake]
// Uses OpenSSL command-line for reliable CA signing
generate_domain_cert_with_ca(
domain: "example.com",
ca_cert_path: "ca-certs/rootCA.crt",
ca_key_path: "ca-certs/rootCA.key"
) -> Result<CertificateData>Features:
- ✅ Trusted by browsers (when CA is installed)
- ✅ Standard X.509 extensions (SAN, key usage, etc.)
- ✅ Proper certificate chain validation
- ✅ Production-ready certificate format
// Uses rcgen for fast self-signed certificate generation
generate_self_signed_cert(
organization: "Rust Forward Proxy",
common_name: "example.com",
validity_days: 1
) -> Result<CertificateData>When used:
⚠️ CA private key not available⚠️ CA signing fails⚠️ Emergency fallback mode
Without Caching:
First request: Generate certificate (5-10ms)
Second request: Generate certificate (5-10ms)
Third request: Generate certificate (5-10ms)
Average latency: 25-30ms per HTTPS request
With Caching:
First request: Generate + cache (5-10ms)
Second request: Retrieve from cache (<1ms)
Third request: Retrieve from cache (<1ms)
Average latency: <1ms per HTTPS request
Performance Improvement: 25-30x faster!
┌─────────────────────────────────────────────────────┐
│ Certificate Manager │
├─────────────────────────────────────────────────────┤
│ • Automatic backend selection (Memory/Redis) │
│ • 24-hour TTL with automatic expiration │
│ • Graceful fallbacks and error handling │
│ • LRU eviction and size management │
└─────────────────┬───────────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
┌───▼────┐ ┌────▼─────┐
│ Memory │ │ Redis │
│ Cache │ │ Cache │
├────────┤ ├──────────┤
│Local │ │Docker │
│Dev │ │Prod │
│Fast │ │Shared │
│1000 │ │Unlimited │
│certs │ │certs │
└────────┘ └──────────┘
pub struct MemoryCache {
certificates: Arc<Mutex<HashMap<String, CachedCertificate>>>,
max_size: usize, // Default: 1000 certificates
}Features:
- ✅ Lightning fast - Sub-millisecond lookups
- ✅ No dependencies - Works without Redis
- ✅ LRU eviction - Automatic cleanup of old certificates
- ✅ Thread safe - Concurrent access with Arc
Perfect for:
- Local development
- Single-instance deployments
- Testing environments
pub struct RedisCache {
client: redis::Client,
key_prefix: String, // Default: "proxy:cert:"
ttl: Duration, // Default: 24 hours
}Features:
- ✅ Unlimited capacity - Limited only by Redis memory
- ✅ Shared across instances - Multiple proxy instances
- ✅ Persistent - Survives proxy restarts
- ✅ Automatic expiration - Redis TTL handling
Perfect for:
- Production deployments
- Docker environments
- Load-balanced setups
🔍 CONNECT httpbin.org:443 - INTERCEPTING
💾 Generating new certificate for httpbin.org (8ms)
📜 Root CA found - generating trusted certificate
✅ Trusted certificate generated for httpbin.org
🔄 Cached certificate for httpbin.org (expires in 24h)
🔒 Connection upgraded, starting TLS handshake
✅ TLS handshake successful
🔍 CONNECT httpbin.org:443 - INTERCEPTING
🎯 Using cached certificate for httpbin.org (0ms)
🔒 Connection upgraded, starting TLS handshake
✅ TLS handshake successful
🔐 Certificate cache initialized: Memory cache: 0/1000 entries
🎯 Certificate cache hit rate: 85.7% (12/14 requests)
📊 Average certificate lookup time: 0.8ms
💾 Active certificates: 8 domains cached
# Generate self-signed certificate
cargo run --bin rust-forward-proxy-cli cert generate \
--organization "My Company" \
--common-name "proxy.local" \
--cert-path "certs/proxy.crt" \
--key-path "certs/proxy.key" \
--validity-days 365
# Generate with specific settings
cargo run --bin rust-forward-proxy-cli cert generate \
--organization "Development" \
--common-name "dev.proxy" \
--cert-path "dev.crt" \
--key-path "dev.key" \
--force # Overwrite existing files# Validate certificate files
cargo run --bin rust-forward-proxy-cli cert validate \
--cert-path "certs/proxy.crt" \
--key-path "certs/proxy.key"
# Validate with detailed output
cargo run --bin rust-forward-proxy-cli cert validate \
--cert-path "ca-certs/rootCA.crt" \
--verbose# Inspect certificate details
cargo run --bin rust-forward-proxy-cli cert inspect \
--cert-path "ca-certs/rootCA.crt"
# Output example:
# 📜 Certificate Details:
# Subject: CN=Rust Proxy Root CA, O=Rust Forward Proxy
# Issuer: CN=Rust Proxy Root CA, O=Rust Forward Proxy
# Valid From: 2023-10-01 12:00:00 UTC
# Valid Until: 2024-10-01 12:00:00 UTC
# Serial: 1234567890
# Key Usage: Certificate Sign, CRL Sign# Certificate Paths
TLS_CA_CERT_PATH=ca-certs/rootCA.crt # CA certificate for signing
TLS_CA_KEY_PATH=ca-certs/rootCA.key # CA private key for signing
# Certificate Generation
TLS_AUTO_GENERATE_CERT=true # Auto-generate if missing
TLS_CERT_ORGANIZATION="Rust Forward Proxy" # Organization name
TLS_CERT_COMMON_NAME="proxy.local" # Common name for proxy cert
TLS_CERT_VALIDITY_DAYS=365 # Certificate validity period
# Certificate Caching
CERTIFICATE_TTL_HOURS=24 # Cache TTL (default: 24h)
MAX_CACHED_CERTIFICATES=1000 # Memory cache limit
CACHE_KEY_PREFIX="proxy:cert:" # Redis key prefix
# Redis Configuration
REDIS_URL=redis://redis:6379 # Redis connection URL# Certificate setup
make setup-ca # Generate root CA for browser
make help-browser # Browser setup instructions
# Certificate modes
make dev # Default (rootCA)
make dev-securly # Securly CA mode
CERT=securly make dev # Securly via environment
# Cache management
make cache-clear-redis # Clear Redis certificate cache
make help-cache # Certificate caching infomake setup-caCreates:
ca-certs/rootCA.crt- Install this in your browserca-certs/rootCA.key- Keep secure, used for signing
Chrome/Edge (macOS):
open ca-certs/rootCA.crt- Add to Keychain
- Set to "Always Trust"
Chrome/Edge (Windows/Linux):
- Settings → Security → Manage certificates
- Import to "Trusted Root Certification Authorities"
Firefox:
- Settings → Certificates → View Certificates
- Authorities → Import
- Check "Trust this CA to identify websites"
- HTTP Proxy:
127.0.0.1:8080 - HTTPS Proxy:
127.0.0.1:8080 - Use proxy for all protocols: ✅
Browse to https://httpbin.org/get and check proxy logs for complete content visibility!
🔍 CONNECT httpbin.org:443 - INTERCEPTING
💾 Generating new certificate for httpbin.org
🔒 TLS handshake failed: certificate not trusted
❌ Browser shows security warning
🔍 CONNECT httpbin.org:443 - INTERCEPTING
🎯 Using cached certificate for httpbin.org (0ms)
🔒 TLS handshake successful
📥 INTERCEPTED HTTPS: GET https://httpbin.org/get
📋 Complete request/response content visible!
- Private Key Storage - CA keys stored securely in PEM format
- Certificate Validation - Automatic validation before use
- TTL Management - Short certificate lifetimes (24h default)
- Secure Generation - Cryptographically secure random key generation
# Secure CA key permissions
chmod 600 ca-certs/rootCA.key
# Backup CA certificates
cp ca-certs/rootCA.* /secure/backup/location/
# Monitor certificate usage
grep "Generating new certificate" logs/proxy.log- 🔒 Separate CA keys for different environments
- 📅 Regular CA rotation (annually recommended)
- 🔍 Certificate monitoring and alerting
- 🛡️ Access control for CA private keys
# Verify CA files exist
ls -la ca-certs/
# Generate if missing
make setup-ca# Install OpenSSL
# macOS: brew install openssl
# Ubuntu: sudo apt-get install openssl
# Verify installation
openssl version# Fix file permissions
chmod 600 ca-certs/rootCA.key
# Verify ownership
ls -la ca-certs/rootCA.key# Check Redis connection
make test-redis
# Check cache configuration
RUST_LOG=debug make dev
# Look for cache hit/miss logs
# Clear and restart
make cache-clear-redis# Start Redis (Docker)
make dev-docker
# Test Redis connectivity
redis-cli ping
# Check Redis URL
echo $REDIS_URL- Verify certificate installation - Check browser certificate store
- Restart browser completely after certificate installation
- Clear browser cache and cookies
- Try incognito/private mode to test
- Certificate pinning - Some sites reject all non-original certificates
- HSTS (HTTP Strict Transport Security) - May prevent proxy usage
- Expected behavior - Not all sites will work with interception
# Validate certificate files
cargo run --bin rust-forward-proxy-cli cert validate \
--cert-path ca-certs/rootCA.crt \
--key-path ca-certs/rootCA.key
# Check certificate details
openssl x509 -in ca-certs/rootCA.crt -text -noout
# Verify private key
openssl rsa -in ca-certs/rootCA.key -check -noout# Monitor cache performance
grep -E "(cached certificate|Generating new)" logs/proxy.log
# Cache hit rate calculation
echo "Cache hits: $(grep 'Using cached certificate' logs/proxy.log | wc -l)"
echo "Cache misses: $(grep 'Generating new certificate' logs/proxy.log | wc -l)"Performance Benchmarks:
- CA-signed certificate: 5-10ms
- Self-signed certificate: 2-5ms
- Certificate cache lookup: <1ms
- Redis cache lookup: 1-2ms
- Memory cache lookup: <0.1ms
# Development CA
TLS_CA_CERT_PATH=ca-certs/dev-ca.crt TLS_CA_KEY_PATH=ca-certs/dev-ca.key make dev
# Production CA
TLS_CA_CERT_PATH=ca-certs/prod-ca.crt TLS_CA_KEY_PATH=ca-certs/prod-ca.key make prod
# Testing CA
TLS_CA_CERT_PATH=ca-certs/test-ca.crt TLS_CA_KEY_PATH=ca-certs/test-ca.key make test// Programmatic certificate management
let cert_manager = CertificateManager::new();
// Generate certificate for specific domain
let cert = cert_manager.generate_certificate("api.example.com").await?;
// Cache with custom TTL
cert_manager.cache_certificate_with_ttl("api.example.com", cert, 48 * 3600).await?;
// Clear specific certificate
cert_manager.remove_certificate("api.example.com").await?;
// Get cache statistics
let stats = cert_manager.cache_stats().await?;
println!("Cache hit rate: {:.1}%", stats.hit_rate * 100.0);The certificate management system provides:
- Dynamic certificate generation for any domain
- CA-signed certificates for browser trust
- Automatic caching for high performance
- Multiple CA support for different environments
- 25-30x faster certificate retrieval with caching
- Memory & Redis backend options
- Automatic TTL management and cleanup
- Shared caching across multiple instances
- One-command setup with
make setup-ca - Browser integration guides and automation
- CLI tools for certificate management
- Comprehensive monitoring and troubleshooting
Ready to intercept HTTPS traffic? Follow our Setup Guide to get started in minutes!