Accès à distance
Par défaut, SkyView n'est accessible que sur le réseau local — une fois que vous quittez votre domicile, l'application mobile ne peut plus joindre votre serveur. Ce chapitre présente trois façons d'exposer SkyView sur Internet de manière sécurisée : VPN maillé (recommandé), reverse proxy, et redirection de ports, et explique les ports nécessaires pour chacune.
À lire en premier
0.0.0.0 sans aucune règle de pare-feu intégrée. Exposer des ports nus sur Internet revient à laisser n'importe quel scanner de la planète atteindre vos caméras. Tout schéma d'accès à distance doit être associé à HTTPS + un mot de passe fort, et éviter autant que possible une exposition publique nue.Choisir parmi les trois méthodes
| Méthode | Sécurité | Difficulté | Exposition publique | Idéal pour |
|---|---|---|---|---|
| VPN maillé | La plus élevée | Faible | Non | La grande majorité des utilisateurs domestiques (recommandé) |
| Reverse proxy + domaine | Moyenne | Moyenne | Oui (443 uniquement) | Vous voulez un nom de domaine, ou envoyer un lien à des proches qui ne peuvent pas facilement installer l'application |
| Redirection de ports | Faible | Faible | Oui (exposition nue) | Non recommandé ; uniquement temporaire / si vous comprenez parfaitement le risque |
En cas de doute, utilisez le VPN maillé : n'ouvrez aucun port sur le routeur, n'achetez aucun nom de domaine, ne configurez aucun certificat — sécurité maximale et administration quasi nulle. Les trois sections ci-dessous détaillent chaque méthode.
Méthode 1 : VPN maillé (recommandé)
Les outils de maillage (Tailscale / WireGuard / ZeroTier, etc.) créent un tunnel chiffré entre votre téléphone et votre serveur domestique, de sorte que le téléphone accède à SkyView via l'adresse interne exactement comme à la maison — aucun port à ouvrir sur le routeur, et le serveur n'est absolument pas exposé sur Internet.
- 1
Installer le client de maillage sur le serveur
Installez Tailscale sur la machine exécutant SkyView (ou un routeur logiciel sur le même réseau local), puis exécutez
tailscale uppour vous connecter. WireGuard / ZeroTier fonctionnent de façon similaire.bashcurl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up - 2
Installer la même application sur votre téléphone et vous connecter au même compte
Installez l'application Tailscale / ZeroTier correspondante sur le téléphone et connectez-vous avec le même compte que le serveur ; les deux extrémités se trouvent désormais sur le même réseau local virtuel.
- 3
Saisir l'adresse de maillage dans l'application
Définissez l'adresse du serveur dans l'application SkyView sur l'IP attribuée par le maillage — Tailscale utilise
100.x.x.x, ZeroTier utilise10.x.x.x— le port reste:23406, par ex.http://100.x.x.x:23406. - 4
Terminé
Une fois à l'extérieur, le téléphone peut y accéder même en 4G/5G, exactement comme à la maison. Aucune IP publique, aucun nom de domaine, aucun certificat HTTPS n'est nécessaire.
Pourquoi le VPN maillé est la recommandation numéro un
Méthode 2 : reverse proxy + nom de domaine
Si vous disposez d'une IP publique + d'un nom de domaine et souhaitez y accéder via une adresse du type https://cam.example.com (pratique pour l'envoyer à des proches qui ne peuvent pas facilement installer l'application de maillage), vous pouvez placer une couche nginx / Caddy devant SkyView pour la terminaison HTTPS. Le conteneur SkyView inclut déjà une couche nginx en interne, le proxy externe n'a donc qu'à rediriger tout le trafic vers :23406.
Un seul port à rediriger
:23406. Le proxy externe ne redirige que ce seul port — n'exposez pas séparément les ports 24214 / 24215 de mediamtx. La vidéo WebRTC en direct utilise l'UDP :23515, qui ne passe pas par le proxy, mais sur Internet ce chemin UDP ne peut généralement pas être établi — la vue en direct sur Internet bascule automatiquement sur HLS, donc ne pas rediriger 23515 ne pose pas de problème ; voir la remarque à la fin de la « Méthode 2 » ci-dessous.Configuration nginx
Enregistrez le contenu ci-dessous intégralement sous /etc/nginx/sites-available/skyview.conf, remplacez <your-domain>, puis créez un lien symbolique (ln -s) vers sites-enabled/ — un seul fichier suffit, aucun extrait séparé n'est nécessaire. Les blocs proxy_set_header des deux location / sont identiques : le proxy_set_header de nginx écrase au lieu d'hériter, donc chaque location doit porter sa propre copie — copiez-le simplement tel quel.
# Transmission de l'en-tête WebSocket Upgrade — doit être dans le contexte http {}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name <your-domain>;
# certbot --nginx réécrira ce bloc en redirection 301 vers https
location / {
proxy_pass http://127.0.0.1:23406;
proxy_http_version 1.1;
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-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme; # ★ Si omis, les déploiements HTTPS tombent dans une boucle de connexion
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_connect_timeout 60s;
proxy_send_timeout 1d;
proxy_read_timeout 1d;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name <your-domain>;
ssl_certificate /etc/letsencrypt/live/<your-domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<your-domain>/privkey.pem;
# Les exports d'enregistrements et les imports groupés de la bibliothèque de visages peuvent faire plusieurs centaines de Mo ; les cookies JWT longs sont volumineux, évite les erreurs 414
client_max_body_size 200m;
client_header_buffer_size 4k;
large_client_header_buffers 8 16k;
location / {
proxy_pass http://127.0.0.1:23406;
proxy_http_version 1.1;
# ↓ Identique à la location :80 ci-dessus, copiez ligne par ligne (proxy_set_header n'hérite pas)
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-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_connect_timeout 60s;
proxy_send_timeout 1d;
proxy_read_timeout 1d;
}
}X-Forwarded-Proto / X-Forwarded-Host doivent être transmis et inclus dans chaque location
X-Forwarded-Proto pour connaître le schéma réel du client et sur X-Forwarded-Host pour connaître le domaine externe. Omettre X-Forwarded-Proto → sur les déploiements HTTPS, vous êtes renvoyé à la page de connexion juste après vous être connecté, et la vue en direct est bloquée par le navigateur en tant que contenu mixte (Mixed Content) ; omettre X-Forwarded-Host → les liens de lecture / téléchargement / export d'enregistrements sont construits avec de mauvaises adresses et le client ne peut pas les ouvrir. Le modèle nginx ci-dessus et Caddy (qui transmet ces deux en-têtes par défaut) couvrent tous les deux ce cas — il suffit de le copier. Vous n'avez pas besoin de définir X-Forwarded-Port manuellement ; le nginx du conteneur gère automatiquement les scénarios « reverse proxy externe / accès direct par IP nue ». De plus, le proxy_set_header de nginx écrase au lieu d'ajouter : si une location en écrit ne serait-ce qu'un seul, tous les set_header du niveau supérieur cessent de s'appliquer — chaque location doit donc include l'extrait complet.Obtenez un certificat (la machine doit être joignable depuis Internet sur le port :80) :
certbot --nginx -d <your-domain> -m <your-email> --agree-tos --no-eff-email --redirectConfiguration Caddy (plus simple)
Caddy émet / renouvelle automatiquement les certificats Let's Encrypt sans certbot, et la configuration est bien plus courte. /etc/caddy/Caddyfile :
<your-domain> {
reverse_proxy 127.0.0.1:23406 {
# Caddy transmet X-Forwarded-{For,Proto,Host} par défaut
# Pour les connexions longue durée (WS de conversation / SSE d'événements / flux en direct), augmentez flush + les délais d'expiration
flush_interval -1
transport http {
read_timeout 24h
write_timeout 24h
}
}
request_body {
max_size 200MB
}
}La vue en direct sur Internet utilise HLS — ne vous souciez pas de WebRTC
443/tcp vers le 443 de la machine proxy. `23515/udp` n'a pas besoin d'être redirigé : le direct WebRTC à faible latence repose sur le fait que mediamtx annonce des adresses de candidats ICE « joignables », mais SkyView n'annonce par défaut que des adresses du réseau local (webrtcAdditionalHosts et le STUN nécessaires à la traversée NAT publique ne sont pas configurés), donc sous un NAT domestique, le client externe ne peut pas obtenir de canal WebRTC utilisable, et rediriger 23515 ne sert à rien. La vue en direct sur Internet se dégrade automatiquement vers HLS (~3 secondes de latence, pleinement fonctionnel) ; pour la faible latence à démarrage instantané de WebRTC, utilisez la Méthode 1, VPN maillé — sur un maillage, le téléphone est traité comme étant sur le réseau local et WebRTC fonctionne normalement.Méthode 3 : redirection de ports (non recommandée)
Comprendre le risque avant utilisation
23406 nu, c'est du HTTP en clair — les mots de passe et le flux ne sont pas chiffrés de bout en bout, et les navigateurs ainsi qu'Android 9+ refusent les requêtes HTTP en clair pour les permissions caméra. Ne l'envisagez que si vous comprenez parfaitement le risque et que c'est temporaire ; pour un usage à long terme, passez au VPN maillé ou à un reverse proxy.Si vous tenez absolument à la redirection de ports, nous recommandons vivement d'exécuter aussi une couche de reverse proxy sur l'hôte SkyView pour le HTTPS (voir Méthode 2), en redirigeant le port public 443 vers le proxy plutôt que d'exposer 23406 nu. Les ports à rediriger :
| Port public | → interne | Protocole | Remarques |
|---|---|---|---|
| 443 | Hôte proxy 443 | TCP | Faites le HTTPS via le proxy, puis redirigez vers 23406 (approche recommandée) |
| 23406 | Hôte SkyView 23406 | TCP | Le port redirigé nu sans proxy, HTTP en clair, non recommandé |
Ne jamais rediriger 24214 / 24215
23406 avec un jeton live-grant. Exposer nus sur Internet les ports 24214 (HLS) / 24215 (signalisation WebRTC) de mediamtx contourne l'authentification par jeton et constitue une faille de sécurité. Le fichier mediamtx.yml du conteneur restreint déjà ces deux ports à 127.0.0.1 uniquement.Aide-mémoire des ports
| Port | Protocole | Usage | Ouvert sur Internet ? |
|---|---|---|---|
| 23406 | TCP | Web Admin + API + proxy à jeton pour le flux en direct (seul point d'entrée HTTP) | Requis (avec un proxy, vous redirigez le 443) |
| 23515 | UDP | Flux média WebRTC de la vue en direct (fonctionne sur le réseau local / maillage) | Inutile (le direct sur Internet utilise automatiquement HLS) |
| 23880 | TCP | RTSP de mediamtx, pour que les caméras / lecteurs externes se connectent directement | Inutile |
| 24214 | TCP | HLS de mediamtx (127.0.0.1 uniquement) | Interdit |
| 24215 | TCP | Signalisation WebRTC de mediamtx (127.0.0.1 uniquement) | Interdit |
Comment vérifier après la configuration
# 1. Redirection HTTP→HTTPS (scénario reverse proxy)
curl -sSI http://<your-domain>/healthz | head -1 # attendu : 301
# 2. Vérification de santé
curl -sS https://<your-domain>/healthz # attendu : {"code":0,...}
# 3. Accéder à un point de terminaison protégé sans être connecté
curl -sS -o /dev/null -w '%{http_code}\n' \
https://<your-domain>/api/cameras # attendu : 401Enfin, parcourez tout le flux dans un navigateur : connexion → voir le flux en direct → aucune erreur de contenu mixte (Mixed Content) dans la console du navigateur. Si vous êtes renvoyé à la page de connexion juste après vous être connecté, ou si la vue en direct signale du Mixed Content, c'est dans 99 % des cas que X-Forwarded-Proto n'a pas été transmis correctement. Pour plus de dépannage, consultez Dépannage.