SSH tra NGINX-flua relaiso sen rompi ĝin
PROXY-kapo estas mesaĝo por ricevanto, kiu atendas ĝin, kaj proksigita DNS-rikordo ne estas TCP-relaiso. Riparu la randon kaj la supran flankon aparte.
Publika SSH tra relaiso malsukcesas ĉe du nerilataj limoj, kaj riparo de unu kutime malkaŝas la alian. Aŭ la rando redonas HTTP-respondon anstataŭ porti fluon, aŭ la relaiso antaŭmetas kapon, kiun la malantaŭa flanko neniam konsentis legi. Tri kondiĉoj decidas, kiun vi rigardas: kien la publika rikordo efektive montras, kion la flua bloko sendas supren, kaj kiun nomon la SSH-kliento kontrolas. Prilaboru ilin en tiu ordo.
Du limoj, du simptomoj
Malsukceso ĉe la rando aspektas kiel HTTP-stata paĝo alvenanta tien, kie devus esti SSH-standardo. La konekto kompletiĝas ĉe TCP-nivelo kaj la unuaj bajtoj estas teksto apartenanta al retservilo. Tio estas protokola nekongruo, ne perdita paketo. Ĝi ankaŭ diras al vi, ke la rando intence servas ion alian por tiu nomo.
Malsukceso ĉe la supra flanko aspektas alie. La konekto atingas sshd, sshd legas bajtojn, kiuj ne estas la identiga interŝanĝo, kiun ĝi atendas, kaj la sesio mortas aŭ pendas sen iam proponi ŝlosilon.
Tiujn du facilas konfuzi, ĉar ambaŭ produktas klienton, kiu konektiĝas kaj poste malsukcesas. La unua protokola respondo, kiun vi ricevas, estas tio, kio distingas ilin, kaj tial ĝi apartenas al la bileto.
La PROXY-kapo estas mesaĝo, ne ŝaltilo
En la flua modulo, proxy_protocol on instrukcias NGINX-n skribi PROXY-protokolan kapon al la supra flanko antaŭ la utilaĵo. Ĝi ne ŝaltas TCP-proksadon, kaj ĝi havas nenion komunan kun SSH-ĉifrado. Ĝi estas noto adresita al la ricevanto. Se la ricevanto ne povas legi ĝin, ĝi fariĝas rubo komence de la fluo.
La ricevanta servo devas konsumi tiun kapon intence. Normala sshd atendas la SSH-identigan interŝanĝon kiel la unuajn bajtojn de la konekto, do neatendita enkonduko rompas la manpremon tiel, ke ĝi aspektas kiel difektita servilo.
stream {
server {
listen 2222;
proxy_pass 10.77.0.20:22;
}
}
Tiu fragmento estas la tuto de funkcianta relaiso por malantaŭa flanko atingebla tra la VPN. Neniu PROXY-direktivo aperas, ĉar la ricevanto ne parolas la protokolon, kaj tiu manko estas decido, ne preterlaso.
Apartigu ankaŭ la du direktojn. Agordi proxy_protocol en la listen-linio signifas, ke NGINX atendas, ke ĝia propra kliento sendu la kapon unue; ŝalti ĝin por ordinara SSH-kliento produktas ĝuste la malon de la problemo, kiun homoj kutime provas solvi.
Kion la publika gastigantnomo efektive atingas
HTTP 400-paĝo en SSH-sesio estas pruvo pri la rando. Io en la vojo parolas HTTP, kaj nenia kvanto da laboro pri ŝlosilo aŭ konto ĉe la malantaŭa flanko ŝanĝos tion. Ĉesu ŝanĝi la malantaŭan flankon ĝis la rando estos solvita.
La ordinara proksigita rikordo de Cloudflare portas sian subtenatan HTTP- kaj HTTPS-trafikon sur difinitaj havenoj. Ŝalti la proksilon por gastigantnomo ne kreas ĝeneralan TCP-relaison, kaj movi SSH al haveno 443 ne igas ĝin HTTPS.
Ekzistas du fareblaj direktoj. Rikordo nur-DNS povas montri al via propra TCP-relaiso, kio metas la decidon pri elmeto en viajn manojn. Alternative uzu produkton, kiu eksplicite dokumentas SSH-transporton, kun propra agordo de origino, kliento kaj aliro.
Kion ajn vi elektos, la relaiso ankoraŭ bezonas VPN-itinieron al la malantaŭa flanko, permesitan konekton kaj revenan vojon. La itiniero ne estas laŭvola, ĉar la publika flanko funkcias.
Tenu la SSH-identecon stabila per kaŝnomo
Uzantoj kutime volas daŭre tajpi sian ekzistantan gastigantnomon. Kaŝnomo en SSH-agordo povas fari tion sen ŝanĝi ion ajn pri la relaiso, kaj ĝi tenas la ŝanĝon ĉe la klienta flanko, kie ĝi apartenas.
Host git.example.com
HostName ssh-entry.example.net
Port 2222
User git
HostKeyAlias git.example.com
Sen HostKeyAlias, OpenSSH serĉas la gastigantan ŝlosilon sub la nomo, al kiu ĝi konektiĝas, do la rikordo moviĝas kaj ĉiu uzanto vidas averton pri ŝanĝita ŝlosilo ĉe la unua uzo. Agordi la kaŝnomon tenas known-hosts-rikordojn stabilaj, dum la konekto daŭre iras al la relaiso.
Ĉi tiu kaŝnomo validas nur por SSH-bazitaj foraĵoj. HTTPS-Git-URL ne konsultas ĝin, kaj la tipa fora URL devas kongrui kun la transporto, kiun vi efektive provizis.
Kion vi ne devas fari, estas malŝalti la kontrolon de la gastiganta ŝlosilo por forigi la averton. Tio forigas protekton, kiun la riparo de plusendado neniam petis tuŝi, kaj ĝi ŝanĝas kosmetikan ĝenon en realan elmeton.
Kontrolu ĉiun salton aparte
Testu la publikan aŭskultanton memstare, poste la konekton de relaiso al malantaŭa flanko de la relaisa gastiganto, kaj nur poste la klienton de fino al fino. Ĉiu el tiuj tri testoj ekskludas malsaman tavolon. Preterlasi unu signifas, ke la du restantaj rezultoj ne povas esti interpretitaj. Tri observoj, tri lokoj, kie malsukceso povas loĝi.
Tenu la celadreson, la havenon kaj la unuajn protokolajn bajtojn kun ĉiu rezulto. Tiu triangulo distingas randan eraron de VPN-itiniera problemo kaj de SSH-aŭtentiga malsukceso, kaj ĝi estas la diferenco inter riparo kaj konjekto.
Fine, dokumentu la intencitan elmeton. TCP-relaiso, kiu portas SSH al privata malantaŭa flanko, estas intenca malfermo en la publika perimetro, kaj ĝi meritas la saman revizion kiel ĉiu alia envena servo.