Skip to main content

Overview

Wings supports HTTPS for its API server through two methods:
  1. Automatic TLS with Let’s Encrypt - Automatic certificate generation and renewal
  2. Manual TLS - Use your own SSL certificates

Automatic TLS with Let’s Encrypt

Wings can automatically obtain and renew SSL certificates from Let’s Encrypt using the ACME protocol.

Requirements

  • Valid domain name pointing to your Wings server
  • Port 80 (HTTP) accessible for ACME challenges
  • Port 443 (HTTPS) available for Wings API

Configuration

Auto-TLS is configured via command-line flags, not the configuration file:
wings --auto-tls --tls-hostname wings.example.com
Flags:
  • --auto-tls - Enable automatic TLS
  • --tls-hostname - FQDN for the SSL certificate (required with --auto-tls)

How It Works

  1. Wings starts and listens on port 443 for HTTPS
  2. An HTTP server starts on port 80 for ACME challenges
  3. Let’s Encrypt validates domain ownership via HTTP-01 challenge
  4. Certificate is automatically generated and stored
  5. Certificates are automatically renewed before expiration

Certificate Storage

Certificates are cached in:
/var/lib/pterodactyl/.tls-cache/
This directory is created automatically within the configured root directory.

Systemd Service Configuration

To use auto-TLS with systemd, modify your Wings service file:
[Unit]
Description=Pterodactyl Wings Daemon
After=docker.service
Requires=docker.service
PartOf=docker.service

[Service]
User=root
WorkingDirectory=/etc/pterodactyl
LimitNOFILE=4096
PIDFile=/var/run/wings/daemon.pid
ExecStart=/usr/local/bin/wings --auto-tls --tls-hostname wings.example.com
Restart=on-failure
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s

[Install]
WantedBy=multi-user.target
Reload and restart:
systemctl daemon-reload
systemctl restart wings

Firewall Configuration

Ensure ports 80 and 443 are accessible: UFW:
ufw allow 80/tcp
ufw allow 443/tcp
FirewallD:
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload
iptables:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Manual TLS Configuration

If you prefer to manage your own SSL certificates, configure manual TLS in the configuration file.

Configuration

api:
  host: 0.0.0.0
  port: 8080
  ssl:
    enabled: true
    cert: /etc/letsencrypt/live/wings.example.com/fullchain.pem
    key: /etc/letsencrypt/live/wings.example.com/privkey.pem
Options:
  • enabled - Set to true to enable SSL
  • cert - Path to certificate file (PEM format)
  • key - Path to private key file (PEM format)

Certificate Requirements

  • Format: PEM encoded
  • Certificate: Full certificate chain (including intermediates)
  • Private Key: Unencrypted private key
  • Permissions: Readable by the Wings process (typically root)

Using Let’s Encrypt Certificates Manually

If you have Let’s Encrypt certificates from another source:
api:
  ssl:
    enabled: true
    cert: /etc/letsencrypt/live/wings.example.com/fullchain.pem
    key: /etc/letsencrypt/live/wings.example.com/privkey.pem

Using Custom Certificates

For certificates from a commercial CA or internal CA:
api:
  ssl:
    enabled: true
    cert: /etc/ssl/certs/wings.crt
    key: /etc/ssl/private/wings.key

Certificate Renewal

With manual TLS, you’re responsible for certificate renewal:
  1. Renew your certificate through your CA or certbot
  2. Replace the certificate files
  3. Restart Wings:
    systemctl restart wings
    

TLS Configuration Details

Wings uses secure TLS defaults regardless of automatic or manual configuration:

Supported Protocols

  • Minimum: TLS 1.2
  • Maximum: TLS 1.3

Cipher Suites

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256

Curve Preferences

  • X25519
  • P-256

HTTP/2 Support

Wings supports HTTP/2 when TLS is enabled:
NextProtos: ["h2", "http/1.1"]

Running Without SSL

For development or when using a reverse proxy, you can run Wings without SSL:
api:
  host: 0.0.0.0
  port: 8080
  ssl:
    enabled: false
Running without SSL in production is not recommended. Use a reverse proxy like Nginx or Caddy if Wings itself won’t handle SSL.

Reverse Proxy Configuration

If using a reverse proxy for SSL termination, Wings should run without SSL:

Wings Configuration

api:
  host: 127.0.0.1
  port: 8080
  ssl:
    enabled: false
  trusted_proxies:
    - 127.0.0.1

Nginx Example

server {
    listen 80;
    server_name wings.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name wings.example.com;

    ssl_certificate /etc/letsencrypt/live/wings.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/wings.example.com/privkey.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Caddy Example

wings.example.com {
    reverse_proxy localhost:8080
}
Caddy automatically handles SSL certificate generation and renewal.

Troubleshooting

Auto-TLS Issues

Port 80 Already in Use

failed to serve autocert http server: listen tcp :80: bind: address already in use
Solution: Another service is using port 80. Stop it or use manual TLS.

Domain Validation Fails

acme/autocert: unable to satisfy http-01 challenge
Causes:
  • Domain doesn’t point to your server
  • Port 80 blocked by firewall
  • DNS propagation not complete
Solution:
  1. Verify DNS: dig wings.example.com
  2. Check firewall rules
  3. Wait for DNS propagation (up to 48 hours)

Manual TLS Issues

Certificate Not Found

failed to configure HTTPS server: open /path/to/cert.pem: no such file or directory
Solution: Verify certificate paths and file permissions.

Permission Denied

failed to configure HTTPS server: open /path/to/key.pem: permission denied
Solution: Ensure Wings (running as root) can read the certificate files:
chmod 600 /path/to/key.pem
chown root:root /path/to/key.pem

Certificate/Key Mismatch

tls: private key does not match public key
Solution: Ensure the certificate and private key are from the same certificate request.

Verification

Test your SSL configuration:
curl -I https://wings.example.com:8080
Check certificate details:
openssl s_client -connect wings.example.com:8080 -servername wings.example.com
Online SSL test:

Security Best Practices

  1. Always use SSL/TLS in production - Even behind a reverse proxy
  2. Keep certificates updated - Monitor expiration dates
  3. Use strong ciphers - Wings defaults are secure
  4. Enable HTTP/2 - Automatically enabled with TLS
  5. Secure private keys - Restrict permissions (600)
  6. Use HSTS - Configure on reverse proxy if applicable

Comparison: Auto-TLS vs Manual TLS

FeatureAuto-TLSManual TLS
Certificate GenerationAutomaticManual
RenewalAutomaticManual
Port Requirements80, 443Custom
ConfigurationCommand-lineConfig file
Best ForSimple deploymentsComplex environments, reverse proxies
DNS RequiredYesOptional
SSL/TLS configuration works alongside:
  • API host/port settings - Where Wings listens
  • Trusted proxies - For X-Forwarded headers
  • CORS settings - Cross-origin requests
  • Panel configuration - Must match Wings URL

Build docs developers (and LLMs) love