Užklausa, atvykstanti į jūsų programą, neša dviejų rūšių adreso įrodymus: partnerį, kuris atidarė tinklo ryšį, ir HTTP lauką, kuris teigia ankstesnio kliento adresą. Jie atsako į skirtingus klausimus. Soketo partneris stebimas, o antraštę teigia tas, kas ją parašė, ir nė vienas neturėtų tyliai pakeisti kito žurnale ar prieigos taisyklėje. Toliau pateiktas palyginimas juos laiko atskirai ir tada parodo vienintelę tvarką, kurioje antraštė tampa naudinga.

Aprašykite kelią prieš ką nors lygindami:

Client -> approved reverse proxy -> application origin

Šioje tvarkoje šaltinio soketo partneris paprastai yra tarpinis serveris, o persiuntimo antraštė gali nešti tarpinio serverio teiginį apie klientą. Jos vertė kyla iš kontroliuojamo santykio su tuo tarpiniu serveriu, o ne iš antraštės pavadinimo.

Dviejų rūšių adreso įrodymai

Soketo partneris yra faktas apie vieną TCP ryšį: kažkas užbaigė rankos paspaudimą iš to adreso. Tai nebūtinai žmogus, įrenginys ar paskyra, kuri jums rūpi, nes VPN ar Tor išėjimas gali teisėtai būti šaltinis, kurį stebi paslauga. Vis dėlto tai vienintelis adresas, kurį patikrino pats mazgas, ir tame yra visa jo vertė.

Persiuntimo laukas yra metaduomenys apie grandinę. X-Forwarded-For, X-Real-IP ir standartizuotas laukas Forwarded gali būti parašyti bet kurio kliento, kuris pasiekia juos atkartojantį galinį tašką, todėl jų patikimumas visiškai priklauso nuo to, kam buvo leista juos nustatyti.

Laikykite abu užklausos kontekste skirtingais pavadinimais. Programa, kuri perrašo partnerį antrašte, praranda galimybę vėliau atkurti pasitikėjimo klaidą, o tai yra būtent tas momentas, kai jos reikia.

Antraštė niekada neperadresuoja ryšio

Adreso įrašymas į persiuntimo lauką nekeičia į serverį atvykstančio TCP ryšio šaltinio ir nekeičia maršrutizavimo niekur kelyje. Įprastas VPN maršrutizavimas arba šaltinio NAT pristato srautą visiškai be jokios HTTP antraštės. Taip pat tranzitiniai vartai neperrašo tinkamai apsaugotų HTTPS mainų nekeitę TLS galinio taško tvarkos.

Atvirkštinė klaida taip pat dažna: HTTPS nepadaro kliento pateiktos persiuntimo antraštės teisinga. Jis apsaugo neteisingo teiginio perdavimą lygiai taip pat kaip teisingo.

Jei kolega siūlo pakeisti antraštę, kad išspręstų maršrutizavimo problemą, diagnozė jau nuėjo ne ta linkme. Sutvarkykite kelią arba sutvarkykite tarpinio serverio konfigūraciją, kuri rašo antraštę.

Įvardykite tarpinį serverį, kuriam leidžiama teigti

Dvi taisyklės daro persiuntimo lauką naudingą, ir abi yra konfigūracija, o ne kodas. Kraštas normalizuoja arba atmeta viską, kas ateina iš išorės, pagal savo dokumentuotą elgesį tiems laukams. Tada šaltinis paima pakaitinį adresą iš jūsų įvardytos tarpinio serverio kelio ir iš niekur kitur. Antroji taisyklė galioja tik tol, kol klientai negali pasiekti šaltinio kitu būdu, nes šaltinis, atsakantis ir į tiesiogines, ir į per tarpinį serverį siųstas užklausas, nežino, kuriai jų tarnauja.

NGINX tikrojo IP modulis aiškiai parodo atskyrimą. set_real_ip_from įvardija siuntėjus, kurių teiginys skaičiuojamas, ir real_ip_header pasako, kuris laukas jį neša; pirmasis atlieka pasitikėjimą, antrasis tik pasako, kur žiūrėti.

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

Vien antraštės pasirinkimo direktyva vis dar nieko neįtvirtina apie tai, kas išsiuntė reikšmę.

Transporto saugumas turi veikti visame kelyje tarp komponentų, kuriais pasitikite. Kraštas, kuris teisingai normalizuoja, praranda tą vertę tą akimirką, kai neapsaugotas šuolis žemiau leidžia kam nors kitam redaguoti teiginį jam keliaujant.

Sąmoningai tvarkykite daugiašuolių grandines

Keli tarpiniai serveriai reikalauja aiškaus grandinės modelio. Neimkite kairiausios ar dešiniausios kableliu atskirtos reikšmės tik todėl, kad taip padarė koks nors tinklaraščio įrašas; išsiaiškinkite, kuris jūsų tarpinis serveris prideda, kuris pakeičia, o kuris išsaugo gaunamą lauką. Pavyzdžiui, NGINX gali pereiti sąrašą atgal prieš savo patikimą rinkinį ir sustoti prie pirmo adreso, kurio jam nepriklauso, ir tai yra to produkto taisyklė, o ne įstatymas, kurio laikosi kiekvienas karkasas. Skaitykite savo tarpinio serverio dokumentaciją su tais pačiais dviem klausimais: kurią reikšmę jis pasirenka ir kuriais siuntėjais tiki?

Užrašykite grandinę: šuolių tvarka, kuris šuolis nustato lauką ir kuris šuolis pašalina gaunamas kopijas. Tada laikykite tą pastabą šalia tarpinio serverio konfigūracijos, o ne tik biliete. Tada išbandykite ją siųsdami užklausą su suklastota antrašte per patvirtintą tikrinimo procesą ir patvirtindami, kad šaltinis ją ignoruoja.

Kai pridedate šuolį, peržiūrėkite tą dokumentą. Naujas apkrovos balansuoklis, įterptas prieš patikimą tarpinį serverį, gali pakeisti, kuris adresas laimi, niekam neredaguojant programos.

Laikykite abu stebėjimus žurnale

Kur diagnostika leidžiama, registruokite ryšio partnerį ir normalizuotą kliento adresą kaip du atskirus laukus, ir pridėkite tik tuos persiuntimo metaduomenis, kurių tikslui iš tikrųjų reikia. Tada įrodykite diegimą dviem užklausomis: viena per tarpinį serverį, kuri turėtų pagrįstai įrašyti abi reikšmes, ir vienu bandymu tiesiogiai į šaltinį, kuris turi būti atmestas.

Prisiminkite, ką reiškia pora. Antraštė prideda kontekstą, kurį suteikia komponentas, kurį pasirinkote pasitikėti; partneris lieka vienintelis adresas, kurį jūsų mazgas tikrai matė. Nė vienas iš jų nėra individualios tapatybės įrodymas, o dizainas, kuris bet kurį jų laiko įrodymu, suklys dėl ko nors.

Susiję straipsniai