Joindre le relais par un tunnel SSH
Le relais peut ouvrir une connexion SSH vers un serveur à vous et demander à ce serveur
de lui renvoyer un port. Vous joignez alors le relais à l’adresse du serveur,
et rien chez vous n’écoute internet. Le relais démarre,
surveille et redémarre lui-même le processus ssh.
Choisissez cette solution quand vous avez déjà un serveur avec une adresse publique et un accès SSH. Si vous n’avez pas de serveur, le Cloudflare Tunnel intégré n’en demande aucun.
Ce qu’il vous faut #
- L’hôte du relais a un programme
sshdans sonPATH(ou vous en désignez un autre aveccommand, voir plus bas). - Une connexion SSH au serveur qui fonctionne avec une clé et sans invite. Le
relais lance
sshen mode batch ; il ne peut donc saisir ni mot de passe ni phrase de passe de clé. Une clé avec phrase de passe ne fonctionne que si un agent SSH la détient. Testez d’abord depuis l’hôte du relais :ssh relay@relay.doit se connecter sans rien demander.example. com - Un port libre sur le serveur pour le tunnel (
remote).Port - Quelque chose sur le serveur qui sert ce port en HTTPS : un serveur web ou un proxy inverse comme Caddy ou nginx. Le tunnel transporte du HTTP en clair ; sans cela, votre token et vos conversations traversent internet sans chiffrement dès que le port est joignable. Voir Faire tourner le relais derrière un proxy inverse.
Le relais n’a besoin d’aucun réglage sshd particulier. Avec remote à loopback, il
demande le transfert sans adresse de liaison ; c’est donc le réglage Gateway
du serveur qui décide où le port s’ouvre. À sa valeur par défaut, no, c’est le serveur
lui-même seulement, et le proxy inverse est la seule chose exposée à internet.
Avec public, le relais demande toutes les interfaces (*:), et cette demande
ne prend effet que si le sshd du serveur l’autorise (Gateway réglé sur
clientspecified ou yes).
La mise en place #
Ajoutez un bloc ssh à config. (voir
Où se trouve le fichier) et redémarrez le
relais avec oar restart.
"sshTunnel": {
"mode": "managed",
"required": false,
"user": "relay",
"host": "relay.example.com",
"remotePort": 4444,
"remoteBind": "loopback",
"identityFile": "~/.ssh/id_ed25519"
}
Sur le serveur, envoyez le HTTPS vers le port du tunnel. Avec Caddy :
relay.example.com {
reverse_proxy localhost:4444
}
Ouvrez https:// dans un navigateur et connectez-vous avec votre token
d’accès. La bannière de démarrage du relais affiche une ligne Remote: et oar url
affiche une ligne Tunnel URL: avec un QR code. Les deux valent https:// suivi de la valeur de host,
sans port et sans vérifier que le tunnel est actif ; elles ne sont donc justes que
si votre proxy sert HTTPS sur le port standard.
Les clés sshTunnel #
Toutes les clés se trouvent dans le bloc ssh. Le tableau concorde avec
config.json, qui a la même liste.
| Clé | Type | Par défaut | Ce qu’elle fait |
|---|---|---|---|
mode |
"disabled" ou "managed" |
"disabled" |
managed fait démarrer et redémarrer le tunnel par le relais. |
user |
chaîne | aucune | L’utilisateur SSH sur le serveur. Obligatoire en mode géré. |
host |
chaîne | aucune | Le nom d’hôte ou l’adresse du serveur. Obligatoire en mode géré. |
remote |
nombre | aucune | Le port qui s’ouvre sur le serveur, de 1 à 65535. Obligatoire en mode géré. |
remote |
"loopback" ou "public" |
"loopback" |
loopback demande le port sans adresse de liaison (le Gateway du serveur décide, voir Ce qu’il vous faut) ; public demande toutes les interfaces. Toute autre valeur compte comme loopback. Indépendant de localhost. |
identity |
chaîne | aucune | Le fichier de clé privée ; ~ est développé. Sans lui, ssh utilise votre agent et ses clés par défaut. |
command |
chaîne | ssh |
Le programme SSH, utilisé aussi pour le nettoyage sur le serveur. Un nom est cherché dans le PATH ; un chemin avec une barre oblique est utilisé tel quel, et un chemin relatif part du dossier du programme du relais. |
required |
booléen | false |
Tant que le tunnel n’est pas connecté, le relais ne prend aucun message dans la queue. Voir Requis. |
auto |
booléen | true |
Quand le port distant est déjà occupé, lancer un nettoyage sur le serveur et réessayer. Seul false le désactive. |
reclaim |
booléen | false |
Dans le cadre de ce nettoyage, mettre fin aussi à vos propres sessions SSH inactives sur le serveur. |
remote |
chaîne | intégrée | Votre propre commande de nettoyage, lancée sur le serveur à la place de celle intégrée. |
L’ancienne forme "enabled": true fonctionne encore et signifie "mode": "managed", mais
seulement quand mode n’est pas réglé sur disabled ou managed.
Le relais transfère le remote du serveur vers son propre port sur 127.
(3333 sauf si vous avez modifié port). Avec public, le transfert est demandé sous la forme
*:, sinon sous la forme remote.
Ces réglages sont fixes et n’ont pas de clé : le relais lance ssh -N avec
Server, Server, Batch,
Strict et Exit. ssh abandonne
une connexion après trois vérifications sans réponse, espacées de 30 secondes.
Si une valeur obligatoire manque (user, host ou un remote valide en
mode géré), le relais démarre normalement, indique dans le journal laquelle, et laisse le tunnel
désactivé.
Son comportement #
Démarrage. Le relais démarre le tunnel dès qu’il écoute. Il considère le
tunnel comme connecté quand ssh tourne depuis 1,2 seconde et que le serveur n’a pas
refusé le transfert. Le journal indique alors Tunnel up to user@host remote port N.
Reconnexion. Quand ssh se termine, le relais le relance après une attente qui
s’allonge : 5, 10, 20, 40 puis 60 secondes, et reste à 60. Le compte repart de zéro
quand une connexion qui a duré plus de 30 secondes tombe. Arrêter le relais
arrête le tunnel et les nouvelles tentatives.
Clés d’hôte. Un serveur que l’hôte du relais n’a jamais vu est accepté et
mémorisé à la première connexion. Ensuite, une clé d’hôte modifiée fait que ssh
refuse de se connecter tant que vous n’avez pas retiré l’ancienne entrée de known_.
Requis #
Avec required: true, la queue reste en pause du démarrage jusqu’à ce que le tunnel soit
connecté, et de nouveau chaque fois qu’il tombe. Les messages que vous envoyez attendent dans la queue et
partent une fois le tunnel actif. Utilisez-le quand le relais ne vous sert à rien sans le
tunnel. Un tunnel qui ne peut pas démarrer à cause d’une valeur manquante maintient aussi la queue
en pause.
Quand le port distant est occupé #
Si le serveur dit que le port ne peut pas être lié, la cause habituelle est une session
restante d’un tunnel précédent dont le serveur n’a pas remarqué qu’elle était morte. Sauf si
auto vaut false, le relais se connecte alors une seconde fois au serveur
et y lance une commande de nettoyage.
Ces options lancent des commandes sur votre serveur
Le nettoyage tourne sous votre connexion SSH et tue des processus. Il met fin à tout
processus de cet utilisateur qui écoute sur le port distant, qu’il s’agisse ou non d’un
tunnel restant. Avec reclaim, il met aussi fin à chaque session SSH
inactive de cet utilisateur, ce qui inclut d’autres tunnels ssh -N -R de la même
connexion sur d’autres ports. remote lance tout ce que vous écrivez. Lisez ce que
fait chaque étape avant de les laisser activées.
Le nettoyage intégré fait ceci, dans l’ordre :
- Il vérifie si le port est utilisé (avec
ss, ou à défaut en lisant la liste des sockets en écoute du noyau). Sinon, il s’arrête et signale un succès. - Il trouve les processus qui écoutent sur le port (avec
lsof, ou à défautfuser, selon ce qui existe), leur envoie un signal de terminaison (kill) et attend une seconde. Un processus auquel votre connexion n’a pas le droit d’envoyer de signal reste. Si le port est maintenant libre, il signale un succès. - Seulement avec
reclaim, et seulement si le port est encore utilisé : il envoie un signal de terminaison à chaque sessionStale Ssh Sessions: true sshdde votre utilisateur qui n’a pas de processus enfant, puis attend une seconde. Ce sont les sessions qu’unssh -N -Rlaisse derrière lui. Les sessions qui font tourner un shell, le serveur distant d’un éditeur ou tout autre programme ont des enfants et sont ignorées, de même que la session qui exécute le nettoyage lui-même. - Si le port est encore utilisé, le nettoyage se termine avec le code 3, que le relais
journalise comme
is still held.
Quand remote est réglée, votre commande tourne à la place de tout cela, et
reclaim n’a aucun effet. Le relais la lance sous la forme sh -lc '<command>' par une
seconde connexion ssh avec la même clé, en mode batch. Elle doit se terminer avec 0 quand le port est libre et avec un autre code quand il
est encore occupé.
Après un nettoyage qui a libéré le port, le relais réessaie au bout d’une seconde, jusqu’à
trois fois de suite. Après un nettoyage qui a échoué, ou avec auto désactivé, il
utilise l’attente normale décrite plus haut.
Voir l’état du tunnel #
Le tunnel SSH n’apparaît pas aux endroits où apparaît le tunnel Cloudflare :
oar status et oar doctor ne signalent que le tunnel Cloudflare, et la pastille
d’état ne passe pas à l’ambre pour un tunnel SSH (voir
La pastille d’état). Regardez plutôt ici :
- Le journal du relais. Chaque ligne commence par
[ssh-. Il montre la ligne de commandetunnel] sshlancée, ce quesshaffiche,Tunnel up to ...,Reconnecting in Ns (attempt N)...et les étapes de récupération du port. L’emplacement du journal dépend de la façon dont le relais tourne ; voir Fichiers et dossiers. - La bannière de démarrage, avec une ligne
Remote:et une ligneTunnel: mode=(ouloopback public) quand le tunnel géré est configuré. Elles montrent la configuration, pas si le tunnel est actif.oar urlaffiche la même adresse sous la formeTunnel URL:. /, qui contient un objetapi/ status sshavecTunnel connected,connected,Since reconnect,Attempts last,Error blocking,required,mode,valid,host,remoteetPort remote. Récupérez-le avec votre token.Bind Mode
last vaut exit:<code> après la fin de ssh, remote-
après que le serveur a refusé le port, invalid- ou le message de valeur manquante
quand le bloc est incomplet, et il est vide tant que le tunnel est actif.
Sécurité #
Une fois le tunnel actif, le relais est joignable depuis internet, et le token d’accès est tout ce qui se dresse entre un inconnu et vos agents, qui exécutent des commandes sur votre machine. Donc :
- Gardez
remoteàBind loopbacket placez HTTPS devant, sur le serveur. Avecpublic, quiconque peut joindre le port du tunnel sur le serveur joint le relais en HTTP en clair. - Le token d’accès est le seul verrou. Voir Le token d’accès et qui peut joindre le relais et Ce qu’OAR expose.
- Le relais refuse les requêtes vers ses chemins internes de worker de session quand elles
portent l’en-tête marqueur de Cloudflare
cf-ou un en-tête que vous listez dansray tunnel. Un simple proxy inverse n’en ajoute aucun ; listez donc l’en-tête qu’ajoute votre proxy, s’il en ajoute un que vous voulez faire bloquer. Voir config.json.Marker Headers
Dépannage #
Regardez d’abord les lignes [ssh- du journal. Les lignes commençant par stderr:
sont ce que ssh lui-même a affiché.
| Vous voyez | Ce que cela signifie | Que faire |
|---|---|---|
ssh (de même pour host) |
Une valeur obligatoire manque. Le tunnel reste désactivé. | Réglez-la et lancez oar restart. |
ssh |
Le port manque ou n’est pas un nombre de 1 à 65535. | Corrigez-le et redémarrez. |
Tunnel mode disabled; running direct relay only. |
mode n’est pas managed. |
Réglez "mode": "managed". |
stderr: ... Permission denied (publickey) |
Le serveur n’a pas accepté votre clé. En mode batch, il n’y a pas d’invite de mot de passe. | Réglez identity, et testez à la main le même ssh user@host sur l’hôte du relais. |
Process exited (code= qui se répète |
ssh n’a pas pu se connecter ou s’authentifier. |
Lancez à la main la commande ssh journalisée et lisez son erreur. |
stderr: ... remote port forwarding failed for listen port N, puis Attempting remote reclaim ... |
Le port est utilisé sur le serveur. | Attendez la récupération. Si elle se termine par is still held, libérez le port vous-même ou choisissez un autre remote. |
Remote reclaim finished: listen port N is still held (code= |
Le nettoyage n’a pas pu libérer le port. | Trouvez qui l’occupe sur le serveur, essayez reclaim, ou réglez remote. |
stderr: ... Host key verification failed ou REMOTE HOST IDENTIFICATION HAS CHANGED |
La clé du serveur diffère de celle enregistrée. | Si le changement est attendu, retirez l’ancienne entrée de known_. Sinon, ne vous connectez pas. |
Reconnecting in 60s (attempt N) encore et encore, et le tunnel n’indique jamais Tunnel up |
La connexion échoue à chaque fois. | Lisez les lignes stderr: qui précèdent chacune. |
Le tunnel indique Tunnel up mais l’adresse ne répond pas |
Le côté relais va bien ; le côté serveur non. | Vérifiez que le proxy inverse tourne et pointe vers le remote, et que remote correspond à la façon dont le proxy le joint. |
| Le tunnel se connecte, tombe et se reconnecte en boucle | Quelque chose sur le serveur ou le réseau met fin à la connexion. | Le journal montre le code de sortie et les messages de ssh. Consultez le journal sshd du serveur. |
| Les messages restent en file | required vaut true et le tunnel n’est pas connecté. |
Réparez le tunnel, ou passez required à false. |