Skip to content

Reverse Proxy & TLS

Configurer un reverse proxy avec terminaison TLS devant Repod pour activer HTTPS, exposer les services sur les ports standard et durcir la surface d'attaque.

Version complète en anglais

Ce guide est une version abrégée. Consultez le guide complet en anglais → pour les configurations détaillées de Traefik, Caddy et le renouvellement de certificats.


Pourquoi un reverse proxy ?

Repod expose trois services en HTTP brut par défaut :

Service Port Description
Interface web 3003 React SPA
Backend API 8000 FastAPI — appelé directement par les navigateurs
Dépôt 80 Servi par Nginx interne

Sans reverse proxy, les identifiants et tokens circulent en clair sur le réseau.


Avant de commencer

Définir BIND_HOST=127.0.0.1 dans .env pour que les services n'écoutent que sur l'interface loopback :

.env
BIND_HOST=127.0.0.1

Redémarrer après modification : docker compose up -d


Option A — Nginx + Let's Encrypt (recommandé)

Installation

sudo apt install -y nginx certbot python3-certbot-nginx
sudo dnf install -y nginx certbot python3-certbot-nginx
sudo systemctl enable --now nginx

Obtenir le certificat

certbot --nginx -d repo.example.com

Configuration Nginx complète

/etc/nginx/sites-available/repod
# Redirection HTTP → HTTPS
server {
    listen 80;
    server_name repo.example.com;
    return 301 https://$host$request_uri;
}

# Frontend + API en HTTPS
server {
    listen 443 ssl http2;
    server_name repo.example.com;

    ssl_certificate     /etc/letsencrypt/live/repo.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/repo.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # HSTS — activer uniquement après validation HTTPS bout-en-bout
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Interface web (React SPA)
    location / {
        proxy_pass       http://127.0.0.1:3003;
        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;
    }

    # API backend — supprimer le préfixe /api avant de transmettre
    location /api/ {
        rewrite ^/api/(.*) /$1 break;
        proxy_pass         http://127.0.0.1:8000;
        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_read_timeout 300s;
        client_max_body_size 512m;
        # Requis pour les Server-Sent Events (progression import/sync)
        proxy_buffering    off;
        proxy_cache        off;
    }
}

Activer et recharger :

# Debian / Ubuntu
ln -s /etc/nginx/sites-available/repod /etc/nginx/sites-enabled/repod

nginx -t && sudo systemctl reload nginx

Option B — Certificat auto-signé (intranet / air-gapped)

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/repod.key \
  -out    /etc/ssl/certs/repod.crt \
  -subj   "/CN=repo.example.com" \
  -addext "subjectAltName=DNS:repo.example.com,IP:192.168.1.100"

Distribuer le certificat aux clients APT :

sudo cp repod.crt /usr/local/share/ca-certificates/repod.crt
sudo update-ca-certificates
echo 'Acquire::https::repo.example.com::CaInfo "/etc/ssl/certs/repod.crt";' \
  | sudo tee /etc/apt/apt.conf.d/99repod-tls

Mettre à jour la configuration Repod

Après activation du reverse proxy, mettre à jour les variables d'environnement :

.env
BIND_HOST=127.0.0.1
REACT_APP_API_URL=https://repo.example.com/api
REACT_APP_REPO_URL=http://repo.example.com
backend.env
CORS_ORIGINS=https://repo.example.com
TRUSTED_PROXIES=127.0.0.1

Reconstruire le frontend (les variables REACT_APP_* sont intégrées au build) :

docker compose build frontend-ui
docker compose up -d frontend-ui

Vérification

# Chaîne de certificat
curl -vI https://repo.example.com 2>&1 | grep -E "SSL|certificate"

# Header HSTS
curl -sI https://repo.example.com | grep -i strict-transport

# Redirection HTTP → HTTPS
curl -I http://repo.example.com

# API via HTTPS
curl -s https://repo.example.com/api/health/live | jq .