Bylothink / do-you-dare

🎴 A web-game based on the original game of "Truth or Dare?" with different game modes.
https://doyoudare.cards
Other
0 stars 0 forks source link

Verificare il corretto funzionamento del limite di richieste per minuto in produzione #56

Open Byloth opened 1 year ago

Byloth commented 1 year ago

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:

HTTP_X_FORWARDED_FOR="89.87.121.212"
HTTP_X_REAL_IP="89.87.121.212"

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:

HTTP_X_FORWARDED_FOR="89.87.121.212, 100.99.88.77"
HTTP_X_REAL_IP="100.99.88.77"

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:

HTTP_X_FORWARDED_FOR="192.168.0.13, 89.87.121.212"
HTTP_X_REAL_IP="89.87.121.212"

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:

HTTP_X_FORWARDED_FOR="192.168.0.13, 89.87.121.212, 100.99.88.77"
HTTP_X_REAL_IP="100.99.88.77"

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:

  1. Splitto l'HEADER HTTP_X_FORWARDED_FOR sul carattere , ottenendo una lista di IP.
  2. Parto ciclando la pimo.
  3. Eseguo uno strip per eliminare eventuali spazi (abbiamo la certezza assoluta che ci sia sempre una virgola seguita da uno spazio?).
  4. Se sono arrivato alla fine della lista, lo prendo per buono (non posso far altro, anche volendo).
  5. 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
  6. SE inizia con 172, controllo se il secondo gruppo di numeri è compreso tra 16 e 31 (inclusi).
  7. Se i controlli precedenti, risultano essere positivi in qualche caso, l'IP viene ignorato e si ricominciano i controlli sull'IP successivo.
  8. 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.