Veřejné SSH přes přepravník selhává na dvou nesouvisejících hranicích a oprava jedné obvykle odhalí druhou. Hrana buď vrací odpověď HTTP místo přenášení toku, nebo přepravník předřadí záhlaví, které backend nikdy nesouhlasil se čtením. Který z případů vidíte, určují tři podmínky: na co veřejný záznam skutečně ukazuje, co blok toku posílá do upstreamu a které jméno klient SSH ověřuje. Zpracujte je v tomto pořadí.

Dvě hranice, dva příznaky

Selhání na hraně vypadá jako stránka stavu HTTP, která dorazí tam, kde má být banner SSH. Spojení se dokončí na úrovni TCP a první bajty jsou text patřící webovému serveru. To je nesoulad protokolů, nikoli ztracený paket. Také vám říká, že hrana pro to jméno záměrně obsluhuje něco jiného.

Selhání v upstreamu vypadá jinak. Spojení dorazí do sshd, sshd přečte bajty, které nejsou výměnou identifikace, kterou očekává, a relace zemře nebo visí, aniž by kdy nabídla klíč.

Obě je snadné zaměnit, protože obě dávají klienta, který se připojí a pak selže. První obdržená odpověď protokolu je to, co je rozliší, a proto patří do tiketu.

Záhlaví PROXY je zpráva, ne přepínač

V modulu toku proxy_protocol on říká NGINX, aby před užitečným zatížením zapsal směrem k upstreamu záhlaví protokolu PROXY. Nezapíná proxy TCP a nemá nic společného se šifrováním SSH. Je to poznámka adresovaná příjemci. Pokud ji příjemce nedokáže přečíst, stane se z ní smetí na začátku toku.

Přijímající služba musí toto záhlaví vědomě spotřebovat. Normální sshd očekává výměnu identifikace SSH jako první bajty spojení, takže neočekávaná preambule rozbije navázání spojení způsobem, který vypadá jako poškozený server.

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

Tento fragment je celý funkční přepravník pro backend dostupný přes VPN. Neobjevuje se žádná direktiva PROXY, protože příjemce daný protokol nezná, a tato nepřítomnost je rozhodnutí, ne opomenutí.

Oddělte také oba směry. Nastavení proxy_protocol na řádku listen znamená, že NGINX očekává, že jeho vlastní klient pošle záhlaví první; zapnutí pro běžného klienta SSH vytvoří přesně opak problému, který se lidé obvykle snaží vyřešit.

Co veřejné jméno hostitele skutečně dosáhne

Stránka HTTP 400 v relaci SSH je důkaz o hraně. Něco na cestě mluví HTTP a žádné množství práce s klíčem nebo účtem na backendu to nezmění. Přestaňte měnit backend, dokud není hrana vyřešena.

Běžný proxy záznam Cloudflare přenáší podporovaný provoz HTTP a HTTPS na definovaných portech. Zapnutí proxy pro jméno hostitele nevytváří obecný TCP přepravník a přesun SSH na port 443 z něj nedělá HTTPS.

Existují dva schůdné směry. Záznam pouze s DNS může ukazovat na váš vlastní TCP přepravník, což dává rozhodnutí o vystavení do vašich rukou. Případně použijte produkt, který výslovně dokumentuje přenos SSH, s vlastním nastavením původu, klienta a přístupu.

Ať zvolíte cokoli, přepravník stále potřebuje trasu VPN k backendu, povolené spojení a zpáteční cestu. Trasa není volitelná, protože veřejná strana funguje.

Udržte identitu SSH stabilní pomocí aliasu

Uživatelé obvykle chtějí dál psát své stávající jméno hostitele. Alias v konfiguraci SSH to umí, aniž by na přepravníku cokoli měnil, a ponechává změnu na straně klienta, kam patří.

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

Bez HostKeyAlias hledá OpenSSH klíč hostitele pod jménem, ke kterému se připojuje, takže se záznam posune a každý uživatel při prvním použití uvidí varování o změněném klíči. Nastavení aliasu udrží záznamy v known-hosts stabilní, zatímco spojení stále míří k přepravníku.

Tento alias platí pouze pro vzdálené repozitáře založené na SSH. URL Git přes HTTPS jej nekonzultuje a typická URL vzdáleného repozitáře musí odpovídat transportu, který jste skutečně zřídili.

Co nesmíte udělat, je vypnout ověřování klíče hostitele, abyste varování zbavili. Tím odstraníte ochranu, kterou oprava předávání nikdy nechtěla změnit, a proměníte kosmetickou nepříjemnost ve skutečné vystavení.

Ověřujte každý skok zvlášť

Otestujte veřejný naslouchač samostatně, potom spojení od přepravníku k backendu z hostitele přepravníku a teprve pak klienta od konce ke konci. Každý z těchto tří testů vylučuje jinou vrstvu. Vynechání jednoho znamená, že zbývající dva výsledky nelze interpretovat. Tři pozorování, tři místa, kde může selhání žít.

U každého výsledku si ponechte cílovou adresu, port a první bajty protokolu. Tato trojice rozlišuje chybu hrany od problému s routingem VPN a od selhání autentizace SSH, a to je rozdíl mezi opravou a hádáním.

Nakonec zdokumentujte zamýšlené vystavení. TCP přepravník, který přenáší SSH k soukromému backendu, je záměrné otevření ve veřejném perimetru a zaslouží stejnou revizi jako kterákoli jiná příchozí služba.

Související články