Tailscale Serve ou Funnel : lequel choisir ?
Serve garde votre URL en HTTPS dans le tailnet, tandis que Funnel l’expose sur Internet. Découvrez la policy qui bloque Funnel et comment choisir.
tailscale serve et funnel : qui peut accéder à l’URL
La différence entre tailscale serve et tailscale funnel concerne le public, et rien d’autre. serve place une interface HTTPS (hypertext transfer protocol secure) devant un port local et le publie uniquement sur votre tailnet. funnel publie ce même port local sur l’ensemble d’Internet, via les serveurs relais gérés par Tailscale. Les deux commandes acceptent les mêmes flags et les mêmes cibles. Un seul mot sépare un tableau de bord privé d’un tableau de bord accessible depuis Internet.
Dans les deux cas, vous obtenez un certificat déjà approuvé par les navigateurs, sur un nom se terminant par ts.net. Aucun des deux modes ne nécessite l’ouverture d’un port entrant dans le firewall de votre VPS. Votre daemon tailscaled maintient déjà une connexion sortante vers le tailnet. Le trafic arrive donc par cette connexion. Ajouter un serveur au tailnet est une tâche distincte. Les articles exécuter un VPS comme nœud de sortie Tailscale et annoncer un routeur de sous-réseau pour un réseau privé couvrent ce sujet. Publier un service déjà présent sur le tailnet est l’objet de cet article.
Ce qu’il vous faut avant d’exécuter l’une ou l’autre commande
- Tailscale 1.38.3 ou une version ultérieure sur le VPS, connecté à votre tailnet. Vérifiez-le avec
tailscale versionettailscale status. - MagicDNS activé. MagicDNS est le DNS intégré de Tailscale (domain name system). C’est lui qui attribue à la machine un nom tel que
blog-vps.your-tailnet.ts.net, au lieu de lui fournir uniquement une adresse100.x. - Les certificats HTTPS activés pour le tailnet, dans la page DNS de la console d’administration. Sinon, aucun certificat ne peut être placé devant votre port.
- Pour
funneluniquement, l’attribut de nœudfunneldans le fichier de stratégie du tailnet. C’est à cette étape que la plupart des premières tentatives échouent. Elle est détaillée plus bas.
Chaque commande de cette page commence par sudo, car la CLI communique avec tailscaled via un socket dans lequel seul root peut écrire. Autorisez un utilisateur à ne pas avoir à le saisir :
sudo tailscale set --operator=$USERPublier sur votre tailnet avec tailscale serve
Pointez serve vers un port local et tailscale serve s’occupe du reste.
sudo tailscale serve 3000Available within your tailnet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.La commande seule 3000 est un raccourci pour http://127.0.0.1:3000. Tailscale écoute sur le port 443 de l’adresse tailnet de la machine, termine TLS (transport layer security) avec le certificat ts.net, puis transmet les requêtes HTTP en clair vers votre port local. Votre application n’a jamais besoin de savoir qu’un certificat existe. C’est la principale raison d’utiliser cette méthode devant un panneau d’administration que vous laisseriez sinon en HTTP non chiffré.
Lisez maintenant la dernière ligne : Press Ctrl+C to exit.. La commande s’exécute au premier plan et le mapping reste dans ce processus. Fermez le terminal et l’URL cesse de fonctionner, car rien n’a été écrit sur le disque. Ajoutez --bg pour enregistrer le mapping dans la configuration serve du nœud. Cette configuration survive à la fermeture du terminal et au redémarrage.
sudo tailscale serve --bg 3000Serve accepte autre chose qu’un numéro de port. --set-path monte un service sous un sous-chemin, afin que plusieurs applications puissent partager le même hostname :
sudo tailscale serve --bg --set-path=/grafana 3000
sudo tailscale serve --bg --set-path=/metrics 9090La cible peut aussi être un répertoire de fichiers statiques ou un backend qui utilise déjà TLS avec un certificat que vous ne voulez pas vérifier :
sudo tailscale serve --bg /srv/reports
sudo tailscale serve --bg https+insecure://localhost:8443La commande ne se limite pas non plus à HTTP. --tcp=<port> transmet un flux TCP (transmission control protocol) brut, tandis que --tls-terminated-tcp=<port> termine TLS sur votre nœud et transmet ensuite le flux en clair. Vous pouvez ainsi placer un certificat de confiance devant un service qui ne parle pas du tout HTTP :
sudo tailscale serve --bg --tls-terminated-tcp=443 tcp://127.0.0.1:9899Pourquoi Funnel indique-t-il que l’attribut du nœud n’est pas défini ?
Funnel est désactivé par défaut pour l’ensemble d’un tailnet. La première exécution affiche ce message, puis s’arrête :
Funnel not available; "funnel" node attribute not set. See https://tailscale.com/kb/1223/tailscale-funnel/.La commande était correcte. La policy du tailnet n’a pas autorisé ce nœud à publier. Le client refuse donc la demande avant même de contacter un relay. Modifiez le fichier de policy du tailnet dans la console d’administration, sous Access Controls, puis ajoutez l’attribut suivant :
"nodeAttrs": [
{
"target": ["autogroup:member"],
"attr": ["funnel"],
},
],autogroup:member l’accorde à tous les membres du tailnet. Si une seule machine doit pouvoir publier, attribuez-lui un tag et ciblez plutôt ce tag, par exemple tag:public. Enregistrez la policy, puis exécutez à nouveau la commande Funnel.
Si votre compte est administrateur du tailnet, les clients récents proposent un raccourci : la CLI affiche une URL de consentement sur login.tailscale.com. En la suivant, vous activez les certificats HTTPS et ajoutez l’attribut automatiquement. Si vous n’êtes pas administrateur, cette URL ne vous sera d’aucune utilité. Une personne disposant d’un accès à la policy doit effectuer la modification.
Publier sur Internet avec Tailscale Funnel
Une fois l’attribut défini, la commande est celle que vous connaissez déjà, avec un verbe différent.
sudo tailscale funnel --bg 3000Available on the internet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.Lisez toujours cette première ligne. Available within your tailnet et Available on the internet sont les seules différences visibles entre un service privé et un service public, et les commandes qui les produisent ne diffèrent que par un mot.
En août 2026, Funnel écoute sur le port 443, 8443 ou 10000, et sur aucun autre. La valeur par défaut est 443, et --https=8443 ou --https=10000 sont les alternatives. Tout autre port est refusé, car les relais Funnel n’acceptent les connexions que sur ces ports. C’est pourquoi une URL Funnel contient toujours le nom d’hôte seul, ou le nom d’hôte suivi de :8443.
Comment voir ce qui est actuellement publié ?
Les suppositions sont la meilleure façon de laisser un tableau de bord public pendant un mois. Interrogez directement le nœud.
tailscale serve status
tailscale funnel status
tailscale serve status --jsonLes deux commandes d’état lisent la même configuration. L’une ou l’autre vous donne donc une vue d’ensemble. Utilisez la forme --json dans un script ou un contrôle planifié, car la sortie standard est destinée à être lue par des personnes. Lorsqu’aucune configuration n’existe, une seule ligne s’affiche :
No serve configSi ce résultat apparaît après une configuration qui fonctionnait, cela signifie que le mapping a été créé au premier plan, puis que le processus s’est arrêté. Recréez-le avec --bg.
Pour supprimer un mapping, répétez la commande qui l’a créé et ajoutez off à la fin. Pour supprimer tous les mappings serve et funnel du nœud, utilisez reset.
sudo tailscale funnel --https=443 3000 off
sudo tailscale serve resetExécutez de nouveau tailscale serve status après l’une ou l’autre de ces commandes et vérifiez ce qui reste, au lieu de supposer que le résultat correspond à votre intention.
Ce que vous obtenez et ce à quoi vous renoncez
Les avantages sont réels, et c’est pour cela que certains choisissent cette solution plutôt qu’un reverse proxy.
- Un certificat reconnu par les navigateurs, renouvelé automatiquement. Vous n’avez pas besoin d’installer de client ACME (automatic certificate management environment), ni de penser à configurer une tâche de renouvellement.
- Aucun port entrant à ouvrir dans le pare-feu du VPS.
tailscaledétablit la connexion vers l’extérieur. Un pare-feu ufw en deny par défaut sur votre VPS peut donc rester aussi restrictif qu’auparavant. - Aucun enregistrement DNS à acheter, à pointer ou dont il faut attendre la propagation.
- Aucun port forwarding. C’est l’essentiel lorsqu’une machine se trouve derrière un NAT (network address translation), et non sur un VPS disposant d’une IP publique.
Les coûts sont tout aussi réels, et funnel les cumule tous.
- Le nom ne vous appartient pas. Les visiteurs voient
host.your-tailnet.ts.net. Funnel ne prend pas en charge les domaines personnalisés. Vous ne pouvez donc pas placerapp.example.comdevant. - Le chemin ne vous appartient pas. Le trafic atteint d’abord un relais Tailscale, qui proxyfie le flux vers votre nœud via le tailnet. Tailscale indique que le trafic funnel est soumis à des limites de bande passante qui ne sont ni publiées ni configurables. Mesurez donc votre propre débit avant de dépendre d’une valeur précise.
- Les contrôles sont absents. Un reverse proxy que vous administrez vous donne accès aux journaux d’accès, aux limites de débit, aux limites de taille des requêtes et à un emplacement où mettre en place l’authentification. Funnel vous fournit une URL. Tout le reste doit être géré par votre application.
- La liste des ports est fixe, comme indiqué plus haut.
Les deux fonctionnalités dépendent également de l’infrastructure exploitée par Tailscale : l’émission du certificat pour le nom ts.net et les relais funnel eux-mêmes. Si vous envisagez un serveur de contrôle Headscale auto-hébergé, ne supposez pas que ces fonctionnalités vous suivent. Consultez les notes de version de la version de Headscale que vous prévoyez d’exécuter.
Lequel faut-il utiliser ?
La règle est simple.
Utilisez serve pour tout ce qui est interne : interfaces d’administration, tableaux de bord, interface de métriques que vous ne voulez pas faire indexer, copie de staging d’un site. L’appartenance au tailnet constitue le contrôle d’accès, et c’est un contrôle efficace. Un appareil qui n’est pas sur le tailnet ne peut même pas résoudre le nom.
Utilisez funnel pour un lien de démonstration, un récepteur de webhook auquel un tiers doit envoyer une requête POST ou un callback OAuth pendant le développement. C’est le moyen le plus rapide d’obtenir une URL HTTPS publique, et une seule commande off suffit pour y mettre fin. Public signifie public : le nom d’hôte n’est pas un secret, et un funnel placé devant une application sans authentification constitue un service ouvert. Tout ce qui se trouve derrière doit authentifier ses propres requêtes, avec la même rigueur que pour un endpoint d’API Ollama exposé.
Utilisez un reverse proxy réel pour tout ce que vous considérez comme de la production. Votre domaine, votre certificat, vos journaux, vos limites de débit, et aucun autre intervenant dans le chemin des requêtes. Comparaison de nginx, Caddy et Traefik comme reverse proxy explique comment en choisir un.
Modes d’échec et messages affichés
Le Funnel refuse de démarrer. Funnel not available; "funnel" node attribute not set. indique un problème de policy, pas un problème de commande. Ajoutez l’attribut funnel au fichier de policy du tailnet, enregistrez-le, puis réessayez.
La commande fonctionnait, puis tailscale serve status indique maintenant No serve config. Le mapping a été créé au premier plan, puis le processus s’est arrêté. Relancez la même commande avec --bg.
Le nom est résolu, mais aucune réponse n’arrive. Serve fait suivre les requêtes vers la cible indiquée. Si aucun processus n’écoute à cette adresse, Serve n’a rien vers quoi transmettre le trafic. Vérifiez avec ss -ltnp | grep 3000 sur la même machine que celle qui exécute tailscaled. La cause fréquente est un conteneur qui publie son port sur une adresse de bridge Docker au lieu de 127.0.0.1. Dans ce cas, l’hôte ne voit aucun processus en écoute à l’endroit attendu. Fonctionnement du réseau Docker Compose indique où un port publié est réellement attaché.
Erreurs de certificat sur le nom ts.net. Les certificats HTTPS ne sont probablement pas activés pour le tailnet. Activez-les dans la console d’administration, puis exécutez l’étape de génération du certificat séparément. Ses erreurs ne seront ainsi pas mélangées à la sortie de Serve :
sudo tailscale cert your-host.your-tailnet.ts.netLe Funnel se charge avec les données mobiles, mais son comportement diffère de celui observé depuis votre ordinateur portable. Votre ordinateur portable est connecté au tailnet. MagicDNS résout donc le nom vers l’adresse 100.x, et vous accédez directement au service sans passer par un relay. Ce comportement est normal. Il signifie que votre ordinateur portable ne peut pas tester l’accessibilité publique. Utilisez curl depuis une machine qui n’est pas connectée au tailnet.
FAQ
Quelle est la différence entre tailscale serve et tailscale funnel ?
Qui peut atteindre le résultat. tailscale serve publie un port local à une URL HTTPS accessible uniquement aux appareils de votre tailnet. tailscale funnel publie le même port à une URL accessible à toute personne sur Internet, via les serveurs relais gérés par Tailscale. Les flags et les cibles sont communs aux deux commandes. La première ligne de la sortie indique laquelle vous avez obtenue : Available within your tailnet ou Available on the internet.
Pourquoi tailscale funnel indique-t-il que l’attribut du nœud n’est pas défini ?
Parce que funnel est désactivé pour un tailnet tant qu’une personne ne l’a pas activé. Le message est Funnel not available; "funnel" node attribute not set. et provient de votre propre client, avant tout contact avec un relais. Ajoutez une entrée nodeAttrs qui accorde l’attribut funnel à autogroup:member, ou à un tag si une seule machine doit publier, dans le fichier de stratégie du tailnet, sous Access Controls. Un administrateur du tailnet peut aussi suivre l’URL de consentement affichée par la CLI.
Quels ports Tailscale Funnel peut-il utiliser ?
Uniquement 443, 8443 et 10000. La valeur par défaut est 443. Vous pouvez en choisir une autre avec --https=8443 ou --https=10000. Il s’agit d’une limite des relais Funnel, pas de votre serveur. Aucun changement de firewall ou de configuration sur le VPS ne permet donc de la supprimer. tailscale serve n’a pas cette restriction, car le trafic ne quitte jamais votre tailnet.
Une URL serve ou funnel reste-t-elle disponible après un redémarrage ?
Uniquement si vous avez utilisé --bg. Sans cette option, la commande s’exécute au premier plan, affiche Press Ctrl+C to exit., puis le mapping disparaît avec le processus. Avec --bg, le mapping est enregistré dans la configuration serve du nœud et revient avec tailscaled après un redémarrage. Vérifiez avec tailscale serve status. Cette commande affiche No serve config lorsqu’aucun réglage n’est défini.
Est-il sûr de laisser un funnel actif ?
C’est sûr du point de vue du transport : la connexion utilise HTTPS et aucun port n’est ouvert sur votre firewall. Ce n’est toutefois pas sûr au sens habituel, car l’URL est publique et l’application qui se trouve derrière l’est donc aussi. Laissez un funnel actif uniquement devant une application qui authentifie elle-même ses requêtes. Désactivez-le lorsque la démonstration ou le test du webhook est terminé, en ajoutant off à la fin de la commande qui l’a créé.
Sources concernant le comportement des commandes ci-dessus : la documentation Tailscale Serve et Funnel ainsi que la référence CLI sur tailscale.com/docs.