Neko usmjeri javni HAProxy host na lokalnu aplikaciju i pita zašto je preglednik ne može pratiti. Proxy dolazi do aplikacije kroz svoj VPN, preusmjeravanje vraća Location zaglavlje, a preglednik zatim pokušava adresu koja postoji samo unutar tunela. Izvana se stranica jednostavno zablokira. Odluka je o tome koja strana otvara drugu vezu, i upravo to razdvaja preusmjeravanje od backenda.

Dvije staze koje u konfiguraciji izgledaju slično

Preusmjeravanje završava razmjenu odgovorom. Klijent čita Location i započinje novi zahtjev s mjesta na kojem se nalazi, a to je mreža koju nikada niste kontrolirali. Proxy više nije uključen. Sve što slijedi zavisi od klijentovog DNS-a, rute i povjerenja, pa ishod varira prema tome gdje je korisnik otvorio preglednik:

GET /app        client -> proxy
302 Location    proxy  -> client   (http://10.40.0.20:8080/)
GET /app        client -> 10.40.0.20:8080   client network, no route

Proxy backend zadržava drugu dionicu na strani servera. Proxy je otvara putem koji već ima, a klijent nastavlja razgovarati s jednim javnim imenom. Ako tunel padne, klijent dobija grešku umjesto URL-a koji ne može pratiti. Ta razlika je i ono što kvar čini dijagnosticiranim, jer se greška pojavljuje tamo gdje su zapisi:

GET /app        client -> proxy
GET /app        proxy  -> 10.40.0.20:8080   over the VPN
response        proxy  -> client

HAProxy dokumentacija o preusmjeravanjima povlači upravo tu granicu: odgovoriti klijentu preusmjeravanjem druga je radnja od prosljeđivanja zahtjeva backendu. Dvije direktive stoje nekoliko redova jedna od druge u konfiguracijskoj datoteci i ponašaju se potpuno različito. Jedna završava zahtjev, druga započinje drugi koji proxy posjeduje.

Šta pregledniku treba, a serverov VPN mu ne daje

Zahtjev samog preglednika treba četiri stvari koje možda nema: DNS odgovor za privatno ime, rutu do te adrese, dozvolu za pristup usluzi koja sluša i povjerenje u certifikat koji ta usluga predstavlja. Proxy host posjeduje sve četiri kroz svoj tunel. Nijedna se ne prenosi na klijenta koji nikada nije bio u tom tunelu, jer je tunel svojstvo hosta, a ne URL-a.

Taj jaz objašnjava simptom skoro-radi. Prvi zahtjev uspijeva, adresna traka se mijenja, a veza se zatim blokira ili pada dok je proxy cijelo vrijeme zdrav. U konfiguraciji proxyja ništa nije pokvareno i njeno podešavanje ne pomaže klijentu koji nema put do 10.40.0.20. Ili klijent dobije rutu, ili proxy mora uspostaviti vezu u njegovo ime.

Kada samo proxy može doći do aplikacije

Uklonite radnju preusmjeravanja i pošaljite te zahtjeve backendu koji pokazuje na privatnu adresu. Frontend zadržava svoje javno ime dok backend odlučuje kuda zahtjev zapravo ide. Ništa se na klijentovoj stazi ne mijenja, jer proxy prestaje opisivati odredište i počinje biti odredište. Za aplikaciju koja namjerno sluša na internom portu 8080, serverski blok je kratak:

backend private_app
    mode http
    option httpchk GET /health
    server app1 10.40.0.20:8080 check

Čitajte taj blok kao tvrdnju o proxyjevoj tablici usmjeravanja: 10.40.0.20 mora biti dostupan sa samog proxy hosta, što ovdje znači kroz VPN interfejs, a ne kroz zadanu rutu. Ključna riječ check samo izvještava šta ta ruta radi, a putanja zdravlja mora postojati na aplikaciji, inače svaka provjera označi server kao isključen. Uspješna provjera ne dokazuje ništa o klijentu i ne zamjenjuje politiku koja odlučuje ko smije koristiti backend.

Fragment nije potpuni frontend. Zadržite listener, autentifikaciju, izbor dozvoljenog hosta i putanje te pravilo koje odlučuje ko uopće smije doći do aplikacije. Uskladite i protokol backenda, jer HTTPS backend traži provjeru certifikata i konfiguraciju identiteta servera, a preskakanje te provjere pretvara privatnu vezu u neprovjerenu.

Potvrdite povratnu putanju u oba smjera prije nego proglasite pobjedu. Aplikacija sada vidi vezu s proxyja, pa njeni zapisi i bilo koji metapodaci adrese klijenta opisuju proxy, osim ako ne uredite drugačije. Odlučite kako se obrađuju identitet i proslijeđene adrese i testirajte odluku umjesto da je pretpostavljate.

Aplikacijina vlastita preusmjeravanja još pokazuju unutra

Prosljeđivanje prvog zahtjeva samo je pola integracije. Aplikacija može emitovati apsolutna preusmjeravanja, tvrdo kodirane URL-ove resursa ili kolačiće ograničene na ime koje poznaje interno, i svako od toga vraća preglednik na adresu koju ne može dosegnuti. Location zaglavlje koje pokazuje na interno ime izgleda identično originalnom problemu, zbog čega se pogrešno dijagnostikuje kao kvar proxyja.

Postavite dokumentovani vanjski URL aplikacije i njene proxy opcije, zatim uskladite Host zaglavlje s virtualnim hostom i očekivanjima certifikata. Kolačić ograničen na interno ime neće se vratiti kroz javno ime, a petlja prijave koja slijedi čita se kao greška autentifikacije. Prvo promijenite vanjski URL, ponovo testirajte iz čistog profila preglednika i očekujte da će napola migrirana podešavanja proizvesti prijavu koja uspijeva i sesiju koja odmah umire.

Vjerujte proslijeđenim metapodacima samo od određenog proxyja. Zaglavlje koje svaki klijent može postaviti nikada ne smije postati vrijednost autorizacije, inače proxy postaje način da pozivalac prisvoji tuđi identitet. To pravilo je neovisno od pitanja preusmjeravanja i nadživljava svaki kasniji redizajn.

Odlučite koji dizajn zapravo imate

Ako svaki korisnik već ima autorizirani VPN pristup, preusmjeravanje na privatni URL može biti namjeran dizajn. Potvrdite taj zahtjev izričito umjesto da ga pretpostavljate, jer dva dizajna služe potpuno različitim populacijama. Jedan od njih uopće ne radi iz hotelske mreže, a drugi izlaže aplikaciju svakome ko može učitati javni URL. Ta razlika pripada u bilješku o dizajnu.

Pokrenite provjeru s mašine na korisničkoj mreži i pratite svaki skok preglednika, ne samo prvi odgovor. Pazite na adresnu traku i svaki sljedeći zahtjev, jer je jedan apsolutni URL u oznaci resursa dovoljan da slomi tok koji je prvi skok prošao. Prijava mora raditi kroz javno ime, a resursi koji treba da budu odbijeni moraju ostati odbijeni.

Objavljivanje reverse proxyja odvojena je odluka o pristupu, a ne transparentno proširenje proxyjevog VPN-a na svakoga ko može učitati njegov javni URL. Njih dvoje izgledaju slično na dijagramu i razlikuju se po tome kome je dozvoljen ulaz. Odlučivanje o tom pitanju nakon implementacije je način na koji interna aplikacija slučajno postane javna.

Zapišite koji ste od dva dizajna izgradili i zašto. Sljedeća osoba koja dotakne konfiguraciju pretpostavit će onaj drugi. Jedno preusmjeravanje dodano radi udobnosti dovoljno je da ponovno stvori originalni kvar, a simptom će izgledati točno kao onaj koji ste upravo ispravili.

Povezani članci