SSH a través d'un relé de flux NGINX sense trencar-lo
Una capçalera PROXY és un missatge per a un receptor que l'espera, i un registre DNS amb proxy no és un relé TCP. Arregleu la vora i l'origen per separat.
L'SSH públic a través d'un relé falla en dues fronteres no relacionades, i arreglar-ne una normalment revela l'altra. La vora o bé retorna una resposta HTTP en lloc de transportar un flux, o bé el relé anteposa una capçalera que el backend mai no va acceptar llegir. Tres condicions decideixen quina de les dues veieu: a què apunta realment el registre públic, què envia el bloc de flux a l'origen i quin nom verifica el client SSH. Treballeu-les en aquest ordre.
Dues fronteres, dos símptomes
Una fallada a la vora sembla una pàgina d'estat HTTP que arriba on hauria d'arribar un bàner SSH. La connexió es completa a nivell TCP i els primers bytes són text que pertany a un servidor web. Això és una discrepància de protocol, no un paquet perdut. També us diu que la vora serveix deliberadament una altra cosa per a aquell nom.
Una fallada a l'origen es veu diferent. La connexió arriba a sshd, sshd llegeix bytes que no són l'intercanvi d'identificació que espera, i la sessió mor o es penja sense oferir mai cap clau.
Aquestes dues són fàcils de confondre perquè totes dues produeixen un client que es connecta i després falla. La primera resposta de protocol que rebeu és el que les distingeix, i per això pertany al tiquet.
La capçalera PROXY és un missatge, no un commutador
A el mòdul de flux, proxy_protocol on indica a NGINX que escrigui una capçalera de protocol PROXY cap a l'origen abans de la càrrega útil. No habilita el proxy TCP i no té res a veure amb el xifratge SSH. És una nota adreçada al receptor. Si el receptor no la pot llegir, es converteix en deixalles a l'inici del flux.
El servei receptor ha de consumir aquesta capçalera deliberadament. Un sshd normal espera l'intercanvi d'identificació SSH com a primers bytes de la connexió, així que un preàmbul inesperat trenca l'encaixada de mans d'una manera que sembla un servidor corrupte.
stream {
server {
listen 2222;
proxy_pass 10.77.0.20:22;
}
}
Aquest fragment és tot un relé funcional per a un backend abastable a través de la VPN. No hi apareix cap directiva PROXY perquè el receptor no parla el protocol, i aquesta absència és una decisió, no una omissió.
Separeu també les dues direccions. Establir proxy_protocol a la línia listen significa que NGINX espera que el seu propi client enviï primer la capçalera; habilitar-ho per a un client SSH ordinari produeix exactament el contrari del problema que la gent sol intentar resoldre.
Què arriba realment el nom d'amfitrió públic
Una pàgina HTTP 400 en una sessió SSH és una prova sobre la vora. Alguna cosa al camí parla HTTP, i cap quantitat de feina amb la clau o el compte al backend ho canviarà. Deixeu de canviar el backend fins que la vora estigui resolta.
El registre amb proxy ordinari de Cloudflare transporta el seu trànsit HTTP i HTTPS compatible en ports definits. Activar el proxy per a un nom d'amfitrió no crea un relé TCP general, i moure l'SSH al port 443 no el converteix en HTTPS.
Existeixen dues direccions viables. Un registre només DNS pot apuntar al vostre propi relé TCP, cosa que posa la decisió sobre l'exposició a les vostres mans. Alternativament, feu servir un producte que documenti explícitament el transport d'SSH, amb la seva pròpia configuració d'origen, client i accés.
Tant se val quin trieu, el relé encara necessita una ruta VPN cap al backend, una connexió permesa i un camí de tornada. La ruta no és opcional perquè la part pública funciona.
Manteniu la identitat SSH estable mitjançant un àlies
Els usuaris normalment volen continuar escrivint el seu nom d'amfitrió existent. Un àlies de configuració SSH ho pot fer sense canviar res del relé, i manté el canvi al costat del client, on li correspon.
Host git.example.com
HostName ssh-entry.example.net
Port 2222
User git
HostKeyAlias git.example.com
Sense HostKeyAlias, OpenSSH busca la clau de l'amfitrió sota el nom amb què es connecta, així que l'entrada es mou i cada usuari veu un avís de clau canviada al primer ús. Establir l'àlies manté estables les entrades de known-hosts mentre la connexió continua anant al relé.
Aquest àlies només s'aplica als remots basats en SSH. Una URL de Git HTTPS no el consulta, i l'URL típica del remot ha de coincidir amb el transport que realment heu aprovisionat.
El que no heu de fer és desactivar la verificació de la clau d'amfitrió per fer desaparèixer l'avís. Això elimina una protecció que la reparació del reenviament mai no va demanar tocar, i converteix una molèstia estètica en una exposició real.
Verifiqueu cada salt per separat
Proveu l'oient públic tot sol, després la connexió del relé al backend des de l'amfitrió del relé, i només llavors el client d'extrem a extrem. Cadascuna d'aquestes tres proves descarta una capa diferent. Saltar-se'n una significa que els dos resultats restants no es poden interpretar. Tres observacions, tres llocs on pot viure una fallada.
Conserveu l'adreça de destinació, el port i els primers bytes de protocol amb cada resultat. Aquest trio distingeix un error de vora d'un problema d'encaminament VPN i d'una fallada d'autenticació SSH, i és la diferència entre una reparació i una conjectura.
Finalment, documenteu l'exposició prevista. Un relé TCP que transporta SSH cap a un backend privat és una obertura deliberada al perímetre públic, i mereix la mateixa revisió que qualsevol altre servei d'entrada.