TLS/HTTPS 
Nylon provides comprehensive TLS support with automatic certificate management through ACME (Let's Encrypt).
Quick HTTPS Setup 
Automatic Certificates (Let's Encrypt) 
# Runtime config
https:
  - 0.0.0.0:443
config_dir: "./config"
acme: "./acme"  # Certificate storage directory# Proxy config
tls:
  - type: acme
    provider: letsencrypt
    domains:
      - example.com
      - www.example.com
    acme:
      email: [email protected]
routes:
  - route:
      type: host
      value: example.com|www.example.com
    name: main
    tls:
      enabled: true
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: backendThat's it! Nylon will:
- Automatically request certificates
- Handle ACME HTTP-01 challenge
- Renew certificates before expiry
- Serve HTTPS traffic
Manual Certificates 
Using Your Own Certificates 
tls:
  - type: custom
    domains:
      - example.com
      - www.example.com
    cert: /path/to/cert.pem
    key: /path/to/key.pemCertificate Formats 
Nylon accepts standard PEM-encoded certificates:
# Certificate file (cert.pem)
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# Private key file (key.pem)
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----ACME Configuration 
Let's Encrypt Production 
tls:
  - type: acme
    provider: letsencrypt
    domains:
      - example.com
    acme:
      email: [email protected]Let's Encrypt Staging (Testing) 
tls:
  - type: acme
    provider: letsencrypt
    domains:
      - example.com
    acme:
      email: [email protected]Use staging for testing to avoid rate limits!
ACME HTTP-01 Challenge 
Nylon automatically handles HTTP-01 challenge:
- ACME server requests validation at: http://example.com/.well-known/acme-challenge/{token}
- Nylon responds with challenge response
- Certificate issued after validation
Requirements:
- Domain must point to your Nylon server
- Port 80 must be accessible from internet
- HTTP listener must be configured
Multi-Domain Certificates 
Separate Certificates 
tls:
  # Certificate for api.example.com
  - type: acme
    provider: letsencrypt
    domains:
      - api.example.com
    acme:
      email: [email protected]
  # Certificate for admin.example.com
  - type: acme
    provider: letsencrypt
    domains:
      - admin.example.com
    acme:
      email: [email protected]Wildcard Certificates 
Wildcard certificates require DNS-01 challenge (not yet supported). Use separate certificates or SAN certificates instead.
# NOT YET SUPPORTED
tls:
  - domains:
      - "*.example.com"  # Wildcard not supported yetWorkaround: List all subdomains:
tls:
  - type: acme
    provider: letsencrypt
    domains:
      - api.example.com
      - admin.example.com
      - app.example.com
    acme:
      email: [email protected]HTTP to HTTPS Redirect 
Automatically redirect HTTP requests to HTTPS:
routes:
  - route:
      type: host
      value: example.com|api.example.com|admin.example.com
    name: main
    tls:
      enabled: true
      redirect: ${host}  # Redirect HTTP to HTTPS
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: backendRequests to http://example.com/* → https://example.com/*
Certificate Renewal 
Automatic Renewal 
Nylon automatically renews certificates:
- Checks expiry daily
- Renews certificates 30 days before expiry
- No downtime during renewal
Manual Renewal 
Force certificate renewal:
# Reload configuration (triggers renewal check)
sudo nylon service reload
# Or send SIGHUP
kill -HUP $(cat /var/run/nylon.pid)Certificate Storage 
Certificates are stored in the ACME directory:
acme/
├── example.com.cert
├── example.com.key
├── api.example.com.cert
├── api.example.com.key
└── account.jsonKeep these files safe!
- Back up regularly
- Set appropriate permissions: chmod 600 *.key
- Don't commit to version control
SNI (Server Name Indication) 
Nylon supports SNI for serving multiple domains on one IP:
tls:
  - domains:
      - example.com
    cert: /path/to/example.com.pem
    key: /path/to/example.com.key
  - domains:
      - another.com
    cert: /path/to/another.com.pem
    key: /path/to/another.com.keyNylon automatically selects the correct certificate based on the requested hostname.
TLS Versions and Ciphers 
Nylon uses secure defaults from Pingora:
- TLS 1.2 and TLS 1.3 enabled
- Modern cipher suites
- Forward secrecy
- No support for insecure protocols (SSLv3, TLS 1.0, TLS 1.1)
Examples 
Production Setup 
# config.yaml
http:
  - 0.0.0.0:80
https:
  - 0.0.0.0:443
config_dir: "/etc/nylon/config"
acme: "/etc/nylon/acme"
pingora:
  threads: 4# config/proxy.yaml
tls:
  - domains:
      - example.com
      - www.example.com
    acme:
      email: [email protected]
services:
  - name: backend
    service_type: http
    endpoints:
      - ip: 10.0.0.1
        port: 3000
routes:
  - route:
      type: host
      value: example.com
    name: main
    tls:
      enabled: true
      redirect: ${host}
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: backendMultiple Domains 
tls:
  - domains:
      - api.example.com
    acme:
      email: [email protected]
  - domains:
      - admin.example.com
    acme:
      email: [email protected]
routes:
  - route:
      type: host
      value: api.example.com
    name: api
    tls:
      enabled: true
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: api-service
  - route:
      type: host
      value: admin.example.com
    name: admin
    tls:
      enabled: true
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: admin-serviceMixed HTTP/HTTPS 
routes:
  # HTTPS only
  - route:
      type: host
      value: secure.example.com
    name: secure
    tls:
      enabled: true
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: secure-service
  # HTTP only (internal service)
  - route:
      type: host
      value: internal.example.com
    name: internal
    paths:
      - path:
          - /
          - /{*path}
        service:
          name: internal-serviceTroubleshooting 
Certificate Not Issued 
Check domain DNS:
dig example.com
nslookup example.comCheck port 80 accessibility:
curl -I http://example.com/.well-known/acme-challenge/testCheck logs:
sudo journalctl -u nylon -fRate Limiting 
Let's Encrypt has rate limits:
- 50 certificates per domain per week
- 5 duplicate certificates per week
Solution: Use staging for testing:
directory_url: https://acme-staging-v02.api.letsencrypt.org/directoryCertificate Expired 
If auto-renewal fails:
# Remove old certificate
rm acme/example.com.cert acme/example.com.key
# Reload to trigger new request
sudo nylon service reloadSNI Not Working 
Ensure:
- Client supports SNI (all modern browsers do)
- Hostname in request matches configured domain
- Certificate includes the requested domain
Security Best Practices 
1. Use Production ACME URL 
# ✅ Good
directory_url: https://acme-v02.api.letsencrypt.org/directory
# ❌ Bad (staging certificates not trusted)
directory_url: https://acme-staging-v02.api.letsencrypt.org/directory2. Protect Private Keys 
chmod 600 acme/*.key
chown root:root acme/*.key3. Enable HTTPS Redirect 
tls:
  enabled: true
  redirect: ${host}  # Force HTTPS4. Use HSTS Header 
middleware:
  - plugin: ResponseHeaderModifier
    payload:
      set:
        - name: strict-transport-security
          value: "max-age=31536000; includeSubDomains"5. Monitor Certificate Expiry 
Set up monitoring for certificates expiring soon:
# Check certificate expiry
openssl x509 -in acme/example.com.cert -noout -datesSee Also 
- Configuration - TLS configuration reference
- Routing - Configure routes with TLS
- Examples - TLS examples