Homelab

Pterodactyl Panel + Wings derrière HAProxy — Port 443 depuis partout

Déployer Pterodactyl Panel et Wings sur Debian 13 avec HAProxy comme reverse proxy TLS — Wings exposé sur le port 443 pour contourner les restrictions réseau d'entreprise.

Table des matières

Pterodactyl est un panel open source de gestion de serveurs de jeu. Le problème classique : Wings (le daemon) écoute par défaut sur le port 8080, souvent bloqué dans les réseaux d’entreprise. Solution : passer Wings derrière HAProxy sur le port 443.

Problème

Le panel Pterodactyl contacte le daemon Wings via le navigateur du client :

Navigateur → node.domaine.com:8080 → Wings

Depuis un réseau d’entreprise, le port 8080 est bloqué par le pare-feu. Le node apparaît en rouge dans le panel même si Wings fonctionne parfaitement en local.

Architecture cible

Internet (port 443 uniquement)
        │
        ▼
HAProxy — TLS termination
        │
        ├── pterodactyl.domaine.com:443 → Panel (nginx:443)
        └── node.domaine.com:443        → Wings (HTTP:8080)

# Wings écoute en HTTP sur 8080 — HAProxy gère le TLS

Installation Debian 13

# PHP 8.3 via sury.org
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg \
  https://packages.sury.org/php/apt.gpg
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] \
  https://packages.sury.org/php/ trixie main" \
  > /etc/apt/sources.list.d/php.list

apt update && apt install -y \
  php8.3 php8.3-{cli,fpm,mysql,mbstring,bcmath,xml,curl,zip,gd,tokenizer} \
  nginx mariadb-client certbot python3-certbot-nginx

Installation du Panel

mkdir -p /var/www/pterodactyl && cd /var/www/pterodactyl
curl -Lo panel.tar.gz \
  https://github.com/pterodactyl/panel/releases/latest/download/panel.tar.gz
tar -xzf panel.tar.gz
chmod -R 755 storage/* bootstrap/cache/

composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate --force
php artisan p:environment:setup
php artisan p:environment:database
php artisan migrate --seed --force
php artisan p:user:make
chown -R www-data:www-data /var/www/pterodactyl

Nginx pour le Panel

server {
    listen 443 ssl;
    server_name pterodactyl.domaine.com;

    ssl_certificate     /etc/letsencrypt/live/pterodactyl.domaine.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pterodactyl.domaine.com/privkey.pem;

    root /var/www/pterodactyl/public;
    index index.php;

    location / { try_files $uri $uri/ /index.php?$query_string; }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
    }
}

Installation de Wings

mkdir -p /etc/pterodactyl
curl -L -o /usr/local/bin/wings \
  "https://github.com/pterodactyl/wings/releases/latest/download/wings_linux_amd64"
chmod u+x /usr/local/bin/wings

Configuration Wings — HTTP interne

Dans le panel : Admin → Nodes → Créer un node :

  • FQDN : node.domaine.com
  • Daemon Port : 443 ← port public exposé par HAProxy
  • Behind Proxy coché ← critique

Copier la config générée dans /etc/pterodactyl/config.yml.

Vérifier que Wings écoute en HTTP sur 8080 (pas 443) :

# /etc/pterodactyl/config.yml
api:
  port: 8080      # Port interne — HAProxy proxifie vers ici
  ssl:
    enabled: false # HAProxy gère le TLS
# Service systemd
curl -o /etc/systemd/system/wings.service \
  https://raw.githubusercontent.com/pterodactyl/wings/develop/wings.service
systemctl enable --now wings

# Vérifier
ss -tlnp | grep 8080
# → Wings écoute sur 0.0.0.0:8080

Configuration HAProxy

frontend https_front
    bind *:443 ssl crt /etc/haproxy/combined.pem alpn h2,http/1.1

    acl is_panel hdr(host) -i pterodactyl.domaine.com
    acl is_node  hdr(host) -i node.domaine.com

    use_backend panel_backend if is_panel
    use_backend wings_backend if is_node

backend panel_backend
    option forwardfor
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    timeout tunnel 1h
    server panel 192.168.x.x:443 check ssl verify none

backend wings_backend
    mode http
    option forwardfor
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    timeout tunnel 1h
    server wings 192.168.x.x:8080 check
    # Pas de "ssl" ici — Wings tourne en HTTP pur
ssl verify none vs check

Pour le backend Wings : juste ‘check’ sans ‘ssl’ — Wings écoute en HTTP. Pour le panel nginx qui écoute en HTTPS : ‘check ssl verify none’.

Vérification

# Tester Wings via HAProxy
curl -sk https://node.domaine.com/api/system -o /dev/null -w "%{http_code}"
# → 401 (authentification requise — Wings répond correctement)

# Le node doit passer en vert dans le panel

Firewall sur le serveur Wings

# Autoriser Wings uniquement depuis HAProxy
iptables -A INPUT -p tcp --dport 8080 -s 192.168.x.11 -j ACCEPT  # IP HAProxy
iptables -A INPUT -p tcp --dport 8080 -j DROP

# Port Panel nginx
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# SFTP Pterodactyl
iptables -A INPUT -p tcp --dport 2022 -j ACCEPT

# Persister
apt install -y iptables-persistent
netfilter-persistent save

Résultat

  • Panel accessible depuis n’importe quel réseau sur le port 443 ✅
  • Wings accessible via HAProxy sur node.domaine.com:443 ✅
  • Port 8080 non exposé sur internet ✅
  • Serveurs de jeu accessibles (Docker ouvre les ports automatiquement) ✅
Renouvellement certificats

Configurez un cron pour renouveler automatiquement les certs Let’s Encrypt et regénérer le combined.pem pour HAProxy (cat fullchain.pem privkey.pem > combined.pem).

Comments