Esta pagina se ve mejor con JavaScript habilitado

Servidor FreeIPA CentOS bajo CBSD

 ·  🎃 kr0m

En este artículo vamos a montar un servidor FreeIPA que nos servirá como backend de autenticación para FreeRadius, la idea es poder gestionar los usuarios de una red wifi mediante el LDAP integrado en FreeIPA.

Todo el sistema se montará sobre una máquina virtual Bhyve utilizando CBSD, empezamos creando la VM:

cbsd bconstruct-tui



Arrancamos la VM:

cbsd bstart freeipa

La instalación de la CentOS8 se realizará de forma regular, pero con la opción Server SIN GUI:

Accedemos al servidor mediante SSH:

Actualizamos el sistema:

yum check-update
yum update

Configuramos el hostname:

hostnamectl set-hostname freeipa.alfaexploit.com

Configuramos los DNS para que freeipa.alfaexploit.com apunte a la ip de nuestro servidor, en mi caso 192.168.69.77.

Instalamos la herramienta dig:

yum install bind-utils

Comprobamos que los DNS estén bien configurados:

dig freeipa.alfaexploit.com +short

192.168.69.77

La herramienta ShellDap nos resultará de mucha utilidad para visualizar y alterar el árbol LDAP de forma fácil y sencilla, la instalamos junto con sus dependencias Perl:

yum -y install git

git clone https://github.com/mahlonsmith/shelldap.git
cp shelldap/shelldap /usr/local/bin/
yum -y install readline-devel gcc perl-core perl-CPAN ncurses-devel perl-Algorithm-Diff.noarch perl-Socket6.x86_64 perl-LDAP.noarch perl-YAML.noarch

cpan YAML::Syck
cpan Term::Shell
cpan Digest::MD5
cpan Net::LDAP
cpan IO::Socket::SSL
cpan Authen::SASL 
cpan Tie::IxHash
cpan Term::ReadLine::Gnu

Instalamos sudo ya que es una dependencia de FreeIPA:

yum -y install sudo

Los paquetes de FreeIPA son distribuidos mediante repositorios AppStream, podemos ver los repositorios disponibles mediante el siguiente comando:

yum module list idm

CentOS-8 - AppStream  
Name                                  Stream                                      Profiles                                                                      Summary                                                                                          
idm                                   DL1 [e]                                     adtrust, client, common [d] [i], dns, server                                  The Red Hat Enterprise Linux Identity Management system module                                   
idm                                   client [d]                                  common [d]                                                                    RHEL IdM long term support client module                              

También podemos ver información del repositorio con el comando:

yum module info idm:DL1

Añadimos el repositorio:

yum -y install @idm:DL1

Instalamos el paquete freeipa-server:

yum -y install freeipa-server

Instalamos el servidor FreeIPA:

ipa-server-install

Do you want to configure integrated DNS (BIND)? [no]Server host name [freeipa.alfaexploit.com]Please confirm the domain name [alfaexploit.com]Please provide a realm name [ALFAEXPLOIT.COM]

Nos pedirá dos passwords, el del directory manager el cual digamos que es un super-admin y el de admin.

Directory Manager password:   
IPA admin password:   
  
Do you want to configure chrony with NTP server or pool address? [no]  
The IPA Master Server will be configured with:  
Hostname:       freeipa.alfaexploit.com  
IP address(es): 192.168.69.77  
Domain name:    alfaexploit.com  
Realm name:     ALFAEXPLOIT.COM  
  
The CA will be configured with:  
Subject DN:   CN=Certificate Authority,O=ALFAEXPLOIT.COM  
Subject base: O=ALFAEXPLOIT.COM  
Chaining:     self-signed  
  
Continue to configure the system with these values? [no]: yes  
  
Please add records in this file to your DNS system: /tmp/ipa.system.records.qrv6k18o.db

Consultamos el contenido del fichero y configuramos los DNS acorde a esta información:

cat /tmp/ipa.system.records.qrv6k18o.db

_kerberos-master._tcp.alfaexploit.com. 86400 IN SRV 0 100 88 freeipa.alfaexploit.com.  
_kerberos-master._udp.alfaexploit.com. 86400 IN SRV 0 100 88 freeipa.alfaexploit.com.  
_kerberos._tcp.alfaexploit.com. 86400 IN SRV 0 100 88 freeipa.alfaexploit.com.  
_kerberos._udp.alfaexploit.com. 86400 IN SRV 0 100 88 freeipa.alfaexploit.com.  
_kerberos.alfaexploit.com. 86400 IN TXT "ALFAEXPLOIT.COM"  
_kpasswd._tcp.alfaexploit.com. 86400 IN SRV 0 100 464 freeipa.alfaexploit.com.  
_kpasswd._udp.alfaexploit.com. 86400 IN SRV 0 100 464 freeipa.alfaexploit.com.  
_ldap._tcp.alfaexploit.com. 86400 IN SRV 0 100 389 freeipa.alfaexploit.com.  
ipa-ca.alfaexploit.com. 86400 IN A 192.168.69.77

Deshabilitamos el firewall de CentOS y reiniciamos:

systemctl disable firewalld
reboot

Accedemos a la interfaz web:
https://freeipa.alfaexploit.com/ipa/ui

admin  
.....

Creamos un usuario de pruebas:


Como explicábamos al principio del artículo los clientes conectarán al AP wifi, este a su vez al servidor Radius y este al LDAP del FreeIPA, visualmente sería así:

Ciente -> APWifi -> FreeRadius -> FreeIPA

Instalamos el servidor FreeRadius:

yum -y install freeradius freeradius-utils freeradius-ldap freeradius-krb5

Permitimos el acceso desde los APs Wifi, añadimos la configuración necesaria a la que viene por defecto:

vi /etc/raddb/clients.conf

client localhost {
 ipaddr = 127.0.0.1
 proto = *
 secret = testing123
 require_message_authenticator = no
 nas_type  = other # localhost isn't usually a NAS...
 limit {
  max_connections = 16
  lifetime = 0
  idle_timeout = 30
 }
}
client localhost_ipv6 {
 ipv6addr = ::1
 secret  = testing123
}

client aps_wifi {
       ipaddr          = 192.168.69.0/24
       secret          = PASSWORD_RADIUS_CLIENTS
}

La autenticación contra el backend de FreeRadius la decide el cliente, FreeRadius tan solo es un intermediario, estos mecanismos de autenticación se configuran en los clientes Wifi, la mayoría de dispositivos deberán ser configurados con:

PEAP  
MSCHAPV2

Al utilizar MS CHAPv2 FreeRadius intentará obtener un hash NTLM de FreeIPA, pero este no se genera por defecto, tendremos que realizar configuración adicional y cambiar el password de los usuarios:

yum -y install freeipa-server-trust-ad
ipa-adtrust-install

Aceptamos los parámetros por defecto, excepto: Do you want to run the ipa-sidgen task?

Do you wish to continue? [no]: yes  
Do you want to run the ipa-sidgen task? [no]: yes

Comprobamos que exista el campo ipaNTHash para el usuario kr0m, pedirá el password de Directory Manager:

ldapsearch -H ldap://freeipa.alfaexploit.com -x -D ‘cn=Directory Manager’ -W -LLL -Z ‘(uid=kr0m)’ ipaNTHash

dn: uid=kr0m,cn=users,cn=compat,dc=alfaexploit,dc=com  
dn: uid=kr0m,cn=users,cn=accounts,dc=alfaexploit,dc=com

Vemos que no responde con el ipaNTHash, cambiamos el password del usuario y vemos como ha generado el campo adicional:



Guardamos los cambios dándole al botón Save:

Volvemos a consultar el campo ipaNTHash para comprobar que esta vez sí que existe:

ldapsearch -H ldap://freeipa.alfaexploit.com -x -D ‘cn=Directory Manager’ -W -LLL -Z ‘(uid=kr0m)’ ipaNTHash

Enter LDAP Password:   
dn: uid=kr0m,cn=users,cn=compat,dc=alfaexploit,dc=com  
  
dn: uid=kr0m,cn=users,cn=accounts,dc=alfaexploit,dc=com  
ipaNTHash:: TGgm80Zaob30Drrli2x5VQ==

NOTA: Cuando creamos usuarios NO se genera el ipaNTHash, hay que crearlos y cambiarles el password.

Para que el servidor Radius pueda hacer las consultas debemos crear una cuenta de servicio con acceso de lectura al campo ipaNTHash:

ipa permission-add ‘ipaNTHash service read’ --attrs=ipaNTHash --type=user  --right=read
ipa privilege-add ‘Radius services’ --desc=‘Privileges needed to allow radiusd servers to operate’
ipa privilege-add-permission ‘Radius services’ --permissions=‘ipaNTHash service read’
ipa role-add ‘Radius server’ --desc=“Radius server role”
ipa role-add-privilege --privileges=“Radius services” ‘Radius server’
ipa service-add ‘radius/freeipa.alfaexploit.com’

Asignamos un password a la cuenta de servicio para ello cargaremos un fichero ldif en el LDAP:

vi setLdapServiceAccountPassword.ldif

dn: krbprincipalname=radius/freeipa.alfaexploit.com@ALFAEXPLOIT.COM,cn=services,cn=accounts,dc=alfaexploit,dc=com  
changetype: modify  
add: objectClass  
objectClass: simpleSecurityObject  
-  
add: userPassword  
userPassword: PASSWORD_SERVICE_ACCOUNT

Cargamos el fichero ldif, pedirá el password de Directory Manager:

ldapmodify -f setLdapServiceAccountPassword.ldif -D ‘cn=Directory Manager’ -W -H ldap://freeipa.alfaexploit.com -Z

Comprobamos que funcione el password PASSWORD_SERVICE_ACCOUNT:

ldapwhoami -H ldap://freeipa.alfaexploit.com -Z -D ‘ krbprincipalname=radius/freeipa.alfaexploit.com@ALFAEXPLOIT.COM ,cn=services,cn=accounts,dc=alfaexploit,dc=com’ -W

Debería responder con:

dn: krbprincipalname=radius/freeipa.alfaexploit.com@alfaexploit.com,cn=services,cn=accounts,dc=alfaexploit,dc=com

El objeto Radius server de LDAP debe tener el atributo member: krbprincipalname, la manera mas sencilla de editar el árbol LDAP es mediante la herramienta ShellDap:

shelldap -h freeipa.alfaexploit.com --binddn ‘cn=Directory Manager’ --basedn ‘cn=roles,cn=accounts,dc=alfaexploit,dc=com’ --promptpass

~ > ls  
- cn=Enrollment Administrator  
- cn=IT Security Specialist  
- cn=IT Specialist  
- cn=Radius server  
- cn=Security Architect  
- cn=User Administrator  
- cn=helpdesk
~ > cat cn='Radius server'  
dn: cn=Radius server,cn=roles,cn=accounts,dc=alfaexploit,dc=com  
objectClass: groupofnames  
objectClass: nestedgroup  
objectClass: top  
cn: Radius server  
description: Radius server role  
memberOf: cn=Radius services,cn=privileges,cn=pbac,dc=alfaexploit,dc=com  
memberOf: cn=ipaNTHash service read,cn=permissions,cn=pbac,dc=alfaexploit,dc=com

Como podemos ver no tiene el campo member, lo añadimos:

~ > vi cn='Radius server'  
dn: cn=Radius server,cn=roles,cn=accounts,dc=alfaexploit,dc=com  
objectClass: groupofnames  
objectClass: nestedgroup  
objectClass: top  
cn: Radius server  
description: Radius server role  
memberOf: cn=Radius services,cn=privileges,cn=pbac,dc=alfaexploit,dc=com  
memberOf: cn=ipaNTHash service read,cn=permissions,cn=pbac,dc=alfaexploit,dc=com  
member: krbprincipalname=radius/freeipa.alfaexploit.com@ALFAEXPLOIT.COM,cn=services,cn=accounts,dc=alfaexploit,dc=com

Habilitamos el módulo LDAP de FreeRadius:

ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/

Retocamos la configuración de FreeRadius para que pida el hash NT:

vi /etc/raddb/mods-enabled/ldap

ldap {  
        server = 'freeipa.alfaexploit.com'  
        base_dn = 'cn=users,cn=accounts,dc=alfaexploit,dc=com'  
        identity = 'krbprincipalname=radius/freeipa.alfaexploit.com@ALFAEXPLOIT.COM,cn=services,cn=accounts,dc=alfaexploit,dc=com'  
        password = PASSWORD_SERVICE_ACCOUNT  
  
        ...  
        update {  
                ...  
                control:NT-Password             := 'ipaNTHash'  
        }

Reiniciamos el servicio:

systemctl restart radiusd

Comprobamos manualmente que el módulo LDAP de Radius pueda acceder al LDAP, pedirá el password PASSWORD_SERVICE_ACCOUNT:

ldapsearch -x -W -D “ krbprincipalname=radius/freeipa.alfaexploit.com@ALFAEXPLOIT.COM ,cn=services,cn=accounts,dc=alfaexploit,dc=com” -b “cn=users,cn=accounts,dc=alfaexploit,dc=com” objectclass=*

Configuramos el modo de autenticación por defecto a mschapv2:

vi /etc/raddb/mods-enabled/eap

default_eap_type = mschapv2

Arrancamos manualmente en modo debug el servidor Radius para hacer las pruebas y poder ver los posibles errores directamente en consola:

systemctl stop radiusd
radiusd -X

Otra opción es arrancarlo pero enviando los logs a un fichero:

radiusd -X -l /var/log/radius/logfile.log
tail -f /var/log/radius/logfile.log

Comprobamos manualmente que el usuario pueda hacer login, debemos fijarnos en el campo de respuesta Received:

radtest -t mschap kr0m PASSWORD_KR0M freeipa.alfaexploit.com 1812 PASSWORD_RADIUS_CLIENTS

Sent Access-Request Id 113 from 0.0.0.0:58841 to 192.168.69.77:1812 length 130  
 User-Name = "kr0m"  
 MS-CHAP-Password = "PASSWORD_KR0M"  
 NAS-IP-Address = 192.168.69.77  
 NAS-Port = 1812  
 Message-Authenticator = 0x00  
 Cleartext-Password = "PASSWORD_KR0M"  
 MS-CHAP-Challenge = 0x46081ee26b22c8f1  
 MS-CHAP-Response = 0x000100000000000000000000000000000000000000000000000092c9b792bf88e62a7eb0d7294c6df8d59afc3263b426852b  
Received Access-Accept Id 113 from 192.168.69.77:1812 to 192.168.69.77:58841 length 84  
 MS-CHAP-MPPE-Keys = 0x00000000000000000cc85029487b5959bbd339d86fc11db6  
 MS-MPPE-Encryption-Policy = Encryption-Allowed  
 MS-MPPE-Encryption-Types = RC4-40or128-bit-Allowed

Arrancamos FreeRADIUS de forma normal:

systemctl start radiusd

Si queremos revisar los logs lo haremos en el siguiente fichero:

tail -f /var/log/radius/radius.log

Como nota final dejo algunas configuraciones típicas de clientes Android/Linux:


Android:

PEAP  
MSCHAPV2

Linux:

vi /home/kr0m/AlfaexploitConf
ctrl_interface=/var/run/wpa_supplicant  
  
network={  
        ssid="WIFI_NET"  
        scan_ssid=1  
        key_mgmt=WPA-EAP  
        eap=PEAP  
        identity="kr0m"  
        password="PASSWORD_KR0M"  
        phase2="auth=MSCHAPV2"  
}

Arrancamos wpa_supplicant con la configuración:

wpa_supplicant -ddddd -Dwext -i wlp2s0 -c/home/kr0m/AlfaexploitConf -K

EAPOL authentication completed - result=SUCCESS

Troubleshooting:

He detectado que un día sin actualizar nada FreeIPA dejó de funcionar, no sé si porque se le quitó el suministro eléctrico de forma subita o porque es un software bastante chapucero pero para arrancarlo son necesarios los siguientes pasos:

mkdir -p /var/lock/dirsrv/slapd-ADSALSA-NET
chown -R dirsrv:dirsrv /var/lock/dirsrv/
service ipa.service start
service radiusd.service start

Si tras arrancar los servicios conflictivos la Wifi sigue sin funcionar es recomendable reiniciar todos los APs Wifi.

Si te ha gustado el artículo puedes invitarme a un RedBull aquí