Das Relay über einen SSH-Tunnel erreichen
Das Relay kann eine SSH-Verbindung zu einem deiner Server öffnen und diesen
Server bitten, einen Port zurück an das Relay weiterzuleiten. Du erreichst das
Relay dann unter der Adresse des Servers, und zu Hause lauscht nichts in
Richtung Internet. Das Relay startet, überwacht und startet den ssh-Prozess
selbst neu.
Nimm das, wenn du schon einen Server mit öffentlicher Adresse und SSH-Zugang hast. Hast du keinen Server, braucht der eingebaute Cloudflare Tunnel keinen.
Was du brauchst #
- Der Relay-Host hat ein
ssh-Programm in seinemPATH(oder du nennst mitcommandein anderes, siehe unten). - Eine SSH-Anmeldung auf dem Server, die mit einem Key und ohne Nachfrage
funktioniert. Das Relay führt
sshim Batch-Modus aus und kann daher weder ein Passwort noch eine Key-Passphrase eintippen. Ein Key mit Passphrase funktioniert nur, wenn ein SSH-Agent ihn hält. Teste es zuerst vom Relay-Host aus:ssh relay@relay.muss sich anmelden, ohne etwas zu fragen.example. com - Einen freien Port auf dem Server für den Tunnel (
remote).Port - Etwas auf dem Server, das diesen Port über HTTPS ausliefert: einen Webserver oder Reverse Proxy wie Caddy oder nginx. Der Tunnel trägt einfaches HTTP; ohne das gehen dein Token und deine Konversationen unverschlüsselt durchs Internet, sobald der Port erreichbar ist. Siehe Das Relay hinter einem Reverse Proxy betreiben.
Das Relay braucht keine besondere sshd-Einstellung. Mit remote auf
loopback fordert es die Weiterleitung ohne Bind-Adresse an, sodass die
eigene Einstellung Gateway des Servers entscheidet, wo sich der Port
öffnet. Beim Standard no ist das nur der Server selbst, und der Reverse Proxy
ist das Einzige, was zum Internet hin offen ist. Mit public fordert das Relay
alle Schnittstellen an (*:), und diese Anforderung wirkt nur, wenn das sshd
des Servers sie erlaubt (Gateway auf clientspecified oder yes).
Einrichten #
Füge einen Block ssh in config. ein (siehe
Wo die Datei liegt) und starte das
Relay mit oar restart neu.
"sshTunnel": {
"mode": "managed",
"required": false,
"user": "relay",
"host": "relay.example.com",
"remotePort": 4444,
"remoteBind": "loopback",
"identityFile": "~/.ssh/id_ed25519"
}
Leite auf dem Server HTTPS an den Tunnel-Port. Mit Caddy:
relay.example.com {
reverse_proxy localhost:4444
}
Öffne https:// in einem Browser und melde dich mit deinem
Zugriffstoken an. Das Startbanner des Relays gibt eine Zeile Remote: aus, und oar url
gibt eine Zeile Tunnel URL: mit QR-Code aus. Beide sind https:// plus der
Wert von host, ohne Port und ohne Prüfung, ob der Tunnel steht; sie stimmen
also nur, wenn dein Proxy HTTPS auf dem Standardport ausliefert.
Die Keys von sshTunnel #
Alle Keys stehen im Block ssh. Die Tabelle stimmt mit
config.json überein, wo dieselbe
Liste steht.
| Key | Typ | Standard | Was er tut |
|---|---|---|---|
mode |
"disabled" oder "managed" |
"disabled" |
Mit managed startet das Relay den Tunnel und startet ihn neu. |
user |
String | keiner | Der SSH-Benutzer auf dem Server. Pflicht bei managed. |
host |
String | keiner | Der Hostname oder die Adresse des Servers. Pflicht bei managed. |
remote |
Zahl | keiner | Der Port, der sich auf dem Server öffnet, 1 bis 65535. Pflicht bei managed. |
remote |
"loopback" oder "public" |
"loopback" |
loopback fordert den Port ohne Bind-Adresse an (Gateway des Servers entscheidet, siehe Was du brauchst); public fordert alle Schnittstellen an. Jeder andere Wert zählt als loopback. Unabhängig von localhost. |
identity |
String | keiner | Die Datei mit dem privaten Key; ~ wird aufgelöst. Ohne sie nutzt ssh deinen Agent und seine Standard-Keys. |
command |
String | ssh |
Das SSH-Programm, auch für das Aufräumen auf dem Server. Ein Name wird im PATH gesucht; ein Pfad mit Schrägstrich wird so genommen, wie er ist, und ein relativer zählt vom Programmordner des Relays aus. |
required |
Boolean | false |
Solange der Tunnel nicht verbunden ist, nimmt das Relay keine Nachrichten aus der Queue. Siehe Pflicht. |
auto |
Boolean | true |
Ist der Remote-Port schon belegt, auf dem Server aufräumen und es erneut versuchen. Nur false schaltet das ab. |
reclaim |
Boolean | false |
Beim Aufräumen außerdem deine eigenen untätigen SSH-Sessions auf dem Server beenden. |
remote |
String | eingebaut | Dein eigener Aufräumbefehl, der auf dem Server statt des eingebauten läuft. |
Die alte Form "enabled": true funktioniert weiterhin und bedeutet
"mode": "managed", aber nur, wenn mode nicht auf disabled oder managed
gesetzt ist.
Das Relay leitet den remote des Servers an seinen eigenen Port auf
127. weiter (3333, sofern du port nicht geändert hast). Mit public
wird die Weiterleitung als *: angefordert, sonst als remote.
Diese Einstellungen sind fest und haben keine Keys: Das Relay führt ssh -N
mit Server, Server, Batch,
Strict und Exit aus. ssh
gibt eine Verbindung nach drei unbeantworteten Prüfungen im Abstand von
30 Sekunden auf.
Fehlt ein Pflichtwert (user, host oder ein gültiger remote im Modus
managed), startet das Relay wie gewohnt, schreibt ins Log, welcher es ist, und
lässt den Tunnel aus.
Wie er sich verhält #
Start. Das Relay startet den Tunnel, sobald es lauscht. Es zählt den Tunnel
als verbunden, wenn ssh 1,2 Sekunden gelaufen ist und der Server die
Weiterleitung nicht abgelehnt hat. Das Log sagt dann
Tunnel up to user@host remote port N.
Neu verbinden. Wenn ssh endet, startet das Relay es nach einer wachsenden
Wartezeit neu: 5, 10, 20, 40 und dann 60 Sekunden, und bleibt bei 60. Die
Zählung beginnt von vorn, sobald eine Verbindung abbricht, die länger als
30 Sekunden gehalten hat. Wird das Relay gestoppt, stoppen auch der Tunnel und
die Wiederholungen.
Host-Keys. Ein Server, den der Relay-Host noch nie gesehen hat, wird bei
der ersten Verbindung akzeptiert und gemerkt. Danach lässt ein geänderter
Host-Key ssh die Verbindung verweigern, bis du den alten Eintrag aus
known_ entfernst.
Pflicht #
Mit required: true bleibt die Queue vom Start an pausiert, bis der Tunnel
verbunden ist, und erneut, sobald er abbricht. Nachrichten, die du schickst,
warten in der Queue und laufen, sobald der Tunnel steht. Nutze das, wenn das
Relay ohne den Tunnel für dich nutzlos ist. Ein Tunnel, der wegen eines
fehlenden Werts nicht starten kann, hält die Queue ebenfalls pausiert.
Wenn der Remote-Port belegt ist #
Sagt der Server, dass der Port nicht gebunden werden kann, ist die übliche
Ursache eine übrig gebliebene Session eines früheren Tunnels, bei der der Server
nicht bemerkt hat, dass sie tot ist. Sofern auto nicht false
ist, verbindet sich das Relay dann ein zweites Mal mit dem Server und führt
dort einen Aufräumbefehl aus.
Diese Optionen führen Befehle auf deinem Server aus
Das Aufräumen läuft unter deiner SSH-Anmeldung und beendet Prozesse. Es beendet
jeden Prozess dieses Benutzers, der auf dem Remote-Port lauscht, ob es ein
übrig gebliebener Tunnel ist oder nicht. Mit reclaim beendet
es außerdem jede untätige SSH-Session dieses Benutzers, darunter auch andere
ssh -N -R-Tunnel derselben Anmeldung auf anderen Ports.
remote führt aus, was immer du hineinschreibst. Lies, was jeder
Schritt tut, bevor du sie eingeschaltet lässt.
Das eingebaute Aufräumen tut Folgendes, in dieser Reihenfolge:
- Es prüft, ob der Port belegt ist (mit
ss, sonst durch Lesen der Liste lauschender Sockets im Kernel). Wenn nicht, hört es auf und meldet Erfolg. - Es sucht die Prozesse, die auf dem Port lauschen (mit
lsof, sonstfuser, je nachdem, was vorhanden ist), schickt ihnen ein Beendigungssignal (kill) und wartet eine Sekunde. Ein Prozess, dem deine Anmeldung kein Signal schicken darf, bleibt. Ist der Port jetzt frei, meldet es Erfolg. - Nur mit
reclaimund nur, wenn der Port noch belegt ist: Es schickt jederStale Ssh Sessions: true sshd-Session deines Benutzers ohne Kindprozesse ein Beendigungssignal und wartet dann eine Sekunde. Das sind die Sessions, die einssh -N -Rhinterlässt. Sessions, in denen eine Shell, der Remote-Server eines Editors oder ein anderes Programm läuft, haben Kindprozesse und werden übersprungen, ebenso die Session, in der das Aufräumen selbst läuft. - Ist der Port immer noch belegt, endet das Aufräumen mit Code 3, was das
Relay als
is still heldprotokolliert.
Ist remote gesetzt, läuft dein Befehl statt all dessen, und
reclaim hat keine Wirkung. Das Relay führt ihn als sh -lc '<command>' über eine
zweite ssh-Anmeldung mit demselben Key im Batch-Modus aus. Er muss mit 0 enden, wenn der Port frei ist, und mit einem anderen Code, wenn er
noch belegt ist.
Nach einem Aufräumen, das den Port freigegeben hat, versucht es das Relay nach
einer Sekunde erneut, bis zu dreimal hintereinander. Nach einem fehlgeschlagenen
Aufräumen oder mit abgeschaltetem auto nutzt es die normale
Wartezeit oben.
Den Zustand des Tunnels sehen #
Der SSH-Tunnel wird nicht an den Stellen angezeigt, an denen der Cloudflare
Tunnel erscheint: oar status und oar doctor melden nur den Cloudflare Tunnel, und der
Statuspunkt wird für einen SSH-Tunnel nicht bernsteinfarben (siehe
Der Statuspunkt). Sieh stattdessen hier nach:
- Im Log des Relays. Jede Zeile beginnt mit
[ssh-. Es zeigt dietunnel] ssh-Befehlszeile, die es ausführt, wassshausgibt,Tunnel up to ...,Reconnecting in Ns (attempt N)...und die Aufräumschritte. Wo das Log liegt, hängt davon ab, wie das Relay läuft; siehe Dateien und Ordner. - Im Startbanner, mit einer Zeile
Remote:und einer ZeileTunnel: mode=(oderloopback public), wenn der verwaltete Tunnel eingerichtet ist. Sie zeigen die Konfiguration, nicht, ob der Tunnel steht.oar urlgibt dieselbe Adresse alsTunnel URL:aus. - In
/, mit einem Objektapi/ status sshmitTunnel connected,connected,Since reconnect,Attempts last,Error blocking,required,mode,valid,host,remoteundPort remote. Ruf es mit deinem Token ab.Bind Mode
last ist exit:<code>, nachdem ssh geendet hat,
remote-, nachdem der Server den Port abgelehnt hat,
invalid- oder die Meldung zum fehlenden Wert, wenn der Block
unvollständig ist, und leer, solange der Tunnel steht.
Sicherheit #
Sobald der Tunnel steht, ist das Relay aus dem Internet erreichbar, und nur das Zugriffstoken steht zwischen einem Fremden und deinen Agents, die Befehle auf deinem Rechner ausführen. Deshalb:
- Lass
remoteaufBind loopbackund stell auf dem Server HTTPS davor. Mitpublicerreicht jeder, der den Tunnel-Port des Servers erreicht, das Relay über einfaches HTTP. - Das Zugriffstoken ist das einzige Schloss. Siehe Das Zugriffstoken und wer das Relay erreicht und Was OAR offenlegt.
- Das Relay lehnt Anfragen an seine internen Session-Worker-Pfade ab, wenn sie
den Cloudflare-Marker-Header
cf-oder einen Header tragen, den du inray tunneleinträgst. Ein einfacher Reverse Proxy fügt keinen davon hinzu; trag also den Header ein, den dein Proxy hinzufügt, falls er einen hinzufügt, den du gesperrt haben möchtest. Siehe config.json.Marker Headers
Fehlerbehebung #
Sieh dir zuerst die Zeilen [ssh- im Log an. Zeilen, die mit stderr:
beginnen, hat ssh selbst ausgegeben.
| Du siehst | Was es bedeutet | Was zu tun ist |
|---|---|---|
ssh (auch für host) |
Ein Pflichtwert fehlt. Der Tunnel bleibt aus. | Setz ihn und führ oar restart aus. |
ssh |
Der Port fehlt oder ist keine Zahl von 1 bis 65535. | Korrigiere ihn und starte neu. |
Tunnel mode disabled; running direct relay only. |
mode ist nicht managed. |
Setz "mode": "managed". |
stderr: ... Permission denied (publickey) |
Der Server hat deinen Key nicht akzeptiert. Batch-Modus heißt: keine Passwortabfrage. | Setz identity und teste dasselbe ssh user@host von Hand auf dem Relay-Host. |
Process exited (code= wiederholt sich |
ssh konnte sich nicht verbinden oder anmelden. |
Führ den protokollierten ssh-Befehl von Hand aus und lies seinen Fehler. |
stderr: ... remote port forwarding failed for listen port N, dann Attempting remote reclaim ... |
Der Port auf dem Server ist belegt. | Warte auf das Aufräumen. Endet es mit is still held, gib den Port selbst frei oder wähl einen anderen remote. |
Remote reclaim finished: listen port N is still held (code= |
Das Aufräumen konnte den Port nicht freigeben. | Such den Inhaber auf dem Server, versuch reclaim oder setz remote. |
stderr: ... Host key verification failed oder REMOTE HOST IDENTIFICATION HAS CHANGED |
Der Key des Servers weicht vom gespeicherten ab. | Ist die Änderung erwartet, entferne den alten Eintrag aus known_. Wenn nicht, verbinde dich nicht. |
Reconnecting in 60s (attempt N) immer wieder, und der Tunnel sagt nie Tunnel up |
Die Verbindung schlägt jedes Mal fehl. | Lies die Zeilen stderr: vor jeder davon. |
Der Tunnel sagt Tunnel up, aber die Adresse antwortet nicht |
Die Seite des Relays ist in Ordnung, die Seite des Servers nicht. | Prüf, ob der Reverse Proxy läuft und auf den remote zeigt und ob remote dazu passt, wie der Proxy ihn erreicht. |
| Der Tunnel verbindet sich, bricht ab und verbindet sich in einer Schleife neu | Etwas auf dem Server oder im Netzwerk beendet die Verbindung. | Das Log zeigt den Exit-Code und die Meldungen von ssh. Prüf das sshd-Log des Servers. |
| Nachrichten bleiben in der Queue | required ist true, und der Tunnel ist nicht verbunden. |
Repariere den Tunnel oder setz required auf false. |