Peer del socket o intestazione inoltrata: a quale indirizzo fidarsi?
Il peer del socket e un’intestazione inoltrata sono prove diverse. Confrontate che cosa dimostra ciascuna e fidatevi dell’intestazione solo attraverso una catena di proxy che controllate.
Una richiesta che arriva alla vostra applicazione porta due tipi di prova sull’indirizzo: il peer che ha aperto la connessione di rete e un campo HTTP che rivendica l’indirizzo di un client precedente. Rispondono a domande diverse. Il peer del socket è osservato, mentre l’intestazione è affermata da chi l’ha scritta, e nessuno dei due dovrebbe sostituire in silenzio l’altro in un registro o in una regola di accesso. Il confronto qui sotto li tiene separati, poi mostra l’unica disposizione in cui l’intestazione diventa utilizzabile.
Descrivete il percorso prima di confrontare qualsiasi cosa:
Client -> approved reverse proxy -> application originIn questa disposizione il peer del socket dell’origine è di solito il proxy, e un’intestazione di inoltro può portare l’affermazione del proxy sul client. Il suo valore deriva dalla relazione controllata con quel proxy, non dal nome dell’intestazione.
Due tipi di prova sull’indirizzo
Il peer del socket è un fatto su una singola connessione TCP: qualcosa ha completato una stretta di mano da quell’indirizzo. Non è necessariamente la persona, il dispositivo o l’account che vi interessa, perché una VPN o un’uscita Tor possono essere legittimamente l’origine che un servizio osserva. Resta comunque l’unico indirizzo che l’host stesso ha verificato, e in questo consiste tutto il suo valore.
Un campo di inoltro è un metadato su una catena. X-Forwarded-For, X-Real-IP e il campo standardizzato Forwarded possono essere scritti da qualsiasi client che raggiunga un endpoint che li riflette, quindi la loro affidabilità dipende interamente da chi è stato autorizzato a impostarli.
Tenete entrambi nel contesto della richiesta con nomi distinti. Un’applicazione che sovrascrive il peer con l’intestazione perde la capacità di ricostruire in seguito un errore di fiducia, ed è proprio il momento in cui vi serve.
Un’intestazione non reindirizza mai la connessione
Scrivere un indirizzo in un campo di inoltro non cambia l’origine della connessione TCP che arriva al server, né altera il routing in nessun punto del percorso. Il routing VPN ordinario o il NAT di origine consegna il traffico senza alcuna intestazione HTTP. Allo stesso modo, un gateway di transito non riscrive uno scambio HTTPS ben protetto senza cambiare la disposizione dell’endpoint TLS.
L’errore inverso è altrettanto comune: HTTPS non rende veritiera un’intestazione di inoltro fornita dal client. Protegge il trasporto di un’affermazione falsa esattamente come quello di una vera.
Se un collega propone una modifica dell’intestazione per risolvere un problema di routing, la diagnosi è già sbagliata. Correggete il percorso o correggete la configurazione del proxy che scrive l’intestazione.
Nominate il proxy autorizzato ad affermare
Due regole rendono utilizzabile un campo di inoltro, ed entrambe sono configurazione e non codice. Il bordo normalizza o scarta tutto ciò che arriva dall’esterno, secondo il proprio comportamento documentato per quei campi. Poi l’origine prende un indirizzo sostitutivo dal percorso di proxy che avete nominato e da nessun altro luogo. La seconda regola vale solo finché i client non possono raggiungere l’origine in altro modo, poiché un’origine che risponde sia a richieste dirette sia a richieste tramite proxy non sa quale delle due stia servendo.
Il modulo IP reale di NGINX mostra la separazione chiaramente. set_real_ip_from nomina i mittenti la cui affermazione conta, e real_ip_header dice quale campo la porta; il primo esercita la fiducia, il secondo dice soltanto dove guardare.
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
Una direttiva di selezione dell’intestazione da sola non stabilisce ancora nulla su chi abbia inviato il valore.
La sicurezza del trasporto deve correre per tutto il percorso tra i componenti di cui vi fidate. Un bordo che normalizza correttamente perde quel valore nel momento in cui un salto non protetto più a valle permette a qualcun altro di modificare l’affermazione mentre viaggia.
Gestite deliberatamente le catene a più salti
Più proxy richiedono un modello di catena esplicito. Non prendete il valore più a sinistra o più a destra separato da virgole solo perché un articolo di blog lo ha fatto; scoprite quale dei vostri proxy aggiunge, quale sostituisce e quale conserva il campo in ingresso. NGINX, per esempio, può percorrere l’elenco a ritroso rispetto al proprio insieme fidato e fermarsi al primo indirizzo che non possiede, e questa è la regola di quel prodotto, non una legge che ogni framework segua. Leggete la documentazione del vostro proxy con le stesse due domande: quale valore seleziona e in quali mittenti crede?
Scrivete la catena: ordine dei salti, quale salto imposta il campo e quale salto elimina le copie in ingresso. Poi tenete quella nota accanto alla configurazione del proxy, non solo nel ticket. Poi provatela inviando una richiesta con un’intestazione falsificata attraverso il processo di validazione approvato e confermando che l’origine la ignora.
Quando aggiungete un salto, rivedete quel documento. Un nuovo bilanciatore di carico inserito davanti al proxy fidato può cambiare quale indirizzo vince senza che nessuno modifichi l’applicazione.
Tenete entrambe le osservazioni nel registro
Dove la diagnostica è autorizzata, registrate il peer della connessione e l’indirizzo client normalizzato come due campi separati, e aggiungete solo i metadati di inoltro di cui lo scopo ha realmente bisogno. Poi dimostrate il deployment con due richieste: una tramite il proxy che dovrebbe registrare entrambi i valori in modo sensato, e un tentativo diretto all’origine che deve essere rifiutato.
Ricordate che cosa significa la coppia. L’intestazione aggiunge un contesto fornito da un componente che avete scelto di fidarvi; il peer resta l’unico indirizzo che il vostro host ha realmente visto. Nessuno dei due è prova di identità individuale, e un progetto che tratti l’uno o l’altro come prova sbaglierà su qualcuno.