O SSH público a través dun relé falla en dúas fronteiras non relacionadas, e arranxar unha adoita revelar a outra. Ou a borde devolve unha resposta HTTP en lugar de transportar un fluxo, ou o relé antepón unha cabeceira que o backend nunca aceptou ler. Tres condicións deciden cal das dúas está a ver: a que apunta realmente o rexistro público, que envía o bloque de fluxo cara á orixe e que nome verifica o cliente SSH. Tráteas nesa orde.

Dúas fronteiras, dous síntomas

Un fallo na borde parece unha páxina de estado HTTP que chega onde debería estar un banner SSH. A conexión complétase a nivel TCP e os primeiros bytes son texto que pertence a un servidor web. Iso é unha discrepancia de protocolo, non un paquete perdido. Tamén lle di que a borde serve deliberadamente outra cousa para ese nome.

Un fallo na orixe vese distinto. A conexión chega a sshd, sshd le bytes que non son o intercambio de identificación que espera, e a sesión morre ou queda colgada sen ofrecer nunca unha chave.

É doado confundir ambos porque os dous producen un cliente que conecta e logo falla. A primeira resposta de protocolo que recibe é o que os distingue, e por iso pertence ao tícket.

A cabeceira PROXY é unha mensaxe, non un interruptor

En o módulo de fluxo, proxy_protocol on indica a NGINX que escriba unha cabeceira de protocolo PROXY cara á orixe antes da carga útil. Non habilita o proxy TCP e non ten nada que ver co cifrado SSH. É unha nota dirixida ao receptor. Se o receptor non a pode ler, convértese en lixo ao comezo do fluxo.

O servizo receptor ten que consumir esa cabeceira de forma deliberada. Un sshd normal espera o intercambio de identificación SSH como primeiros bytes da conexión, así que un preámbulo inesperado rompe o apretón de mans dun xeito que parece un servidor corrupto.

stream {
    server {
        listen 2222;
        proxy_pass 10.77.0.20:22;
    }
}

Ese fragmento é todo un relé funcional para un backend alcanzable a través da VPN. Non aparece ningunha directiva PROXY porque o receptor non fala o protocolo, e esa ausencia é unha decisión, non unha omisión.

Separe tamén as dúas direccións. Poñer proxy_protocol na liña listen significa que NGINX espera que o seu propio cliente envíe primeiro a cabeceira; habilitalo para un cliente SSH corrente produce exactamente o contrario do problema que a xente adoita intentar resolver.

A que chega realmente o nome de host público

Unha páxina HTTP 400 nunha sesión SSH é evidencia sobre a borde. Algo no camiño fala HTTP, e ningunha cantidade de traballo coa chave ou a conta no backend o cambiará. Deixe de cambiar o backend ata que a borde estea resolta.

O rexistro con proxy ordinario de Cloudflare transporta o seu tráfico HTTP e HTTPS compatible en portos definidos. Activar o proxy para un nome de host non crea un relé TCP xeral, e mover SSH ao porto 443 non o converte en HTTPS.

Existen dúas direccións viables. Un rexistro só DNS pode apuntar ao seu propio relé TCP, o que deixa a decisión sobre a exposición nas súas mans. Como alternativa, use un produto que documente explicitamente o transporte de SSH, coa súa propia configuración de orixe, cliente e acceso.

Elixa o que elixa, o relé segue necesitando unha ruta VPN cara ao backend, unha conexión permitida e un camiño de volta. A ruta non é opcional porque o lado público funcione.

Manteña estable a identidade SSH mediante un alias

Os usuarios adoitan querer seguir escribindo o seu nome de host actual. Un alias na configuración de SSH pode facelo sen cambiar nada do relé, e mantén o cambio no lado do cliente, onde corresponde.

Host git.example.com
    HostName ssh-entry.example.net
    Port 2222
    User git
    HostKeyAlias git.example.com

Sen HostKeyAlias, OpenSSH busca a chave do host baixo o nome ao que se conecta, así que a entrada móvese e cada usuario ve un aviso de chave cambiada no primeiro uso. Establecer o alias mantén estables as entradas de known-hosts mentres a conexión segue indo ao relé.

Este alias só se aplica a remotos baseados en SSH. Unha URL de Git por HTTPS non o consulta, e a URL típica do remoto debe coincidir co transporte que realmente aprovisionou.

O que non debe facer é desactivar a verificación da chave do host para que o aviso desapareza. Iso elimina unha protección que a reparación do reenvío nunca pediu tocar, e converte unha molestia estética nunha exposición real.

Verifique cada salto por separado

Probe o oínte público por si só, despois a conexión do relé ao backend desde o host do relé, e só despois o cliente de extremo a extremo. Cada unha desas tres probas descarta unha capa distinta. Saltarse unha significa que os dous resultados restantes non se poden interpretar. Tres observacións, tres lugares onde pode vivir un fallo.

Conserve o enderezo de destino, o porto e os primeiros bytes de protocolo con cada resultado. Ese trío distingue un erro de borde dun problema de encamiñamento VPN e dun fallo de autenticación SSH, e é a diferenza entre unha reparación e unha conxectura.

Por último, documente a exposición prevista. Un relé TCP que transporta SSH cara a un backend privado é unha apertura deliberada no perímetro público, e merece a mesma revisión que calquera outro servizo entrante.

Artigos relacionados