Llegar al relay por un túnel SSH
El relay puede abrir una conexión SSH a un servidor tuyo y pedirle a ese
servidor que reenvíe un puerto de vuelta al relay. Así llegas al relay en la
dirección del servidor, y nada en casa escucha conexiones de internet. El relay
arranca, vigila y reinicia el proceso ssh por sí mismo.
Elige esta opción cuando ya tengas un servidor con una dirección pública y acceso SSH. Si no tienes servidor, el Cloudflare Tunnel integrado no lo necesita.
Lo que necesitas #
- El host del relay tiene un programa
sshen suPATH(o indicas otro concommand, ver más abajo). - Un inicio de sesión SSH en el servidor que funcione con una clave y sin
preguntar nada. El relay ejecuta
sshen modo batch, así que no puede escribir una contraseña ni la frase de contraseña de una clave. Una clave con frase de contraseña solo funciona si la tiene un agente SSH. Pruébalo antes desde el host del relay:ssh relay@relay.debe iniciar sesión sin preguntar nada.example. com - Un puerto libre en el servidor para el túnel (
remote).Port - Algo en el servidor que sirva ese puerto por HTTPS: un servidor web o un proxy inverso como Caddy o nginx. El túnel lleva HTTP sin cifrar, así que sin eso tu token y tus conversaciones cruzan internet sin cifrar en cuanto el puerto es accesible. Consulta Ejecutar el relay detrás de un proxy inverso.
El relay no necesita ningún ajuste especial de sshd. Con remote en
loopback, pide el reenvío sin dirección de enlace, así que el propio ajuste
Gateway del servidor decide dónde se abre el puerto. Con su valor
predeterminado, no, eso es solo el propio servidor, y el proxy inverso es lo
único que da a internet. Con public el relay pide todas las interfaces (*:),
y esa petición solo surte efecto si el sshd del servidor lo permite
(Gateway fijado a clientspecified o yes).
Configurarlo #
Añade un bloque ssh a config. (consulta
Dónde está el archivo) y reinicia el
relay con oar restart.
"sshTunnel": {
"mode": "managed",
"required": false,
"user": "relay",
"host": "relay.example.com",
"remotePort": 4444,
"remoteBind": "loopback",
"identityFile": "~/.ssh/id_ed25519"
}
En el servidor, envía el HTTPS al puerto del túnel. Con Caddy:
relay.example.com {
reverse_proxy localhost:4444
}
Abre https:// en un navegador e inicia sesión con tu token
de acceso. El banner de arranque del relay imprime una línea Remote: y oar url
imprime una línea Tunnel URL: con un código QR. Ambas son https:// más el
valor de host, sin puerto y sin comprobar que el túnel esté activo, así que
solo son correctas cuando tu proxy sirve HTTPS en el puerto estándar.
Las claves de sshTunnel #
Todas las claves están en el bloque ssh. La tabla coincide con
config.json, que tiene la misma
lista.
| Clave | Tipo | Valor predeterminado | Qué hace |
|---|---|---|---|
mode |
"disabled" o "managed" |
"disabled" |
managed hace que el relay arranque y reinicie el túnel. |
user |
cadena | ninguno | El usuario SSH en el servidor. Obligatorio en modo gestionado. |
host |
cadena | ninguno | El nombre de host o la dirección del servidor. Obligatorio en modo gestionado. |
remote |
número | ninguno | El puerto que se abre en el servidor, de 1 a 65535. Obligatorio en modo gestionado. |
remote |
"loopback" o "public" |
"loopback" |
loopback pide el puerto sin dirección de enlace (decide el Gateway del servidor, consulta Lo que necesitas); public pide todas las interfaces. Cualquier otro valor cuenta como loopback. Independiente de localhost. |
identity |
cadena | ninguno | El archivo de la clave privada; ~ se expande. Sin él, ssh usa tu agente y sus claves predeterminadas. |
command |
cadena | ssh |
El programa SSH, que también se usa para la limpieza en el servidor. Un nombre se busca en el PATH; una ruta con barra se usa tal cual, y una relativa cuenta desde la carpeta del programa del relay. |
required |
booleano | false |
Mientras el túnel no está conectado, el relay no toma mensajes de la queue. Consulta Obligatorio. |
auto |
booleano | true |
Cuando el puerto remoto ya está ocupado, ejecuta una limpieza en el servidor y lo vuelve a intentar. Solo false lo desactiva. |
reclaim |
booleano | false |
Como parte de esa limpieza, termina también tus propias sesiones SSH inactivas en el servidor. |
remote |
cadena | integrado | Tu propio comando de limpieza, que se ejecuta en el servidor en lugar del integrado. |
La forma antigua "enabled": true sigue funcionando y significa
"mode": "managed", pero solo cuando mode no está fijado a disabled ni a
managed.
El relay reenvía el remote del servidor a su propio puerto en 127.
(3333 salvo que hayas cambiado port). Con public el reenvío se pide como
*:, y si no, como remote.
Estos ajustes son fijos y no tienen claves: el relay ejecuta ssh -N con
Server, Server, Batch,
Strict y Exit. ssh da por
perdida una conexión tras tres comprobaciones sin respuesta, con 30 segundos
entre ellas.
Si falta un valor obligatorio (user, host o un remote válido en modo
gestionado), el relay arranca como siempre, registra cuál falta y deja el túnel
desactivado.
Cómo se comporta #
Arranque. El relay arranca el túnel en cuanto está escuchando. Cuenta el
túnel como conectado cuando ssh lleva 1,2 segundos en ejecución y el servidor
no ha rechazado el reenvío. El registro dice entonces
Tunnel up to user@host remote port N.
Reconexión. Cuando ssh termina, el relay lo vuelve a arrancar tras una
espera que crece: 5, 10, 20, 40 y luego 60 segundos, y se queda en 60. La cuenta
vuelve a empezar cuando se cae una conexión que duró más de 30 segundos. Detener
el relay detiene el túnel y los reintentos.
Claves de host. Un servidor que el host del relay no ha visto nunca se
acepta y se recuerda en la primera conexión. Después, una clave de host cambiada
hace que ssh se niegue a conectarse hasta que quites la entrada antigua de
known_.
Obligatorio #
Con required: true la queue queda en pausa desde el arranque hasta que el túnel
está conectado, y otra vez cada vez que se cae. Los mensajes que envías esperan
en la queue y se ejecutan en cuanto el túnel está activo. Úsalo cuando el relay
no te sirva sin el túnel. Un túnel que no puede arrancar porque falta un valor
también mantiene la queue en pausa.
Cuando el puerto remoto está ocupado #
Si el servidor dice que no se puede enlazar el puerto, la causa habitual es una
sesión sobrante de un túnel anterior que el servidor no ha detectado como
muerta. Salvo que auto sea false, el relay se conecta entonces al
servidor una segunda vez y ejecuta allí un comando de limpieza.
Estas opciones ejecutan comandos en tu servidor
La limpieza se ejecuta con tu inicio de sesión SSH y mata procesos. Termina
cualquier proceso de ese usuario que escuche en el puerto remoto, sea o no un
túnel sobrante. Con reclaim termina también todas las sesiones
SSH inactivas de ese usuario, lo que incluye otros túneles ssh -N -R del mismo
inicio de sesión en otros puertos. remote ejecuta lo que
escribas. Lee lo que hace cada paso antes de dejarlas activadas.
La limpieza integrada hace esto, en orden:
- Comprueba si el puerto está en uso (con
sso, si no, leyendo la lista de sockets a la escucha del kernel). Si no lo está, se detiene e informa de éxito. - Busca los procesos que escuchan en el puerto (con
lsofo, si no,fuser, el que exista), les envía una señal de terminación (kill) y espera un segundo. Un proceso al que tu inicio de sesión no puede enviar señales se queda. Si el puerto ya está libre, informa de éxito. - Solo con
reclaim, y solo si el puerto sigue en uso: envía una señal de terminación a cada sesiónStale Ssh Sessions: true sshdde tu usuario que no tenga procesos hijos y espera un segundo. Son las sesiones que deja atrás unssh -N -R. Las sesiones que ejecutan una shell, el servidor remoto de un editor o cualquier otro programa tienen hijos y se omiten, igual que la sesión que ejecuta la propia limpieza. - Si el puerto sigue en uso, la limpieza termina con el código 3, que el relay
registra como
is still held.
Con remote fijado, tu comando se ejecuta en lugar de todo eso, y
reclaim no tiene efecto. El relay lo ejecuta como sh -lc '<command>' a través de un
segundo inicio de sesión ssh con la misma clave, en modo batch. Debe terminar con 0 cuando el puerto está libre y con otro código cuando
sigue ocupado.
Tras una limpieza que liberó el puerto, el relay lo reintenta al cabo de un
segundo, hasta tres veces seguidas. Tras una limpieza fallida, o con
auto desactivado, usa la espera normal descrita arriba.
Ver el estado del túnel #
El túnel SSH no se muestra en los sitios donde aparece el túnel de Cloudflare:
oar status y oar doctor solo informan del túnel de Cloudflare, y el punto
de estado no se vuelve ámbar con un túnel SSH (consulta
El punto de estado). Mira aquí en su lugar:
- El registro del relay. Cada línea empieza por
[ssh-. Muestra la línea de comandos detunnel] sshque ejecuta, lo que imprimessh,Tunnel up to ...,Reconnecting in Ns (attempt N)...y los pasos de la recuperación del puerto. Dónde está el registro depende de cómo se ejecute el relay; consulta Archivos y carpetas. - El banner de arranque, con una línea
Remote:y una líneaTunnel: mode=(oloopback public) cuando el túnel gestionado está configurado. Muestran la configuración, no si el túnel está activo.oar urlimprime la misma dirección comoTunnel URL:. /, que tiene un objetoapi/ status sshconTunnel connected,connected,Since reconnect,Attempts last,Error blocking,required,mode,valid,host,remoteyPort remote. Consúltalo con tu token.Bind Mode
last es exit:<code> cuando ssh ha terminado,
remote- cuando el servidor ha rechazado el puerto,
invalid- o el mensaje del valor que falta cuando el bloque está
incompleto, y vacío mientras el túnel está activo.
Seguridad #
Una vez activo el túnel, se puede llegar al relay desde internet, y el token de acceso es lo único que se interpone entre un desconocido y tus agentes, que ejecutan comandos en tu máquina. Por eso:
- Mantén
remoteenBind loopbacky pon HTTPS delante en el servidor. Conpublic, cualquiera que llegue al puerto del túnel en el servidor llega al relay por HTTP sin cifrar. - El token de acceso es el único cerrojo. Consulta El token de acceso y quién llega al relay y Qué expone OAR.
- El relay rechaza las solicitudes a sus rutas internas del worker de sesión
cuando llevan la cabecera marcadora de Cloudflare
cf-o una cabecera que listes enray tunnel. Un proxy inverso normal no añade ninguna de ellas, así que lista la cabecera que añade tu proxy, si añade una que quieras bloquear. Consulta config.json.Marker Headers
Solución de problemas #
Mira primero las líneas [ssh- del registro. Las líneas que empiezan
por stderr: son lo que imprimió el propio ssh.
| Lo que ves | Qué significa | Qué hacer |
|---|---|---|
ssh (también para host) |
Falta un valor obligatorio. El túnel queda desactivado. | Fíjalo y ejecuta oar restart. |
ssh |
Falta el puerto o no es un número de 1 a 65535. | Corrígelo y reinicia. |
Tunnel mode disabled; running direct relay only. |
mode no es managed. |
Fija "mode": "managed". |
stderr: ... Permission denied (publickey) |
El servidor no aceptó tu clave. El modo batch implica que no se pide contraseña. | Fija identity y prueba el mismo ssh user@host a mano en el host del relay. |
Process exited (code= repetido |
ssh no pudo conectarse o iniciar sesión. |
Ejecuta a mano el comando ssh registrado y lee su error. |
stderr: ... remote port forwarding failed for listen port N, y luego Attempting remote reclaim ... |
El puerto del servidor está en uso. | Espera a la recuperación. Si termina con is still held, libera el puerto tú mismo o elige otro remote. |
Remote reclaim finished: listen port N is still held (code= |
La limpieza no pudo liberar el puerto. | Busca en el servidor quién lo ocupa, prueba reclaim o fija remote. |
stderr: ... Host key verification failed o REMOTE HOST IDENTIFICATION HAS CHANGED |
La clave del servidor no coincide con la guardada. | Si el cambio es esperado, quita la entrada antigua de known_. Si no, no te conectes. |
Reconnecting in 60s (attempt N) una y otra vez, y el túnel nunca dice Tunnel up |
La conexión falla cada vez. | Lee las líneas stderr: anteriores a cada una. |
El túnel dice Tunnel up pero la dirección no responde |
El lado del relay está bien; el del servidor, no. | Comprueba que el proxy inverso esté en marcha y apunte al remote, y que remote encaje con cómo llega a él el proxy. |
| El túnel se conecta, se cae y se reconecta en bucle | Algo en el servidor o en la red termina la conexión. | El registro muestra el código de salida y los mensajes de ssh. Revisa el registro de sshd del servidor. |
| Los mensajes se quedan en la queue | required es true y el túnel no está conectado. |
Arregla el túnel o fija required a false. |