Configuration Reference

This document provides detailed configuration references for all components of the PQC SSL deployment. All examples are based on our production deployment at pqcnow.com.

Table of Contents

1. HAProxy Configuration 2. Nginx Configuration 3. Apache Configuration 4. systemd Service Configuration 5. Docker Deployment 6. Advanced Scenarios

---

HAProxy Configuration

HAProxy acts as a layer-4 (TCP) proxy that routes traffic based on Server Name Indication (SNI) without decrypting SSL/TLS.

Complete HAProxy Configuration

File: \/etc/haproxy/haproxy.cfg\

\\\haproxy global # Logging configuration log /dev/log local0 log /dev/log local1 notice # Security: run in chroot jail chroot /var/lib/haproxy # Admin socket for runtime management stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s # User/group to run as user haproxy group haproxy # Run as daemon daemon # Maximum concurrent connections maxconn 2000 # SSL/TLS tuning (optional) # tune.ssl.default-dh-param 2048

defaults log global mode tcp # Layer 4 (TCP) mode for SNI routing option tcplog # TCP-specific logging option dontlognull # Don't log null connections timeout connect 5000 # 5 seconds to establish connection timeout client 50000 # 50 seconds client inactivity timeout server 50000 # 50 seconds server inactivity # Error handling retries 3 option redispatch

Main HTTPS frontend - routes based on SNI

frontend https_front bind *:443 # Listen on all interfaces, port 443 mode tcp option tcplog # SNI inspection settings tcp-request inspect-delay 5s # Wait up to 5s to inspect SNI tcp-request content accept if { req_ssl_hello_type 1 } # ACLs for routing based on SNI # Add your PQC domain here acl is_pqc_demo req_ssl_sni -i demo.pqcnow.com acl is_pqc_demo req_ssl_sni -i pqc.pqcnow.com # Routing logic use_backend pqc_demo if is_pqc_demo default_backend main_site

Backend for traditional SSL website

backend main_site mode tcp balance roundrobin # Load balancing algorithm # Backend server(s) server nginx1 127.0.0.1:8080 check inter 2000 rise 2 fall 3 # Add more servers for load balancing: # server nginx2 127.0.0.1:8081 check inter 2000 rise 2 fall 3 # Health check settings option tcp-check

Backend for PQC demo website

backend pqc_demo mode tcp balance roundrobin # Backend PQC server(s) server pqc1 127.0.0.1:9443 check inter 2000 rise 2 fall 3 # Add more servers for load balancing: # server pqc2 127.0.0.1:9444 check inter 2000 rise 2 fall 3 # Health check settings option tcp-check

Optional: HAProxy statistics page

listen stats bind *:8404 # Stats page on port 8404 mode http stats enable stats uri /stats # Access via http://server:8404/stats stats refresh 30s stats auth admin:your-password-here # Change this! \
\\

HAProxy ACL Examples

Different SNI matching patterns:

\\\haproxy

Exact match

acl is_pqc req_ssl_sni -i pqc.example.com

Multiple domains

acl is_pqc req_ssl_sni -i pqc.example.com demo.example.com

Wildcard matching

acl is_pqc req_ssl_sni -m end .pqc.example.com

Regex matching

acl is_pqc req_ssl_sni -m reg ^pqc[0-9]+\.example\.com$ \
\\

Testing HAProxy Configuration

\\\bash

Check configuration syntax

haproxy -c -f /etc/haproxy/haproxy.cfg

Reload without downtime

systemctl reload haproxy

View logs

journalctl -u haproxy -f \
\\

---

Nginx Configuration

Main Site Configuration (Traditional SSL)

File: \/etc/nginx/sites-available/pqcnow.com\ (Production Example)

\\\nginx

HTTP to HTTPS redirect

server { listen 80; listen [::]:80; server_name pqcnow.com www.pqcnow.com; # ACME challenge for Let's Encrypt location /.well-known/acme-challenge/ { root /var/www/letsencrypt; } # Redirect all other traffic to HTTPS location / { return 301 https://\$host\$request_uri; } }

HTTPS server on backend port 8080

HAProxy forwards :443 traffic here based on SNI

server { listen 8080 ssl http2; listen [::]:8080 ssl http2; server_name pqcnow.com www.pqcnow.com;

# Document root root /var/www/pqcnow-laravel/public; index index.php index.html index.htm;

# Let's Encrypt SSL certificate ssl_certificate /etc/letsencrypt/live/pqcnow.com-0001/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/pqcnow.com-0001/privkey.pem;

# SSL configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;

# Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always;

# Laravel specific location / { try_files \$uri \$uri/ /index.php?\$query_string; }

# PHP-FPM configuration location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name; include fastcgi_params; }

# Deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; }

# Logging access_log /var/log/nginx/pqcnow.com.access.log; error_log /var/log/nginx/pqcnow.com.error.log;

# WebSocket support (if needed) location /ws { proxy_pass http://127.0.0.1:6001; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_cache_bypass \$http_upgrade; } } \\\

PQC Demo HTTP Redirect

File: \/etc/nginx/sites-available/demo.pqcnow.com\

\\\nginx

HTTP to HTTPS redirect for PQC demo

server { listen 80; listen [::]:80; server_name demo.pqcnow.com;

# Redirect to HTTPS # HAProxy will route HTTPS traffic to BoringSSL server location / { return 301 https://\$server_name\$request_uri; }

# Optional: serve ACME challenge if using Let's Encrypt for PQC cert location /.well-known/acme-challenge/ { root /var/www/letsencrypt; } } \\\

Advanced Nginx Features

#### Rate Limiting

\\\nginx

In http block

limit_req_zone \$binary_remote_addr zone=general:10m rate=10r/s; limit_req_zone \$binary_remote_addr zone=api:10m rate=2r/s;

In server block

location / { limit_req zone=general burst=20 nodelay; # ... rest of config }

location /api/ { limit_req zone=api burst=5 nodelay; # ... rest of config } \\\

#### Caching Static Assets

\\\nginx

Cache static files

location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot|webp)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } \\\

---

Apache Configuration

Main Site Configuration (Traditional SSL)

File: \/etc/apache2/sites-available/example.com-ssl.conf\

\\\apache

Listen on backend port 8080

Listen 8080

ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/public # SSL Configuration SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem # SSL Protocol settings SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite HIGH:!aNULL:!MD5 SSLHonorCipherOrder on # HSTS header Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" # Security headers Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" # Directory settings Options -Indexes +FollowSymLinks AllowOverride All Require all granted # Logging ErrorLog \${APACHE_LOG_DIR}/example.com.error.log CustomLog \${APACHE_LOG_DIR}/example.com.access.log combined \\\

PQC Demo Apache Configuration

File: \/etc/apache2/sites-available/demo-pqc-apache.conf\ (Production Example)

\\\apache

PQC Demo Site with ML-DSA Certificate

Serves on port 9443 with PQC certificate

Listen 9443

ServerName demo.pqcnow.com DocumentRoot /var/www/html/demo # SSL Configuration with ML-DSA Certificate SSLEngine on SSLCertificateFile /var/www/pqcnow-laravel/storage/app/certificates/demo.pqcnow.com/demo.pqcnow.com.crt SSLCertificateKeyFile /var/www/pqcnow-laravel/storage/app/certificates/demo.pqcnow.com/demo.pqcnow.com.key # SSL Protocol settings SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite HIGH:!aNULL:!MD5 SSLHonorCipherOrder on # Directory settings Options -Indexes +FollowSymLinks AllowOverride All Require all granted # Security headers Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" # Logs ErrorLog \${APACHE_LOG_DIR}/demo-pqc.error.log CustomLog \${APACHE_LOG_DIR}/demo-pqc.access.log combined \\\

HTTP Redirect for Apache

File: \/etc/apache2/sites-available/000-default.conf\

\\\apache ServerName example.com ServerAlias www.example.com demo.example.com # Redirect all HTTP to HTTPS RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] # ACME challenge for Let's Encrypt Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/ Require all granted \\\

---

systemd Service Configuration

PQC Demo Server Service

File: \/etc/systemd/system/pqc-demo.service\ (Production Example)

\\\ini [Unit] Description=PQC HTTPS Demo Server Documentation=https://pqcnow.com/docs/ After=network.target network-online.target Wants=network-online.target

[Service] Type=simple User=root Group=root WorkingDirectory=/home/pqc

Command to start the PQC server

Arguments: certificate-bundle key port [web-root]

ExecStart=/home/pqc/bssl_https_server_pqc demo.pqcnow.com-bundle.crt demo.pqcnow.com.key 9443 /var/www/html/demo

Restart policy

Restart=always RestartSec=5 StartLimitInterval=0

Output to journal

StandardOutput=journal StandardError=journal SyslogIdentifier=pqc-demo

Security settings

PrivateTmp=yes NoNewPrivileges=true ProtectSystem=strict ProtectHome=yes ReadWritePaths=/var/log/pqc-demo

Resource limits

LimitNOFILE=65536

[Install] WantedBy=multi-user.target \\\

Managing the Service

\\\bash

Reload systemd after changes

systemctl daemon-reload

Enable service (start on boot)

systemctl enable pqc-demo

Start service

systemctl start pqc-demo

Check status

systemctl status pqc-demo

View logs

journalctl -u pqc-demo -f

Restart service

systemctl restart pqc-demo

Stop service

systemctl stop pqc-demo \
\\

---

Docker Deployment

Docker Compose Configuration

File: \docker-compose.yml\

\\\yaml version: '3.8'

services: # HAProxy SNI router haproxy: image: haproxy:2.8-alpine container_name: haproxy ports: - "80:80" - "443:443" volumes: - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro networks: - web restart: unless-stopped

# Main website (Nginx + traditional SSL) main-site: image: nginx:alpine container_name: main-site volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/ssl:/etc/nginx/ssl:ro - ./www:/var/www/html:ro networks: - web expose: - "8080" restart: unless-stopped

# PQC demo server pqc-demo: build: context: . dockerfile: Dockerfile.pqc container_name: pqc-demo volumes: - ./pqc-certs:/opt/pqc/certificates:ro - ./pqc-www:/opt/pqc/www:ro networks: - web expose: - "9443" restart: unless-stopped command: [ "/opt/pqc/bssl_https_server_pqc", "/opt/pqc/certificates/pqc.example.com-bundle.crt", "/opt/pqc/certificates/pqc.example.com.key", "9443", "/opt/pqc/www" ]

networks: web: driver: bridge \\\

Dockerfile for PQC Server

File: \Dockerfile.pqc\

\\\dockerfile FROM ubuntu:22.04

Install dependencies

RUN apt-get update && apt-get install -y \ ca-certificates \ && rm -rf /var/lib/apt/lists/*

Copy pre-built BoringSSL server

COPY bssl_https_server_pqc /opt/pqc/bssl_https_server_pqc RUN chmod +x /opt/pqc/bssl_https_server_pqc

Create directories

RUN mkdir -p /opt/pqc/certificates /opt/pqc/www

WORKDIR /opt/pqc

EXPOSE 9443

Will be overridden by docker-compose command

CMD ["/opt/pqc/bssl_https_server_pqc", "--help"] \
\\

---

Advanced Scenarios

Multiple PQC Demo Sites

HAProxy configuration for multiple PQC sites:

\\\haproxy frontend https_front bind *:443 mode tcp option tcplog tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } # Route different PQC demos to different backends use_backend pqc_demo1 if { req_ssl_sni -i pqc1.example.com } use_backend pqc_demo2 if { req_ssl_sni -i pqc2.example.com } use_backend pqc_demo3 if { req_ssl_sni -i pqc3.example.com } default_backend main_site

backend pqc_demo1 mode tcp server pqc1 127.0.0.1:9443 check

backend pqc_demo2 mode tcp server pqc2 127.0.0.1:9444 check

backend pqc_demo3 mode tcp server pqc3 127.0.0.1:9445 check \\\

Load Balancing

HAProxy configuration with multiple backend servers:

\\\haproxy backend main_site mode tcp balance roundrobin option httpchk GET /health server web1 10.0.1.10:8080 check server web2 10.0.1.11:8080 check server web3 10.0.1.12:8080 check backup

backend pqc_demo mode tcp balance leastconn server pqc1 10.0.2.10:9443 check server pqc2 10.0.2.11:9443 check \\\

Firewall Configuration

\\\bash

UFW (Ubuntu/Debian)

ufw allow 80/tcp ufw allow 443/tcp ufw allow 8404/tcp # HAProxy stats (if enabled)

iptables

iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT \
\\

---

Configuration Testing

Test HAProxy

\\\bash haproxy -c -f /etc/haproxy/haproxy.cfg \\\

Test Nginx

\\\bash nginx -t \\\

Test Apache

\\\bash apachectl configtest \\\

Test SSL/TLS

\\\bash

Test traditional SSL

openssl s_client -connect example.com:443 -servername example.com

Test PQC server locally

openssl s_client -connect localhost:9443 -servername pqc.example.com \
\\

---

Related Documentation

Support

  • Technical Support: support@pqcnow.com
  • Website: https://pqcnow.com