Freeradius: AD domain users authentication and filter by domain groups

L’obiettivo è quello di permettere l’autenticazione radius di utenti di dominio per l’accesso telnet ad uno o più apparati di rete. Nel mio caso utilizzerò uno switch C2960. L’accesso dovrà essere consentito solamente agli utenti appartenenti ad un determinato gruppo del dominio e dovrà fornire loro il livello 15 di privilegi (il massimo livello).

Freeradius grazie all’utility samba ntlm_auth consentirà l’autenticazione degli utenti del dominio.

Prima di iniziare consiglio la lettura attenta di questo sito per comprendere i metodi di autenticazione di Freeradius. Se l’avessi letto io quando ho iniziato la configurazione la prima volta avrei risparmiato davvero tanto tempo. La documentazione seguita: wiki ufficiale, simweb.ch,  e alcune indicazioni contenute in freeradius.1045715…, in particolare per lo script scritto da Scott McLane Gardner.

Questo articolo presuppone che abbiate già a disposizione un dominio active directory gestito (in esclusiva o inserito in un dominio Windows pre-esistente) da samba 4. Questo articolo vi spiegherà passo passo come fare.

Freeradius andrà installato sullo stesso server, nel mio caso Ubuntu 14.40 LTS Server.

1. Installazione e configurazione freeradius

Iniziamo con l’installazione di alcune dipendenze necessarie a freeradius

# apt-get install snmp libtalloc-dev libssl-dev

Ora scarichiamo i sorgenti di openssl e di freeradius direttamente dai siti ufficiali oppure dal mio server: openssl-1.0.1j.tar e freeradius-server-3.0.4.tar

Ci spostiamo nella directory dove abbiamo scaricato gli archivi e  compiliamo e installiamo openssl:

# tar -xvf openssl-1.0.1j.tar 
# cd openssl-1.0.1j/
# ./config --prefix=/usr/local/openssl shared
# make
# make install

Il primo comando scompatta l’archivio tar, il secondo ci fa entrare nella directory scompattata, il terzo esegue uno script di shell che fa un check per i requisiti di sistema, il quarto costruisce i binari (richiede un po’ di tempo), il quinto esegue le istruzioni di installazione.

Ora è la volta di freeradius:

# tar -xvf freeradius-server-3.0.4.tar 
# cd freeradius-server-3.0.4/
# ./configure
# make
# make install

Ora lavoriamo ai file di configurazione.

Entriamo nel file /usr/local/etc/raddb/clients.conf e alla fine inseriamo la rete dalla quale verranno le richieste di autenticazione, con la password di autenticazione e il nas_type:

# vim /usr/local/etc/raddb/clients.conf
....
client 192.168.201.0/24 {
 secret = testing123
 shortname = ReteCOS
 nas_type = cisco
 }
......

Ora modifichiamo il file /usr/local/etc/raddb/users, dopo aver salvato, per sicurezza, la versione originale:

# cp /usr/local/etc/raddb/users /usr/local/etc/raddb/users_orig

Inseriamo in users alcuni utenti di test (per i quali verrà bypassata l’autenticazione da dominio):

....
# The canonical testing user which is in most of the
# examples.
testuser1 Cleartext-Password := "testuser1!", MS-CHAP-Use-NTLM-Auth := 0
testuser2 Cleartext-Password := "testuser2!", MS-CHAP-Use-NTLM-Auth := 0
testuser3 Cleartext-Password := "testuser3!", MS-CHAP-Use-NTLM-Auth := 0
....

Notare che “MS-CHAP-Use-NTLM-Auth := 0″ indica proprio che l’autenticazione dell’utente indicato non dovrà essere processata da ntlm_auth ma avvenire “localmente” tramite il file di configurazione.

Verificare poi che il file di configurazione inner-tunnel contenga la seguente indicazione:

# cat /usr/local/etc/raddb/sites-available/inner-tunnel
...
...
authorize {
 ...
 # Read the 'users' file
 files # <--- questo
 ...
 pap # <--- e questo
}

Ora in /usr/local/etc/raddb/radiusd.conf, sezione security, aggiungere il parametro:
allow_vulnerable_openssl = ‘CVE-2014-0160′

# vim /usr/local/etc/raddb/radiusd.conf
...
...
security {
 allow_core_dumps = no
 max_attributes = 200
 reject_delay = 1
 status_server = yes
 allow_vulnerable_openssl = 'CVE-2014-0160' # <- questo parametro va confiurato
}
...

Ora possiamo effettuare un primo test, cercando di autenticare gli utenti che abbiamo inserito in “users”.

1.1 test autenticazione utenti in “file”

Avviamo il servizio radius in modalità debug:

# radiusd -X

Su altra macchina Linux installare le freeradius-utils per il test dell’autenticazione freeradius

$ sudo apt-get install freeradius-utils

NB Nel prossimo comando troviamo la parola chiave “testing123″, che dovrà essere configurata uguale in /usr/local/etc/raddb/clients.conf, nella sezione “client” che da poco abbiamo inserito.
Eseguire il test:

$ radtest testuser1 testuser1! 192.168.201.136 0 testing123
Sending Access-Request of id 197 to 192.168.201.136 port 1812
 User-Name = "testuser1"
 User-Password = "testuser1!"
 NAS-IP-Address = 127.0.1.1
 NAS-Port = 0
 Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 192.168.201.136 port 1812, id=197, length=20

L’autenticazione è riuscita.

1.2 Configurazione freeradius per autenticazione utenti di dominio

Per permettere a freeradius di autenticare gli utenti di dominio è necessario il binario ntlm_auth, fornito dal pacchetto “winbind”. Installiamo quindi winbind:

# apt-get install winbind

Testare l’autenticazione tramite binario ntlm_auth:

# ntlm_auth --request-nt-key --domain=DOMINIOSAMBA --username=administrator
Password: 
NT_STATUS_OK: Success (0x0)

e ancora:

# ntlm_auth --request-nt-key --domain=DOMINIOSAMBA.IT --username=pippo
assword: 
NT_STATUS_OK: Success (0x0)

Per altri test possiamo utilizzare wbinfo:

wbinfo -u -> lista tutti gli utenti di dominio
-u, –domain-users -> Lists all domain users
-g, –domain-groups -> Lists all domain groups
–user-info=USER-> Get user info
–user-groups=USER-> Get user groups
–authenticate=user%password-> authenticate user

Alcuni esempi:

# wbinfo --user-info=administrator
DOMINIOSAMBA\Administrator:*:0:100::/home/DOMINIOSAMBA/Administrator:/bin/false
# wbinfo --user-info=guest
DOMINIOSAMBA\Guest:*:3000011:3000012::/home/DOMINIOSAMBA/Guest:/bin/false
# wbinfo --user-groups=administrator
100
3000004
3000006
3000008
3000007

Ora configuriamo opportunamente il file di configurazione di ntlm_auth gestito da freeradius. Sostanzialmente inseriamo il path al binario e il nome del nostro dominio:

# vim /usr/local/etc/raddb/mods-enabled/ntlm_auth
exec ntlm_auth {
 wait = yes
 program = "/usr/bin/ntlm_auth --request-nt-key --domain=DOMINIOSAMBA.IT --username=%{mschap:User-Name} --password=%{User-Password}"
}

Se ora proviamo a fare il radtest di prima cercando l’autenticazione di un utente di dominio, l’utente non sarà autenticato. Analizzando il debug di freeradius (ottenuto avviandolo con l’opzione “-X”) si vedrà che il problema è relativo al fatto che freeradius non riesce a gestire correttamente la richiesta, non riuscendo ad identificare il tipo di autenticazione e dando quindi un:
(2) ERROR: No Auth-Type found: rejecting the user via Post-Auth-Type = Reject

$ radtest pippo pippo123! 192.168.201.136 0 testing123
Sending Access-Request of id 178 to 192.168.201.136 port 1812
 User-Name = "pippo"
 User-Password = "pippo123!"
 NAS-IP-Address = 127.0.1.1
 NAS-Port = 0
 Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Reject packet from host 192.168.201.136 port 1812, id=178, length=20

Il debug mostra:

.....
(2) WARNING: pap : No "known good" password found for the user. Not setting Auth-Type
(2) WARNING: pap : Authentication will fail unless a "known good" password is available
(2) [pap] = noop
(2) } # authorize = ok
(2) ERROR: No Auth-Type found: rejecting the user via Post-Auth-Type = Reject
.....
.....

Per risolvere il problema dobbiamo indicare a freeradius di utilizzare il protocollo PAP (possiamo quindi disabilitare tutto il resto) che a sua volta deve attivare il modulo ntlm_auth. O meglio: se l’Auth-Type non viene inviato dal client, aggiorna il “control” affinchè usi il proprio ntlm_auth che definito nella sezione authenticate.

fonte: http://www.simweb.ch/blog/2013/08/a-freeradius-for-your-switch-authentication/

Salviamo una copia del file default (sito di default) originale:

cp /usr/local/etc/raddb/sites-available/default /usr/local/etc/raddb/sites-available/default_orig

Poi tagliamo il contenuto della sezione “authorize” e “authenticate” incolliamo il contenuto seguente:

# vim /usr/local/etc/raddb/sites-available/default
authorize {
# If you are using multiple kinds of realms, you probably
# want to set "ignore_null = yes" for all of them.
# Otherwise, when the first style of realm doesn't match,
# the other styles won't be checked.
#
suffix

expiration
logintime
# Most switches support PAP only
 #
 # This module should be listed last, so that the other modules
 # get a chance to set Auth-Type for themselves.
 #
 pap
# If no Auth-Type was sent, we assume PAP but that we should
 # use ntlm_auth for AD authentication through ntlm_auth.
 if(!control:Auth-Type) {
 update control {
 Auth-Type = "ntlm_auth"
 }
 }
 }
authenticate {
 # For PAP against AD with ntlm_auth we need to
 # let Samba ntlm_auth do the authentication work.
 Auth-Type NTLM_AUTH {
 ntlm_auth
 }
># For local users with plaintext password we can still use LDAP
 # Reminder - you might disable update conrol in such casse in
 # authorize because it's an unconditinal update.
 Auth-Type PAP {
 pap
 }
 }

Se ora ripetiamo il test di prima otterremo la corretta autenticazione dell’utente:

$ radtest pippo pippo123! 192.168.201.136 0 testing123
Sending Access-Request of id 54 to 192.168.201.136 port 1812
 User-Name = "pippo"
 User-Password = "pippo123!"
 NAS-IP-Address = 127.0.1.1
 NAS-Port = 0
 Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 192.168.201.136 port 1812, id=54, length=20

E il debug di radiusd restituirà che nella fase di “authorize” (prima fase), freeradius non trova l’Auth-Type e quindi “sovrascrive” con “NTLM_AUTH”:

....
(0) # Executing section authorize from file /usr/local/etc/raddb/sites-enabled/default
(0) authorize {
(0) suffix : Checking for suffix after "@"
(0) suffix : No '@' in User-Name = "pippo", looking up realm NULL
(0) suffix : No such realm "NULL"
(0) [suffix] = noop
(0) [expiration] = noop
(0) [logintime] = noop
(0) WARNING: pap : No "known good" password found for the user. Not setting Auth-Type
(0) WARNING: pap : Authentication will fail unless a "known good" password is available
(0) [pap] = noop
(0) if (!control:Auth-Type) 
(0) if (!control:Auth-Type) -> TRUE
(0) if (!control:Auth-Type) {
(0) update control {
(0) Auth-Type = NTLM_AUTH
(0) } # update control = noop
(0) } # if (!control:Auth-Type) = noop
(0) } # authorize = noop
(0) Found Auth-Type = NTLM_AUTH
(0) # Executing group from file /usr/local/etc/raddb/sites-enabled/default
.....

L’Auth-Type NTLM_AUTH è configurato nella sezione “authorize” e quindi nella seconda fase di autenticazione freeradius lancia ntlm_auth seconda la configurazione che abbiamo precedentemente settato in /usr/local/etc/raddb/mods-enabled/ntlm_auth:

......
(0) Auth-Type NTLM_AUTH {
Executing: /usr/bin/ntlm_auth --request-nt-key --domain=DOMINIOSAMBA.IT --username=%{mschap:User-Name} --password=%{User-Password}:
(0) ntlm_auth : EXPAND --username=%{mschap:User-Name}
(0) ntlm_auth : --> --username=pippo
(0) ntlm_auth : EXPAND --password=%{User-Password}
(0) ntlm_auth : --> --password=pippo123!
Program returned code (0) and output 'NT_STATUS_OK: Success (0x0)'
(0) ntlm_auth : Program executed successfully
(0) [ntlm_auth] = ok
(0) } # Auth-Type NTLM_AUTH = ok
.......

La fase successiva e ultima, la fase “post-auth”, tutto procede senza problemi:

........
(0) # Executing section post-auth from file /usr/local/etc/raddb/sites-enabled/default
(0) post-auth {
(0) [exec] = noop
(0) remove_reply_message_if_eap remove_reply_message_if_eap {
(0) if (&reply:EAP-Message && &reply:Reply-Message) 
(0) if (&reply:EAP-Message && &reply:Reply-Message) -> FALSE
(0) else else {
(0) [noop] = noop
(0) } # else else = noop
(0) } # remove_reply_message_if_eap remove_reply_message_if_eap = noop
(0) } # post-auth = noop
(0) Sending Access-Accept packet to host 192.168.201.205 port 36553, id=54, length=0
Sending Access-Accept Id 54 from 192.168.201.136:1812 to 192.168.201.205:36553
(0) Finished request
Waking up in 0.2 seconds.
Waking up in 4.7 seconds.
(0) Cleaning up request packet ID 54 with timestamp +5
.........

2. Configurazione dello switch Cisco 2960 series

In questa sede non indicheremo step by step la procedura per la configurazione del C2960 ma ci limiteremo a mostrare la running-config (configurazione principale) dalla quale si potranno facilmente dedurre i vari comandi da impartire all’apparato:

Switch#sh run
Building configuration...
Current configuration : 1727 bytes
!
version 12.2
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname Switch
!
boot-start-marker
boot-end-marker
!
enable password password
!
username admin privilege 15 password 0 password
!
!
aaa new-model
!
!
aaa authentication login default group radius local
aaa authorization exec default group radius if-authenticated 
aaa accounting exec default start-stop group radius
aaa accounting system default start-stop group radius
!
!
aaa session-id common
system mtu routing 1500
!
!
spanning-tree mode pvst
spanning-tree extend system-id
!
vlan internal allocation policy ascending
!
!
interface FastEthernet0/1
!
(.....)
!
interface FastEthernet0/24
!
interface GigabitEthernet0/1
!
interface GigabitEthernet0/2
!
interface Vlan1
 ip address 192.168.201.5 255.255.255.0
!
ip default-gateway 192.168.201.20
ip http server
ip http secure-server
radius-server host 192.168.201.136 auth-port 1812 acct-port 1813
radius-server key testing123
radius-server vsa send authentication
!
line con 0
line vty 5 15
!
end

Da una qualsiasi macchina della rete possiamo accedere in telnet allo switch, utilizzando le utenze di dominio:

$ telnet 192.168.201.5
Trying 192.168.201.5...
Connected to 192.168.201.5.
Escape character is '^]'.


User Access Verification

Username: pippo
Password: 

Switch>

L’autenticazione è riuscita. Il livello di privilegi è però il più basso, come prova il simbolo “>” dopo l’hostname “Switch” dell’apparato.

3. Configurazione avanzata di freeradius per filtrare gli accessi ed assegnare livello 15 di privilegi sull’apparato di rete

Ora vogliamo che si possano loggare solo gli utenti appartenenti al gruppo “NetAdmins” e che si logghino direttamente al massimo livello di privilegi (level 15), ovvero in enable. Tutti gli altri utenti devono essere rifiutati.

Il livello massimo di privilegi assegnato agli utenti autenticati, si può semplicemente settare inserendo nella sezione “post-auth” (terza e ultima fase) sempre dello stesso file (/usr/local/etc/raddb/sites-enabled/default) queste poche righe:

post-auth {
....
          update reply {
                        Service-Type = Administrative-User
                       Cisco-AVpair = "shell:priv-lvl=15"
          }
....
}

Testiamo:

$ telnet 192.168.201.5
Trying 192.168.201.5...
Connected to 192.168.201.5.
Escape character is '^]'.

User Access Verification
Username: pippo
Password:
Switch#

OK: il segno “#” dopo “Switch” indica che l’utente viene automaticamente associato la livello di enable.

Ora vediamo come autenticare solo gli utenti appartenenti al gruppo “NetAdmins” del dominio.
Tramite Windows 7 e RSAT creiamo il gruppo “NetAdmins” e vi inseriamo il nuovo utente “pluto”.

Ora ricorriamo ad uno stratagemma, forse non molto “ortodosso” ma efficace: creiamo uno script basato su wbinfo che restituisca una stringa contenente i gruppi di appartenenza di un utente:
creiamo una directory che conterrà il nostro script:

mkdir /usr/local/etc/raddb/myscripts

ci entriamo e creiamo lo script get_groups.sh (grazie a Scott McLane Gardner):

 # cd /usr/local/etc/raddb/myscripts
# vim get_groups.sh
#!/bin/sh
 for T in $(wbinfo --user-domgroups `wbinfo -n $1`) ; do wbinfo -s $T |
perl -ne 'chomp and print'; done

a questo punto facciamo in modo che la sezione “post-auth” di /usr/local/etc/raddb/sites-enabled/default, lanci lo script passandogli come primo argomento lo username dell’utente che sta tentando l’autenticazione, sovrascrivendo in parte ciò che abbiamo settato nello step precedente. Se il match viene verificato l’utente viene accettato e gli vengono assegnati i privilegi level 15, altrimenti viene rifiutato:

# vim /usr/local/etc/raddb/sites-enabled/default
....
post-auth {
...
 if (`/bin/sh /usr/local/etc/raddb/myscripts/get_groups.sh %{User-Name}` =~ /NetAdmins/) {
 update reply {
 Service-Type = Administrative-User
 Cisco-AVpair = "shell:priv-lvl=15"
 }
 noop
 }
# No-one else is allowed.
 else {
 reject
 }
....

La restante parte della sezione deve rimanere invariata.

Come test conclusivo provo l’accesso telnet allo switch con le credenziali di pippo (utente non appartenente al gruppo “NetAdmins”):

$ telnet 192.168.201.5
Trying 192.168.201.5...
Connected to 192.168.201.5.
Escape character is '^]'.

User Access Verification

Username: pippo
Password:

% Authentication failed

Username:

giustamente l’autenticazione fallisce.
Se invece tento l’autenticazione dell’utente pluto (appartenente al gruppo “NetAdmins”), l’autenticazione andrà a buon fine e l’utente godrà dei privilegi livello 15:

$ telnet 192.168.201.5
Trying 192.168.201.5...
Connected to 192.168.201.5.
Escape character is '^]'.

User Access Verification

Username: pluto
Password:

Switch#

Lascia una risposta

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>