Skip to content

SSL/TLS Configuration Guide

This guide covers configuring SSL/TLS for secure connections in MAID, including both Telnet (TLS) and WebSocket (HTTPS/WSS) servers.

Overview

MAID supports SSL/TLS encryption for: - Telnet connections - Secure login and gameplay over TLS - WebSocket connections - HTTPS for the web interface and WSS for real-time communication

Both can run alongside unencrypted connections on different ports, or you can configure TLS-only mode.


Quick Start (Development)

Generate Self-Signed Certificates

For development and testing, generate a self-signed certificate:

# Create a directory for certificates
mkdir -p certs

# Generate a self-signed certificate (valid for 365 days)
openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -nodes \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

For development with IP addresses:

openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -nodes \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

Enable SSL in Development

Create or update your .env file:

# Enable SSL for Telnet
MAID_TELNET__SSL__ENABLED=true
MAID_TELNET__SSL__CERT_PATH=certs/cert.pem
MAID_TELNET__SSL__KEY_PATH=certs/key.pem
MAID_TELNET__SSL_PORT=4001

# Enable SSL for Web
MAID_WEB__SSL__ENABLED=true
MAID_WEB__SSL__CERT_PATH=certs/cert.pem
MAID_WEB__SSL__KEY_PATH=certs/key.pem
MAID_WEB__HTTPS_PORT=8443

Start the server:

uv run maid server start

The server will now accept: - Plain Telnet on port 4000 - Secure Telnet (TLS) on port 4001 - HTTP on port 8080 - HTTPS on port 8443


Configuration Reference

SSL Settings (SSLSettings)

SSL settings are nested under MAID_TELNET__SSL__ or MAID_WEB__SSL__:

Setting Type Default Description
enabled bool false Enable SSL/TLS
cert_path Path None Path to certificate file (.pem or .crt)
key_path Path None Path to private key file (.pem or .key)
key_password str None Password for encrypted private key
ca_path Path None Path to CA bundle for chain verification
min_version str "TLSv1.2" Minimum TLS version ("TLSv1.2" or "TLSv1.3")
verify_client bool false Require client certificate (mutual TLS)
client_ca_path Path None CA for verifying client certificates
ciphers str None Custom cipher suite (None = secure defaults)

Telnet-Specific Settings

Setting Type Default Description
MAID_TELNET__SSL_PORT int None Separate port for TLS connections

Web-Specific Settings

Setting Type Default Description
MAID_WEB__HTTPS_PORT int None HTTPS port
MAID_WEB__REDIRECT_HTTP_TO_HTTPS bool false Auto-redirect HTTP to HTTPS

TLS Version Selection

TLS 1.2 (Default)

TLS 1.2 is the default minimum version and provides broad compatibility:

MAID_TELNET__SSL__MIN_VERSION=TLSv1.2

Use TLS 1.2 when: - Supporting older MUD clients - Compatibility is more important than cutting-edge security

TLS 1.3 provides improved security and performance:

MAID_TELNET__SSL__MIN_VERSION=TLSv1.3

Use TLS 1.3 when: - All clients support TLS 1.3 - Maximum security is required - Better performance is desired (faster handshakes)


Production Configuration

Using Let's Encrypt Certificates

  1. Install Certbot:
# Ubuntu/Debian
sudo apt install certbot

# macOS
brew install certbot
  1. Obtain certificates:
sudo certbot certonly --standalone -d yourdomain.com
  1. Configure MAID:
MAID_TELNET__SSL__ENABLED=true
MAID_TELNET__SSL__CERT_PATH=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
MAID_TELNET__SSL__KEY_PATH=/etc/letsencrypt/live/yourdomain.com/privkey.pem
MAID_TELNET__SSL__MIN_VERSION=TLSv1.3
MAID_TELNET__SSL_PORT=4001

MAID_WEB__SSL__ENABLED=true
MAID_WEB__SSL__CERT_PATH=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
MAID_WEB__SSL__KEY_PATH=/etc/letsencrypt/live/yourdomain.com/privkey.pem
MAID_WEB__SSL__MIN_VERSION=TLSv1.3
MAID_WEB__HTTPS_PORT=443
MAID_WEB__REDIRECT_HTTP_TO_HTTPS=true
  1. Set up automatic renewal:

Certbot automatically installs a cron job or systemd timer for renewal. MAID's certificate hot-reload feature will detect the new certificates.

Full Production Example

# .env - Production Configuration

# Telnet SSL
MAID_TELNET__SSL__ENABLED=true
MAID_TELNET__SSL__CERT_PATH=/etc/ssl/maid/cert.pem
MAID_TELNET__SSL__KEY_PATH=/etc/ssl/maid/key.pem
MAID_TELNET__SSL__MIN_VERSION=TLSv1.3
MAID_TELNET__SSL_PORT=4001

# Web SSL
MAID_WEB__SSL__ENABLED=true
MAID_WEB__SSL__CERT_PATH=/etc/ssl/maid/cert.pem
MAID_WEB__SSL__KEY_PATH=/etc/ssl/maid/key.pem
MAID_WEB__SSL__MIN_VERSION=TLSv1.3
MAID_WEB__HTTPS_PORT=443
MAID_WEB__REDIRECT_HTTP_TO_HTTPS=true

Client Certificate Authentication (Mutual TLS)

For enhanced security, you can require clients to present certificates:

Server Configuration

# Enable client verification
MAID_TELNET__SSL__VERIFY_CLIENT=true
MAID_TELNET__SSL__CLIENT_CA_PATH=/etc/ssl/maid/client-ca.pem

MAID_WEB__SSL__VERIFY_CLIENT=true
MAID_WEB__SSL__CLIENT_CA_PATH=/etc/ssl/maid/client-ca.pem

Creating a Client CA and Certificates

  1. Create the CA:
# Generate CA key
openssl genrsa -out client-ca-key.pem 4096

# Generate CA certificate
openssl req -x509 -new -nodes -key client-ca-key.pem -sha256 -days 1825 \
  -out client-ca.pem -subj "/CN=MAID Client CA"
  1. Create a client certificate:
# Generate client key
openssl genrsa -out client-key.pem 2048

# Generate certificate signing request
openssl req -new -key client-key.pem -out client.csr \
  -subj "/CN=PlayerName/O=MAID Players"

# Sign with CA
openssl x509 -req -in client.csr -CA client-ca.pem -CAkey client-ca-key.pem \
  -CAcreateserial -out client-cert.pem -days 365 -sha256
  1. Distribute to players:

Players will need both client-cert.pem and client-key.pem to connect.


Certificate Hot-Reload

MAID automatically detects certificate file changes and reloads them without restart.

How It Works

The CertificateReloader class monitors certificate file modification times: - Checks are performed periodically during server operation - When changes are detected, the SSL context is rebuilt - Active connections continue with the old context - New connections use the updated certificates

Triggering a Reload

Simply replace the certificate files:

# Update certificates
cp new-cert.pem /etc/ssl/maid/cert.pem
cp new-key.pem /etc/ssl/maid/key.pem

The server will automatically detect the change and reload within seconds.

Verification

Check the server logs for reload confirmation:

INFO: Certificate files changed, reloading SSL context
INFO: Created SSL context: TLS >= TLSv1.3, cert=/etc/ssl/maid/cert.pem

Custom Cipher Suites

For specific compliance requirements, you can specify custom cipher suites:

# TLS 1.3 ciphers only
MAID_TELNET__SSL__CIPHERS="TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"

# TLS 1.2+ with specific suites
MAID_WEB__SSL__CIPHERS="ECDHE+AESGCM:DHE+AESGCM:ECDHE+CHACHA20:DHE+CHACHA20"

The default cipher suite prioritizes: 1. ECDHE key exchange (forward secrecy) 2. AES-GCM and ChaCha20 encryption 3. SHA-384/256 for integrity


Troubleshooting

Certificate File Not Found

Error: ValueError: File not found: /path/to/cert.pem

Solutions: - Verify the file path is correct and absolute - Check file permissions (MAID needs read access) - Ensure the file exists before starting the server

Invalid Certificate Format

Error: SSLError: SSL configuration error: [SSL] PEM lib

Solutions: - Verify the certificate is in PEM format (starts with -----BEGIN CERTIFICATE-----) - Check that the private key matches the certificate - Ensure no extra whitespace or characters in the files

Certificate Expired

Error: SSLError: certificate has expired

Solutions: - Renew the certificate - For Let's Encrypt: sudo certbot renew - Check expiration: openssl x509 -enddate -noout -in cert.pem

TLS Version Mismatch

Error: SSLError: [SSL: UNSUPPORTED_PROTOCOL]

Solutions: - Lower the minimum TLS version: MAID_TELNET__SSL__MIN_VERSION=TLSv1.2 - Update the client to support newer TLS versions

Permission Denied

Error: SSLError: [Errno 13] Permission denied

Solutions: - Ensure MAID has read permissions on certificate files - For Let's Encrypt: Add MAID user to the ssl-cert group - Consider copying certificates to a MAID-accessible location

Connection Refused on SSL Port

Symptoms: Cannot connect to the SSL port, but plain port works

Solutions: - Verify SSL is enabled: MAID_TELNET__SSL__ENABLED=true - Check the SSL port is configured: MAID_TELNET__SSL_PORT=4001 - Verify no firewall is blocking the SSL port - Check server logs for SSL context creation messages

Testing SSL Connections

Test Telnet SSL with OpenSSL:

openssl s_client -connect localhost:4001

Test HTTPS:

curl -v https://localhost:8443/api/v1/health --insecure

Check certificate details:

openssl s_client -connect localhost:4001 -showcerts </dev/null

Security Best Practices

  1. Use TLS 1.3 when possible - Better security and performance
  2. Enable HTTP to HTTPS redirect - Prevent accidental unencrypted access
  3. Use strong keys - RSA 4096-bit or ECDSA P-384
  4. Automate certificate renewal - Prevent expiration issues
  5. Monitor certificate expiration - Set up alerts before expiry
  6. Restrict certificate file permissions - chmod 600 for key files
  7. Use separate ports in development - Run both plain and TLS for testing
  8. Test certificate changes - Verify hot-reload works before production