2.6. SPI e cookie IKE SA
2.6. SPI e cookie IKE SA
I primi due campi di otto ottetti nell'intestazione, chiamati "IKE SPIs", sono utilizzati come identificatore di connessione all'inizio dei pacchetti IKE. Ciascun endpoint sceglie uno dei due SPI e DEVE sceglierli in modo che siano identificatori univoci di una IKE SA. Un valore SPI di zero è speciale: indica che il valore SPI remoto non è ancora noto al mittente.
I pacchetti IKE in arrivo sono mappati a una IKE SA utilizzando solo lo SPI del pacchetto, non (ad esempio) l'indirizzo IP sorgente del pacchetto.
A differenza di ESP e AH dove solo lo SPI del ricevente appare nell'intestazione di un messaggio, in IKE lo SPI del mittente viene inviato anch'esso in ogni messaggio. Poiché lo SPI scelto dall'iniziatore originale della IKE SA viene sempre inviato per primo, un endpoint con multiple IKE SA aperte che vuole trovare la IKE SA appropriata utilizzando lo SPI da esso assegnato deve guardare il flag Initiator nell'intestazione per determinare se ha assegnato i primi o i secondi otto ottetti.
Nel primo messaggio di uno scambio IKE iniziale, l'iniziatore non conoscerà il valore SPI del risponditore e pertanto imposterà tale campo a zero. Quando lo scambio IKE_SA_INIT non produce la creazione di una IKE SA a causa di INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN o COOKIE (vedere sezione 2.6), lo SPI del risponditore sarà zero anche nel messaggio di risposta. Tuttavia, se il risponditore invia uno SPI di risponditore non nullo, l'iniziatore non deve rifiutare la risposta solo per questo motivo.
Due attacchi previsti contro IKE sono l'esaurimento di stato e di CPU, in cui il bersaglio viene inondato da richieste di inizializzazione di sessione provenienti da indirizzi IP falsificati. Questi attacchi possono essere resi meno efficaci se un risponditore utilizza CPU minima e non impegna alcuno stato per una SA finché non sa che l'iniziatore può ricevere pacchetti all'indirizzo da cui afferma di inviarli.
Quando un risponditore rileva un gran numero di IKE SA semi-aperte, DOVREBBE rispondere alle richieste IKE_SA_INIT con una risposta contenente la notifica COOKIE. I dati associati a questa notifica DEVONO essere di lunghezza compresa tra 1 e 64 ottetti (inclusi), e la sua generazione è descritta più avanti in questa sezione. Se la risposta IKE_SA_INIT include la notifica COOKIE, l'iniziatore DEVE quindi ritentare la richiesta IKE_SA_INIT, e includere la notifica COOKIE contenente i dati ricevuti come primo payload, e tutti gli altri payload invariati. Lo scambio iniziale sarà quindi il seguente:
Initiator Responder
HDR(A,0), SAi1, KEi, Ni --> <-- HDR(A,0), N(COOKIE) HDR(A,0), N(COOKIE), SAi1, KEi, Ni --> <-- HDR(A,B), SAr1, KEr, Nr, [CERTREQ] HDR(A,B), SK {IDi, [CERT,] [CERTREQ,] [IDr,] AUTH, SAi2, TSi, TSr} --> <-- HDR(A,B), SK {IDr, [CERT,] AUTH, SAr2, TSi, TSr}
I primi due messaggi non influenzano alcuno stato dell'iniziatore o del risponditore eccetto per comunicare il cookie. In particolare, i numeri di sequenza dei messaggi nei primi quattro messaggi saranno tutti zero e i numeri di sequenza dei messaggi negli ultimi due messaggi saranno uno. 'A' è lo SPI assegnato dall'iniziatore, mentre 'B' è lo SPI assegnato dal risponditore.
Un'implementazione IKE può implementare la generazione del suo cookie di risponditore in modo tale da non richiedere alcuno stato salvato per riconoscere il suo cookie valido quando il secondo messaggio IKE_SA_INIT arriva. Gli algoritmi e la sintassi esatti utilizzati per generare i cookie non influenzano l'interoperabilità e pertanto non sono specificati qui. Segue un esempio di come un endpoint potrebbe utilizzare i cookie per implementare una protezione DoS limitata.
Un buon modo per farlo è impostare il cookie di risponditore come:
Cookie =
dove
Se un nuovo valore per
Quando una parte riceve una richiesta IKE_SA_INIT contenente un cookie il cui contenuto non corrisponde al valore atteso, tale parte DEVE ignorare il cookie ed elaborare il messaggio come se non fosse incluso alcun cookie; di solito ciò significa inviare una risposta contenente un nuovo cookie. L'iniziatore dovrebbe limitare il numero di scambi di cookie che tenta prima di abbandonare, possibilmente utilizzando un back-off esponenziale. Un attaccante può falsificare multiple risposte cookie al messaggio IKE_SA_INIT dell'iniziatore, e ciascuna di quelle risposte cookie falsificate causerà l'invio di due pacchetti: un pacchetto dall'iniziatore al risponditore (che rifiuterà quei cookie), e una risposta dal risponditore all'iniziatore che include il cookie corretto.
Una nota sulla terminologia: il termine "cookies" origina da Karn e Simpson [PHOTURIS] in Photuris, una proposta iniziale per la gestione delle chiavi con IPsec, ed è persistito. L'intestazione dei messaggi fissa dell'Internet Security Association and Key Management Protocol (ISAKMP) [ISAKMP] include due campi di otto ottetti chiamati "cookies", e tale sintassi è utilizzata sia da IKEv1 che da IKEv2, sebbene in IKEv2 essi siano indicati come "IKE SPI" e vi sia un nuovo campo separato in un payload Notify che contiene il cookie.
2.6.1. Interazione tra COOKIE e INVALID_KE_PAYLOAD
Ci sono due ragioni comuni per cui l'iniziatore potrebbe dover ritentare lo scambio IKE_SA_INIT: il risponditore richiede un cookie o vuole un gruppo Diffie-Hellman diverso da quello incluso nel payload KEi. Se l'iniziatore riceve un cookie dal risponditore, l'iniziatore deve decidere se includere il cookie solo nel prossimo ritentativo della richiesta IKE_SA_INIT, o anche in tutti i ritentativi successivi.
Se l'iniziatore include il cookie solo nel prossimo ritentativo, in alcuni casi potrebbe essere necessario un round trip aggiuntivo. Un round trip aggiuntivo è necessario anche se l'iniziatore include il cookie in tutti i ritentativi, ma il risponditore non lo supporta. Ad esempio, se il risponditore include i payload KEi nel calcolo del cookie, rifiuterà la richiesta inviando un nuovo cookie.
Se entrambi i peer supportano l'inclusione del cookie in tutti i ritentativi, può avvenire uno scambio leggermente più breve.
Initiator Responder
HDR(A,0), SAi1, KEi, Ni --> <-- HDR(A,0), N(COOKIE) HDR(A,0), N(COOKIE), SAi1, KEi, Ni --> <-- HDR(A,0), N(INVALID_KE_PAYLOAD) HDR(A,0), N(COOKIE), SAi1, KEi', Ni --> <-- HDR(A,B), SAr1, KEr, Nr
Le implementazioni DOVREBBERO supportare questo scambio più breve, ma NON DEVONO fallire se altre implementazioni non lo supportano.