Fiecare linie din jurnalul de acces arată aceeași adresă de loopback, în timp ce pagina se încarcă și certificatul este validat corect. Nimic nu este stricat în sensul inaccesibilității, și de aceea acest caz supraviețuiește luni întregi. Ce s-a stricat este atribuirea: backendul web înregistrează adresa saltului care a redirecționat conexiunea, iar fiecare decizie ulterioară care a avut încredere în jurnal a moștenit același răspuns greșit.

Verificările de mai jos merg de la cablu spre interior. Opriți-vă la prima care explică valoarea pe care o vedeți, deoarece fiecare pas următor presupune că cele anterioare sunt deja adevărate. Niciuna dintre ele nu cere ghicirea configurației front-endului.

Urmați cele două conexiuni, nu linia din jurnal

Port-Share multiplexează două protocoale pe un singur ascultător TCP. OpenVPN inspectează primii octeți ai unei conexiuni de intrare, o păstrează când pare a fi propriul său protocol și predă orice altceva unui al doilea destinatar. Acel destinatar este de obicei un server web pe același gazdă, așa că socketul acceptat al serverului web are procesul OpenVPN drept partener.

ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'

Prima comandă arată cine deține ascultătorul public. A doua arată conexiunile care ajung la portul backendului, iar adresa partenerului lor este cea pe care o va tipări jurnalul de acces. Dacă acel partener este loopback, jurnalul este exact și informația s-a pierdut cu un strat mai devreme. Redenumirea câmpului din jurnal sau activarea unui modul IP de client nu va recupera o adresă pe care conexiunea nu a purtat-o niciodată.

Aceasta este verificarea care decide tot restul. Dacă partenerul backendului este adresa browserului, partajarea portului nu este problema dumneavoastră și formatul jurnalului este.

Redirecționarea transportului nu este injectare de antet

Redirecționarul mută octeți. Nu analizează HTTP, deci nu poate insera un antet într-o cerere pe care nu o citește niciodată ca cerere și nu poate adăuga nimic într-un flux TLS pe care îl lasă să treacă neatins. Un modul care așteaptă un antet de proxy va aștepta în continuare unul pe care nicio componentă nu îl produce.

Două mecanisme pot purta adresa originală, iar ambele necesită acord la ambele capete. Protocolul PROXY adaugă un antet mic la începutul conexiunii, iar backendul trebuie configurat să îl aștepte; un backend care nu îl așteaptă va trata acei octeți ca începutul cererii și va eșua într-un mod confuz. Antetele de proxy de încredere precum X-Forwarded-For funcționează atunci când un proxy care înțelege HTTP le setează și backendului i se spune ce parteneri le pot afirma.

Niciunul nu este automat și niciunul nu este sigur implicit. Un backend care crede orice antet redirecționat primit permite clientului să își aleagă propria adresă, ceea ce transformă o inexactitate din jurnal într-o ocolire a controlului de acces. Rulați demonstrația o dată pe un gazdă de test înainte de a avea încredere în orice antet pe o cale de producție.

curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3

Directorul opțional de mapare a surselor

Partajarea portului are un argument de director opțional care înregistrează o mapare între adresa sursă originală și conexiunea de redirecționare, pe platformele unde funcția este implementată. Se așteaptă ca partea web să consulte acea mapare; nu este un antet și nu este injectată în cerere.

Acel design merită cunoscut pentru că explică de ce unele implementări raportează adrese reale și altele nu, cu o configurație de front-end aparent identică. Diferența este pe partea receptoare și de obicei locuiește într-un modul sau patch pe care majoritatea serverelor web împachetate nu îl activează implicit. Citiți documentația serverului dumneavoastră web pentru cârligul exact pe care îl oferă și confirmați că modulul este încărcat în loc să presupuneți.

Dacă urmați această cale, tratați-o ca o integrare din două jumătăți: maparea scrisă de redirecționar și căutarea făcută de backend. Verificați ambele și confirmați că directorul supraviețuiește unei reporniri și nu crește nelimitat pe un ascultător aglomerat.

Decideți ce componentă garantează adresa

Înainte de a schimba configurația, numiți componenta căreia i se permite să afirme o adresă de client și componentele cărora li se permite să o creadă. Un singur răspuns scris previne derivarea obișnuită, în care trei straturi diferite au încredere fiecare într-o sursă diferită.

Trei designuri acoperă majoritatea nevoilor. Țineți ascultătorul public și ascultătorul web separate, astfel încât serverul web să vadă parteneri reali și să nu existe nicio problemă de atribuire. Puneți în față un proxy invers care înțelege HTTP, terminați sau analizați cererea acolo și lăsați-l să seteze un antet redirecționat pentru un backend care are încredere doar în acel proxy. Sau păstrați partajarea portului și acceptați că jurnalele arată saltul, cu reguli de acces scrise împotriva identității aplicației în locul unei adrese.

Ce nu funcționează este să tratați o adresă de loopback redirecționată drept dovadă că cererea a provenit de pe această mașină. Acea inferență este exact pe dos: adresa este prezentă tocmai pentru că o componentă locală a făcut conexiunea. O regulă scrisă astfel admite pe oricine poate ajunge la ascultător.

Testați regula, nu pagina

O pagină care se încarcă dovedește că calea de redirecționare funcționează și nu spune nimic despre atribuire. Testați consumatorul adresei: regula de acces, limita de rată, înregistrarea de audit, căutarea geografică.

curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log

Comparați o cerere externă autorizată cu înregistrările atât ale front-endului, cât și ale backendului, și confirmați că o regulă care ar trebui să respingă respinge în continuare, iar una care ar trebui să admită admite în continuare. Dacă linia din jurnal este corectă dar regula se comportă în continuare ca și cum toți ar fi locali, regula citește un alt câmp decât cel pe care l-ați corectat.

Încheiați scriind lanțul de atribuire în notele de implementare: ce ascultător, ce redirecționar, ce antet sau mapare și ce backend este configurat să aibă încredere în el. Următoarea persoană care citește o linie din jurnal va avea nevoie de toate patru, iar absența acelei note este modul în care același tichet se redeschide un an mai târziu. Țineți-o lângă configurație și nu într-un fir de chat.

Articole similare