Pieprasījums, kas nonāk jūsu programmā, nes divu veidu adreses pierādījumus: partneri, kas atvēra tīkla savienojumu, un HTTP lauku, kas apgalvo iepriekšēja klienta adresi. Tie atbild uz dažādiem jautājumiem. Soketa partneris tiek novērots, bet galveni apgalvo tas, kurš to rakstīja, un nevienam nevajadzētu klusi aizstāt otru žurnālā vai piekļuves noteikumā. Tālāk dotais salīdzinājums tos tur atsevišķi un pēc tam parāda vienīgo izkārtojumu, kurā galvenis kļūst lietojams.

Aprakstiet ceļu, pirms kaut ko salīdzināt:

Client -> approved reverse proxy -> application origin

Šajā izkārtojumā oriģināla soketa partneris parasti ir starpniekserveris, un pārsūtīšanas galvenis var nest starpniekservera apgalvojumu par klientu. Tā vērtība nāk no kontrolētajām attiecībām ar šo starpniekserveri, nevis no galveņa nosaukuma.

Divu veidu adreses pierādījumi

Soketa partneris ir fakts par vienu TCP savienojumu: kaut kas pabeidza rokasspiedienu no šīs adreses. Tas nav obligāti cilvēks, ierīce vai konts, kas jums rūp, jo VPN vai Tor izeja var likumīgi būt avots, ko pakalpojums novēro. Tomēr tas joprojām ir vienīgā adrese, ko pārbaudīja pats resursdators, un tajā ir visa tā vērtība.

Pārsūtīšanas lauks ir metadati par ķēdi. X-Forwarded-For, X-Real-IP un standartizēto lauku Forwarded var rakstīt jebkurš klients, kas sasniedz galapunktu, kurš tos atkārto, tāpēc to uzticamība pilnībā atkarīga no tā, kam bija atļauts tos iestatīt.

Turiet abus pieprasījuma kontekstā ar atšķirīgiem nosaukumiem. Programma, kas pārraksta partneri ar galveni, zaudē spēju vēlāk rekonstruēt uzticēšanās kļūdu, un tas ir tieši tas brīdis, kad tā jums ir vajadzīga.

Galvenis nekad nepārvirza savienojumu

Adreses ierakstīšana pārsūtīšanas laukā nemaina uz serveri pienākošā TCP savienojuma avotu un nemaina maršrutēšanu nekur ceļā. Parastā VPN maršrutēšana vai avota NAT piegādā datplūsmu bez jebkāda HTTP galveņa. Tāpat tranzīta vārteja nepārraksta pareizi aizsargātu HTTPS apmaiņu, nemainot TLS galapunkta izkārtojumu.

Pretējā kļūda ir tikpat izplatīta: HTTPS nepadara klienta sniegto pārsūtīšanas galveni patiesu. Tas aizsargā nepatiesa apgalvojuma pārsūtīšanu tieši tikpat labi kā patiesa.

Ja kolēģis ierosina mainīt galveni, lai labotu maršrutēšanas problēmu, diagnoze jau ir nogājusi greizi. Izlabojiet ceļu vai izlabojiet starpniekservera konfigurāciju, kas raksta galveni.

Nosauciet starpniekserveri, kuram atļauts apgalvot

Divi noteikumi padara pārsūtīšanas lauku lietojamu, un abi ir konfigurācija, nevis kods. Mala normalizē vai izmet visu, kas nāk no ārpuses, saskaņā ar savu dokumentēto uzvedību šiem laukiem. Pēc tam oriģināls ņem aizvietotāja adresi no jūsu nosauktā starpniekservera ceļa un ne no kurienes citur. Otrais noteikums ir spēkā tikai tik ilgi, kamēr klienti nevar sasniegt oriģinālu citādi, jo oriģināls, kas atbild gan uz tiešiem, gan uz starpniekservera pieprasījumiem, nezina, kuram no tiem tas kalpo.

NGINX īstās IP modulis skaidri parāda nodalījumu. set_real_ip_from nosauc sūtītājus, kuru apgalvojums tiek skaitīts, un real_ip_header pasaka, kurš lauks to nes; pirmais veic uzticēšanos, otrais tikai pasaka, kur skatīties.

set_real_ip_from 10.20.0.0/24;
real_ip_header X-Forwarded-For;
# real_ip_recursive off - take the rightmost value in the field
# real_ip_recursive on  - walk the list back past every trusted address

Tikai galveņa atlases direktīva pati par sevi vēl neko nenodibina par to, kas nosūtīja vērtību.

Transporta drošībai jādarbojas visā ceļā starp komponentiem, kuriem uzticaties. Mala, kas pareizi normalizē, zaudē šo vērtību tajā brīdī, kad neaizsargāts lēciens lejāk ļauj kādam citam rediģēt apgalvojumu tā ceļā.

Apzināti rīkojieties ar vairāku lēcienu ķēdēm

Vairākiem starpniekserveriem nepieciešams skaidrs ķēdes modelis. Neņemiet kreisāko vai labāko komatu atdalīto vērtību tikai tāpēc, ka kāds bloga ieraksts tā darīja; noskaidrojiet, kurš no jūsu starpniekserveriem pievieno, kurš aizstāj un kurš saglabā ienākošo lauku. Piemēram, NGINX var iet sarakstu atpakaļ pret savu uzticamo kopu un apstāties pie pirmās adreses, kas tam nepieder, un tas ir tā produkta noteikums, nevis likums, kam seko katra ietvara sistēma. Lasiet sava starpniekservera dokumentāciju ar tiem pašiem diviem jautājumiem: kuru vērtību tas izvēlas un kuriem sūtītājiem tas tic?

Pierakstiet ķēdi: lēcienu secība, kurš lēciens iestata lauku un kurš lēciens noņem ienākošās kopijas. Pēc tam turiet šo piezīmi blakus starpniekservera konfigurācijai, nevis tikai biļetē. Pēc tam pārbaudiet to, nosūtot pieprasījumu ar viltotu galveni caur apstiprināto validācijas procesu un apstiprinot, ka oriģināls to ignorē.

Kad pievienojat lēcienu, pārskatiet šo dokumentu. Jauns slodzes līdzsvarotājs, kas ievietots uzticamā starpniekservera priekšā, var mainīt to, kura adrese uzvar, bez tam, ka kāds rediģē programmu.

Turiet abus novērojumus žurnālā

Kur diagnostika ir atļauta, reģistrējiet savienojuma partneri un normalizēto klienta adresi kā divus atsevišķus laukus, un pievienojiet tikai tos pārsūtīšanas metadatus, kas mērķim patiešām vajadzīgi. Pēc tam pierādiet izvietošanu ar diviem pieprasījumiem: vienu caur starpniekserveri, kam abas vērtības būtu saprātīgi jāreģistrē, un vienu tiešu mēģinājumu uz oriģinālu, kas ir jānoraida.

Atcerieties, ko nozīmē pāris. Galvenis pievieno kontekstu, ko sniedz komponents, kuru jūs izvēlējāties uzticēties; partneris paliek vienīgā adrese, ko jūsu resursdators patiešām redzēja. Neviens no tiem nav individuālas identitātes pierādījums, un dizains, kas jebkuru no tiem uzskata par pierādījumu, kļūdīsies par kādu.

Saistītie raksti