Ho appena messo online -finalmente- una versione dell'applicazione da cui ho potuto leggere gli effettivi HEADERS aggiunti da Traefik.
Quelli che ci interessano sono: HTTP_X_FORWARDED_FOR e HTTP_X_REAL_IP.
Edge-cases
Descrizione del problema
Caso semplice
Questi due HEADERS presentano il medesimo valore se il client che esegue la richiesta non si trova dietro ad alcun server proxy; di seguito un esempio:
In questo caso, l'IP reale del client effettivo che ci interessa, risulta essere il primo elencato in HTTP_X_FORWARDED_FOR.
Gli altri fanno riferimento al server proxy intermedio e non sono di nostro interesse.
Caso con proxy privato
Potrebbe verificarsi un edge-case in cui, se il proxy dovesse essere interno ad una rete privata, gli HEADERS potrebbero assumere un valore in contrasto, con quello appena detto:
In questo caso, il primo IP risulta essere un IP interno di una rete privata; ergo, l'IP reale del client effettivo che ci interessa, risulta essere il secondo elencato.
Caso con proxy pubblico e privato
Mettendo insieme tutte queste casistiche, si potrebbe anche ottenere una casistica ancora più insolita:
In questo caso, l'IP reale del client effettivo che ci interessa, risulta essere il secondo elencato in quanto -il primo- risulta essere un IP interno ad una rete privata e -l'ultimo- risulta essere l'IP di un proxy pubblico.
Soluzione
L'algoritmo di selezione dell'indirizzo IP presumibilmente più corretto, dovrebbe funzionare -quindi- nella seguente maniera:
Splitto l'HEADER HTTP_X_FORWARDED_FOR sul carattere , ottenendo una lista di IP.
Parto ciclando la pimo.
Eseguo uno strip per eliminare eventuali spazi (abbiamo la certezza assoluta che ci sia sempre una virgola seguita da uno spazio?).
Se sono arrivato alla fine della lista, lo prendo per buono (non posso far altro, anche volendo).
Viceversa, controllo se l'IP ottenuto inizia con una delle seguenti formule:
10.X.X.X
127.X.X.X(in linea teorica, non dovrebbe MAI esser presente)
172.X.X.X
192.168.X.X
SE inizia con 172, controllo se il secondo gruppo di numeri è compreso tra 16 e 31 (inclusi).
Se i controlli precedenti, risultano essere positivi in qualche caso, l'IP viene ignorato e si ricominciano i controlli sull'IP successivo.
Continuo fino a quando i controlli non trovano corrispondenza oppure sono arrivato all'ultimo IP della lista.
Dettagli aggiuntivi riguardo agli IP riservati alle reti private, qui: RFC1918.
Ho appena messo online -finalmente- una versione dell'applicazione da cui ho potuto leggere gli effettivi HEADERS aggiunti da Traefik.
Quelli che ci interessano sono:
HTTP_X_FORWARDED_FOR
eHTTP_X_REAL_IP
.Edge-cases
Descrizione del problema
Caso semplice
Questi due HEADERS presentano il medesimo valore se il client che esegue la richiesta non si trova dietro ad alcun server proxy; di seguito un esempio:
In questo caso, l'IP reale del client effettivo che ci interessa, è il medesimo; un HEADER vale l'altro.
Caso con proxy pubblico
Se il client dovesse trovarsi dietro un server proxy (supponiamo con IP
100.99.88.77
), i due HEADERS assumerebbero un valore diverso:In questo caso, l'IP reale del client effettivo che ci interessa, risulta essere il primo elencato in
HTTP_X_FORWARDED_FOR
.Gli altri fanno riferimento al server proxy intermedio e non sono di nostro interesse.
Caso con proxy privato
Potrebbe verificarsi un edge-case in cui, se il proxy dovesse essere interno ad una rete privata, gli HEADERS potrebbero assumere un valore in contrasto, con quello appena detto:
In questo caso, il primo IP risulta essere un IP interno di una rete privata; ergo, l'IP reale del client effettivo che ci interessa, risulta essere il secondo elencato.
Caso con proxy pubblico e privato
Mettendo insieme tutte queste casistiche, si potrebbe anche ottenere una casistica ancora più insolita:
In questo caso, l'IP reale del client effettivo che ci interessa, risulta essere il secondo elencato in quanto -il primo- risulta essere un IP interno ad una rete privata e -l'ultimo- risulta essere l'IP di un proxy pubblico.
Soluzione
L'algoritmo di selezione dell'indirizzo IP presumibilmente più corretto, dovrebbe funzionare -quindi- nella seguente maniera:
HTTP_X_FORWARDED_FOR
sul carattere,
ottenendo una lista di IP.10.X.X.X
127.X.X.X
(in linea teorica, non dovrebbe MAI esser presente)172.X.X.X
192.168.X.X
172
, controllo se il secondo gruppo di numeri è compreso tra16
e31
(inclusi).Dettagli aggiuntivi riguardo agli IP riservati alle reti private, qui: RFC1918.