SSL/TLS Configuration
BWS provides robust, production-ready SSL/TLS support with automatic certificate management, comprehensive error handling, and thread-safe operations. Each site can have its own HTTPS configuration, enabling mixed HTTP/HTTPS deployments with different certificates per domain.
Overview
BWS supports two types of SSL/TLS configuration:
- Automatic SSL Certificates - Using ACME (Let's Encrypt) with automatic renewal monitoring
- Manual SSL Certificates - Using your own SSL certificate files
Production-Ready Features
- Automatic Certificate Renewal: Background monitoring service checks and renews certificates
- Thread-Safe Operations: All SSL operations are safe for concurrent access
- Comprehensive Error Handling: Graceful error propagation with detailed logging
- Zero-Downtime Renewal: Certificates renewed without service interruption
- Robust Monitoring: Certificate expiration tracking and proactive renewal
Automatic SSL Certificates (ACME)
Basic ACME Configuration
[[sites]]
name = "auto_ssl_site"
hostname = "example.com"
port = 443
static_dir = "static"
[sites.ssl]
enabled = true
auto_cert = true
domains = ["example.com", "www.example.com"]
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false
challenge_dir = "./acme-challenges"
ACME Configuration Options
Field | Type | Description | Default |
---|---|---|---|
enabled | Boolean | Enable ACME certificate generation | false |
email | String | Email address for ACME registration | Required |
staging | Boolean | Use Let's Encrypt staging environment | false |
challenge_dir | String | Directory for ACME HTTP-01 challenges | "./acme-challenges" |
ACME Challenge Handling
BWS automatically handles ACME HTTP-01 challenges with robust error handling:
- Challenge Directory: Configure
challenge_dir
where ACME challenges will be served - Automatic Routing: BWS automatically serves files from
/.well-known/acme-challenge/
- Directory Creation: The challenge directory is created automatically if it doesn't exist
- Error Handling: Comprehensive error reporting for challenge failures
# Create challenge directory
mkdir -p ./acme-challenges
# BWS will automatically serve challenges from:
# http://yourdomain.com/.well-known/acme-challenge/TOKEN
Automatic Certificate Renewal
BWS includes a production-ready certificate monitoring system:
#![allow(unused)] fn main() { // Background service automatically monitors certificates // - Checks certificate expiration every hour // - Renews certificates when needed (before 30 days expiration) // - Handles renewal failures gracefully with logging // - Thread-safe operations prevent race conditions }
Renewal Features:
- Automatic Monitoring: Background service checks certificates hourly
- Proactive Renewal: Renews certificates 30 days before expiration
- Error Recovery: Comprehensive error handling with detailed logging
- Zero Downtime: Renewals happen without service interruption
- Thread Safety: All operations are safe for concurrent access
Production vs Staging
Staging Environment (staging = true
):
- Use for testing and development
- Higher rate limits
- Certificates are not trusted by browsers
- Recommended for initial setup
Production Environment (staging = false
):
- Use for live websites
- Lower rate limits (5 certificates per domain per week)
- Certificates are trusted by browsers
- Use only after testing with staging
# Testing configuration
[sites.ssl.acme]
enabled = true
email = "test@example.com"
staging = true # Use staging environment
challenge_dir = "./acme-challenges"
# Production configuration
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false # Use production environment
challenge_dir = "./acme-challenges"
Manual SSL Certificates
Basic Manual SSL Configuration
[[sites]]
name = "manual_ssl_site"
hostname = "secure.example.com"
port = 443
static_dir = "static"
[sites.ssl]
enabled = true
auto_cert = false
cert_file = "/etc/ssl/certs/secure.example.com.crt"
key_file = "/etc/ssl/private/secure.example.com.key"
Certificate File Requirements
Certificate File (cert_file
):
- Must contain the SSL certificate in PEM format
- Can include intermediate certificates (certificate chain)
- File must be readable by the BWS process
Private Key File (key_file
):
- Must contain the private key in PEM format
- Should be protected with appropriate file permissions (600)
- Must correspond to the certificate
Certificate Generation
You can generate certificates using various methods:
Self-Signed Certificates (Development)
# Generate private key
openssl genrsa -out server.key 2048
# Generate certificate
openssl req -new -x509 -key server.key -out server.crt -days 365 -subj "/CN=localhost"
# Use in configuration
[sites.ssl]
enabled = true
auto_cert = false
cert_file = "./server.crt"
key_file = "./server.key"
Commercial SSL Certificates
# Generate private key
openssl genrsa -out example.com.key 2048
# Generate certificate signing request
openssl req -new -key example.com.key -out example.com.csr
# Submit CSR to certificate authority
# Download certificate and intermediate certificates
# Combine certificate with intermediate certificates
cat example.com.crt intermediate.crt > example.com-chain.crt
# Use in configuration
[sites.ssl]
enabled = true
auto_cert = false
cert_file = "/etc/ssl/certs/example.com-chain.crt"
key_file = "/etc/ssl/private/example.com.key"
Per-Site SSL Configuration
Configuration Structure
Each site has its own SSL configuration section:
[[sites]]
name = "site_name"
hostname = "example.com"
port = 443
static_dir = "static"
[sites.ssl]
enabled = true # Enable SSL for this site
auto_cert = true # Use automatic certificates
domains = ["example.com", "www.example.com"] # Additional domains
cert_file = "path/to/cert.pem" # Manual certificate file
key_file = "path/to/key.pem" # Manual private key file
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false
challenge_dir = "./acme-challenges"
SSL Configuration Options
Field | Type | Description | Required |
---|---|---|---|
enabled | Boolean | Enable SSL for this site | Yes |
auto_cert | Boolean | Use ACME for automatic certificates | Yes |
domains | Array | Additional domains for the certificate | No |
cert_file | String | Path to certificate file (manual SSL) | If auto_cert = false |
key_file | String | Path to private key file (manual SSL) | If auto_cert = false |
Multi-Site SSL Examples
Mixed HTTP and HTTPS Sites
[server]
name = "Mixed Protocol Server"
# HTTP site on port 80
[[sites]]
name = "http_site"
hostname = "example.com"
port = 80
static_dir = "static"
[sites.ssl]
enabled = false
# HTTPS site on port 443 with auto SSL
[[sites]]
name = "https_site"
hostname = "example.com"
port = 443
static_dir = "static"
[sites.ssl]
enabled = true
auto_cert = true
domains = ["example.com", "www.example.com"]
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false
challenge_dir = "./acme-challenges"
# API site with manual SSL
[[sites]]
name = "api_site"
hostname = "api.example.com"
port = 8443
static_dir = "api-static"
[sites.ssl]
enabled = true
auto_cert = false
cert_file = "/etc/ssl/certs/api.example.com.crt"
key_file = "/etc/ssl/private/api.example.com.key"
Different SSL Configurations per Site
# Main website with Let's Encrypt
[[sites]]
name = "main"
hostname = "example.com"
port = 443
static_dir = "static"
[sites.ssl]
enabled = true
auto_cert = true
domains = ["example.com", "www.example.com"]
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false
challenge_dir = "./acme-challenges"
# Corporate subdomain with commercial certificate
[[sites]]
name = "corporate"
hostname = "corp.example.com"
port = 443
static_dir = "corp-static"
[sites.ssl]
enabled = true
auto_cert = false
cert_file = "/etc/ssl/certs/corp.example.com.crt"
key_file = "/etc/ssl/private/corp.example.com.key"
# Development site without SSL
[[sites]]
name = "dev"
hostname = "dev.example.com"
port = 8080
static_dir = "dev-static"
[sites.ssl]
enabled = false
Security Best Practices
File Permissions
Ensure proper file permissions for SSL files:
# Certificate files can be world-readable
chmod 644 /etc/ssl/certs/*.crt
# Private keys should be readable only by the owner
chmod 600 /etc/ssl/private/*.key
# Ensure BWS can read the files
chown bws:bws /etc/ssl/private/*.key
Security Headers
Use security headers with HTTPS sites:
[[sites]]
name = "secure_site"
hostname = "example.com"
port = 443
static_dir = "static"
[sites.ssl]
enabled = true
auto_cert = true
domains = ["example.com"]
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false
challenge_dir = "./acme-challenges"
[sites.headers]
"Strict-Transport-Security" = "max-age=31536000; includeSubDomains; preload"
"X-Frame-Options" = "DENY"
"X-Content-Type-Options" = "nosniff"
"Referrer-Policy" = "strict-origin-when-cross-origin"
"Content-Security-Policy" = "default-src 'self'; script-src 'self' 'unsafe-inline'"
Certificate Monitoring
Monitor certificate expiration:
# Check certificate expiration
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -dates
# For ACME certificates, BWS handles renewal automatically
# Check ACME certificate status in logs
tail -f /var/log/bws.log | grep -i acme
Troubleshooting
Common Issues
ACME Challenge Failures
# Ensure challenge directory is accessible
[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = true # Use staging for debugging
challenge_dir = "./acme-challenges"
Check that:
- Domain resolves to your server
- Port 80 is accessible for HTTP-01 challenges
- Challenge directory exists and is writable
- No firewall blocking HTTP traffic
Certificate File Errors
# Verify certificate file format
openssl x509 -in cert.pem -text -noout
# Verify private key format
openssl rsa -in key.pem -check
# Check if certificate and key match
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
Port Binding Issues
# Check if port is already in use
sudo lsof -i :443
# Ensure BWS has permission to bind to privileged ports
sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/bws
Debug Mode
Enable verbose logging for SSL debugging:
# Start BWS with verbose logging
RUST_LOG=debug bws --config config.toml --verbose
Validation
Test SSL configuration:
# Test HTTPS connectivity
curl -I https://example.com
# Check SSL certificate
openssl s_client -connect example.com:443 -servername example.com
# Test with specific protocol versions
curl --tlsv1.2 -I https://example.com
curl --tlsv1.3 -I https://example.com
Next Steps
- Configure Custom Headers for enhanced security
- Set up Health Monitoring for SSL sites
- Learn about Production Deployment with SSL
- Review Multi-Site Setup for complex configurations