Radius - Freeradius

Per capire fino in fondo le tonnellate di informazioni che ho scritto con l'articolo sulla wireless security  ho deciso di testare il funzionamento di una rete wi-fi in modalità WPA2-ENTERPRISE. Quindi iniziamo con l'installazione di un server radius, in questo caso freeradius.

Per generare chiavi e certificati ci metterà un po'...
freeradius-utils viene installato automaticamente, su fedora invece è un rpm separato
Poi blocco il demone che fa partire automaticamente

e lo levo dall'elenco dei servizi che partono in automatico

I file di configurazione sono in /etc/freeradius (mentre in fedora, e sulle guide, sono in /etc/raddb)
Mi faccio una copia

Nel file client.conf ci sono le indicazioni di quali NAS (network access serer, gli access point o router) andranno ad accedere al server freeradius. Di base c'è una voce per localhost, quindi permette di accedere a se stesso e serve più che altro per le prove, ci sono poi mille esempi per le esigenze più disparate. Io aggiungo l'ip del mio access point.

Vado poi nel file users e aggiungo all'inizio del file queste 2 righe per questi 2 utenti di prova

Faccio partire il server in modalità debug lanciando

Se tutto va bene ti trovi come ultima riga
Ready to process requests.

Ora apro un'altra shell e faccio una prova col comando

(il mio secondo utente)

Quello 0 è il nas-port-number, da manuale
The value of the NAS-Port attribute is an integer between 0 and 2^31, and it really doesn't matter what you put here. 10 will do fine.
Penso serva perchè il server radius può essere utilizzato per autenticare le porte di uno switch cablato. Il protocollo 802.1x in origine era fatto per un'autenticazione port-based di una rete cablata, quindi lo switch dice al server radius di quale porta si sta parlando (penso che poi in qualche modo sta cosa si potrà configurare con opzioni personalizzate a seconda della porta).

Se tutto va bene la risposta a al comando è

Sul server in modalità debug  vedrò cosa succede nel processare quel comando
Si dovrebbe vedere che prova vari metodi di autenticazione, chap, digest, mschap senza successo, poi prova a vedere se si sta utilizzando il protocollo eap senza successo,  poi scopre che nel file degli utenti ce n'è uno che corrisponde “[files] users: Matched entry pelato at line 2” , poi prova pap e scopre che “Found Auth-Type = PAP”, confronta le credenziali e “[pap] User authenticated successfully”

Quel Frame-Protocol = PPP  ci dice che per comunicare al server radius sta usando il protocollo PPP e non EAP, visto che qui si tratta solo di un test effettuato peraltro non su una rete wireless, quindi per l'autentica/autorizzazione usa pap e non il modulo eap.

Con delle credenziali sbagliate invece ottengo

Questo era solo un semplice test.

PEAP_MD5
Ora proviamo ad autenticarci da un client tramite un NAS utilizzando WPA2 Enterprise con PEAP e MD5 come autenticazione (inner authentication, phase 2 authentication o come lo vuoi chiamare)

Andiamo a modificare il file radiusd.conf, o, nelle ultime versioni, nella sottodirectory sites-enabled il file default (che è incluso in radiusd.conf)

Guardo la sezione authorize (la prima) (si occupa del fornire gli specifici servizi a un utente, basati sui servizi disponibili in base all'autenticazione)
Dovresti vedere cose tipo se filtrare la stringa dello username in qualche modo, se modificare al volo la stringa (tipo metterla tutta in maiuscolo), se effettuare i log. Poi le cose che ci interessano, ovvero i moduli supportati. Notiamo che, in base al modulo che richiede il client, lui modifica al volo l'attributo (nel nostro caso nel file users sostituendo Cleartex-Password := FOO con Auth-Type := FOO)in modo che tu non debba creare un utente diverso per ogni sistema di autentica e quindi si possa tenere “Cleartext-Password” indipendentemente dal metodo utilizzato (sempre che si usi l'elencone e non un db degli utenti remoto tipo ldap).
L'importante in questa sezione è che ci sia il modulo eap e files.

Ora la sezione authentication (la conferma che, un utente che sta richiedendo serivizi, è un utente valido per i servizi richiesti)
Gia sappiamo dalla precedente sezione quale metodo andremo a usare guardando l'attributo Auth-Type di cui abbiam parlato sopra. Quindi usando l'attributo Auth-Type andremo a utilizzare il modulo corrispondente in questa sezione.
Se si usa eap, e in particolare eap_md5 l'importante è che in questo file ci sia eap. Poi c'è un file apposito chiamato eap.conf dove ci sono tutte le modalità di autenticazione utilizzate da eap, tra cui anche md5 (che incidentalmente di default è il default)

Faccio partire freeradius -X (sempre in modalità debug)

Configuro l'access point per contattare il server radius (nel mio caso 192.168.1.220) con wpa2-enterprise, crittazione AES, segreto precondiviso “testing123”.

Provo a connetermi alla rete wireless con un client (ubuntu) specificando

Sicurezza: WPA2-Enterprise
Authentication: PEAP
Nessuna identità anonima, nessun certificato
Inner authentication (fase 2):MD5
Utente/password: pelato/pelati

Premesso che funziona, le righe significative nel debug del server sono, affogate nei vari passaggi che servono a contrattare le chiavi, creare il tunnel, distruggerlo etc..

In authorization
[files] users: Matched entry pelato at line 2
++[files] returns ok
Found Auth-Type = EAP
In authentication
[eap] Request found, released from the list
[eap] EAP/peap
[eap] processing type peap
[eap] EAP-NAK asked for EAP-Type/md5
[eap] processing type md5
rlm_eap_md5: Issuing Challenge
++[eap] returns handled

EAP_TTLS e MSCHAPv2 SENZA verifica del certificato server
Provo ora a testare WPA2 Enterprise con EAP_TTLS e MSCHAPv2, su un client (ubuntu) dovrò specificare:

Sicurezza: WPA2-Enterprise
Authentication: Tunneled TLS (EAP_TTLS)
Nessuna identità anonima, nessun certificato
Inner Authentication (fase2): MSCHAPv2
Utente/password robiolo//robiola

Funziona e avremo nei log/debug

In authorization
Found Auth-Type = EAP
[eap] EAP/ttls
[eap] processing type ttls
[ttls] Authenticate
[mschap] Found MS-CHAP attributes.  Setting 'Auth-Type  = mschap'
++[mschap] returns ok
Found Auth-Type = MSCHAP
+- entering group MS-CHAP {...}
[mschap] Creating challenge hash with username: robiolo
[mschap] Told to do MS-CHAPv2 for robiolo with NT-Password
[mschap] adding MS-CHAPv2 MPPE keys
++[mschap] returns ok

Insomma, sebbene i log non siano chiarissimi le cose funzionano correttamente proprio come mi aspetto.

NOTE: Da client, settare la sicurezza a WPA-ENTERPRISE implica di voler usare 802.1x/EAP, per cui nel server radius verdrò sempre che viene usato il module eap per autentica/autorizzazione.
Come metodi di autenticazione di eap poi viene usato la prima volta PEAP (e poi md5) e la seconda volta TTLS (e poi mschapv2)

Mi rimane da provare ad utilizzare il certificato del server nelle modalità gia sperimentate EAP_TTLS, PEAP e sopratutto EAP_TLS coi certificati sia di server che di client

I certificati in fedora  li trovi li trovi in /etc/raddb/certs e in questa stessa directory ci sono gli script per la creazione e configurazione degli stessi.
Su ubuntu invece i certificati stanno in /etc/freeradius/certs e gli script di creazione e configurazione  degli stessi stanno in /usr/share/doc/freeradius/examples/certs.
In fase di installazione di freeradius gia crea dei certificati di prova.

Nel file di configurazione di eap di freeradius /etc/raddb/eap.conf nella sezione tls trovi le direttive che puntano di default alla directory sopra-indicata. La sezione tls quindi conterrà sia le configurazioni per il metodo eap_tls, sia le parti inerenti ai certificati per gli altri 2 metodi (eap_ttls, eap_peap).

Puoi leggere il file readme per la creazione dei certificati: In sostanza modifica i file di configurazione  ca.cnf, client.cnf e server.cnf mettendo i tuoi dati e poi rilancia i vari script di creazione (make server.pem etc..)

EAP_TTLS con certificato di server
Per la prima prova non modifico niente in quanto mi servo dei certificati di default creati (e che volendo si possono ricreare lanciando il comando bootstrap).
Mi copio il file /etc/freeradius/certs/ca.pem sul client da cui mi connetterò.

Cerco di collegarmi alla rete appena creata usando:

Sicurezza: WPA2-Enterprise
Authentication: Tunneled TLS (EAP_TTLS)
Nessuna identità anonima,
CA Certificate: ca.pem (quello creato sul server e poi copiato sul client. Se il certificato è “buono” e non fatto con un PKI casalinga, su alcuni sistemi tipo windows puoi specificare l'indirizzo della CA in modo che si scarichi automaticamente il tutto)
Inner Authentication (fase2): MSCHAPv2
Utente/password robiolo//robiola

Se il client volesse vedere/verificare il contenuto del certificato basterebbe digitare

In sostanza il server mi manda il suo certificato e io con la public key del ca.pem verifico che sia davvero chi dice di essere.

Così facendo tutto mi funziona correttamente e nel debug del server radius ti troverai le voci che ti confermano l'utilizzo del certificato.

Nota che non puoi imporre al client di verificare il certificato del server in quanto questa è una configurazione che va fatta appunto sul client.

EAP_TLS
Per la seconda prova devo creare un certificato client per ogni  client (utente) che voglio far connettere alla rete.Serve anche il certificato server. Tutti questi certificati devono essere firmati dalla stessa CA e tutti si devono fidare di questa CA.
Quindi non basta un certificato server self-signed ma serve proprio creare una PKI.

Vado quindi in /usr/share/doc/freeradius/examples/certs e modifico solo la sezione [client] lasciando il resto inalterato in modo che tutte le password siano quelle di default.

E' importante che i dati corrispondano a quelli che hai messo in ca.cnf e server.cnf (tranne l'utente ovviamente) e, visto che per questa prova ho tenuto tutto ciò che c'era di defautl, anche qui non posso modificare altro se non l'utente.

Poi lancio

che ricrea i certificati farlocchi per il server e per la ca (questo passaggi mi è servito perchè lanciare subito make client.pem dava degli errori)
e

Questo ultimo comando mi va a creare il certificato client corrispondente al nome (gabriele@gabrielemerli.com.pem) che altro non è che una copia di client.pem, e la chiave privata e criptata dello stesso utente (client.key)

Ora vado a mettere alcuni certificati/chiavi che ho appena ricreato in /etc/freeradius/cert

E sempre in /etc/freeradius/cert metto anche il certificato client appena creato (gabriele@gabrielemerli.com.pem) (non credo serva, vedi dopo)

Mi copio sul client  gabriele@gabrielemerli.com.pem,  ca.pem,  client.key
e poi provo a connettermi con questi dati:

Sicurezza: WPA2-Enterprise
Authentication: TLS
Identity: gabriele@gabrielemerli.com
User Certificate:  gabriele@gabrielemerli.com.pem
CA Certificate: ca.pem
Private Key: client.key
Private Key Password: whatever

Nota che la password della chiave privata del client è rimasta quella di default settata in client.cnf

Poi provo a creare un'altro utente, modifico client.conf in questo modo
input_password          = simona
output_password         = simona
emailAddress            = simona@gabrielemerli.com
commonName              = simona@gabrielemerli.com

Ricreo il certificato del client digitando

Copio in /etc/freeradius/certs il certificato appena creato (non so se serva questo passaggio, in teoria no visto che radius non è che confronta il certificato del client che ha memorizzato con quello che il client gli passa, ma si limita a verificare che sia firmato dalla giusta ca per avere certezza che l'utente è chi dice di essere)

Mi copio su un'altro client ca.pem, simona@gabrielemerli.com.pem, client.key e provo a connettermi con quest'altra identità (simona@gabrielemerli.com) e con la password “simona” e anche questo funziona.

Quindi, ogni utente che vai a creare devi poi copiare sul client il certificato e la chiave utente (e conoscere la password per sbloccare la chiave). Oltre a questo il client deve avere il certificato della ca o scaricarselo da una ca certificata.

In sostanza quindi il server mi manda il suo certificato e io client verifico con la public key del ca.pem che sia davvero chi dice di essere.
Io client mando al server il mio certificato e lui con la public key del  ca.pem verifica che anche il client sia chi dice di essere->Gia questo fatto di per se implica che è un utente buono, poi il fatto di specificare un nome utente viene usato penso per le autorizzazioni specifiche.
Ciascun client deve poi avere anche la propria chiave privata e la password della stessa. (in questo modo il client ha la sua chiave pubblica -nel certificato- e la sua chiave privata). Manda la chiave pubblica al server nella forma del certificato che verrà poi verificato e poi il server la userà per parlare poi al client che decritta con la sua chiave privata.

Ovviamente, visto che per creare i certificati di ciascun client li ho dovuti firmare con la chiave privata della ca, questo funziona se mi sono creato un'infrastruttura PKI casalinga, di certo non vado a chiedere a verisign n certificati per gli n client che voglio che si connettano alla mia rete...

Se guardi il readme nella directory certs dice che il certificato del client lo firma col certificato del server, ma non è vero se poi vai a guardare i singoli comandi nel Makefile si vede benissimo che lo firma con la chiave privata della ca.

openssl req -new  -out client.csr -keyout client.key -config ./client.cnf
REQ -> The req command primarily creates and processes certificate requests in PKCS#10 format. It can additionally create self signed certificates for use as root CAs for example.
-new -> this option generates a new certificate request  It will prompt the user for the relevant field values. (le solite cose tipo stato, provincia, nome etc)
If the -key option is not used it will generate a new RSA private key using information specified in the configuration file.
-out -> This specifies the output filename to write to or standard output by default.
-keyout -> this gives the filename to write the newly created private key to. If this option is not specified then the filename present in the configuration file is used.
Questo comando in pratica crea la chiave privata e il certificato non firmato (o la certificate request da firmare da parte della ca)

openssl ca -batch -keyfile ca.key -cert ca.pem -in client.csr  -key $(PASSWORD_CA) -out client.crt -extensions xpclient_ext -extfile xpextensions -config ./client.cnf
-keyfile -> the private key to sign requests with.
-cert -> the CA certificate file.
-in -> an input filename containing a single certificate request to be signed by the CA.
-key -> the password used to encrypt the private key. Since on some systems the command line arguments are visible (e.g. Unix with the 'ps' utility) this option should be used with caution.
-out -> the output file to output certificates to. The default is standard output. The certificate details will also be printed out to this file.
Questo comando firma il certificato del client con la chiave privata della CA

Penso che si possa benissimo far firmare alla ca  (verisign o simili) il solo certificato server e poi firmarsi in casa con la chiave privata del server i certificati dei client poi da distribuire: In ultima analisi è il server che deve autenticare e lo può fare o fidandosi della ca (come detto prima, comodo se la ca è lui stesso) oppure agendo in prima persona.
Per ottenere questo risultato basta modificare il Makefile nella sezione del client, nella creazione di client.crt modifica il comando mettendo il certificato del server e la chiave del server e non quello della ca come di default. Per semplicità modifica anche i vari server.cnf e client.cnf in modo che countryName, stateOrProvinceName, localityName  siano tutti “optional” e non “match” in modo da poter scrivere ciò che si vuole. Una volta poi fatto il make client.pem verifica nel certificato del client appena creato che
openssl x509 -in client.pem -text -noout
l'issuer (ovvero il rilasciante) non sia la ca ma il server.

Print Friendly, PDF & Email