In this article, we will set up a FreeIPA server that will serve as an authentication backend for FreeRadius. The idea is to manage the users of a Wi-Fi network through the LDAP integrated in FreeIPA.
The entire system will be set up on a Bhyve virtual machine using CBSD. We start by creating the VM:
We start the VM:
The CentOS8 installation will be performed regularly, but with the Server WITHOUT GUI option:
We access the server via SSH:
We update the system:
yum update
We configure the hostname:
We configure the DNS so that freeipa.alfaexploit.com points to the IP of our server, in my case 192.168.69.77.
We install the dig tool:
We check that the DNS is properly configured:
192.168.69.77
The ShellDap tool will be very useful for us to easily view and alter the LDAP tree, so we install it along with its Perl dependencies:
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
We install sudo since it is a dependency of FreeIPA:
FreeIPA packages are distributed through AppStream repositories. We can see the available repositories with the following command:
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
We can also see repository information with the command:
We add the repository:
We install the freeipa-server package:
We install the FreeIPA server:
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]:
It will ask us for two passwords, the directory manager’s which is a super-admin and the admin’s.
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
We check the contents of the file and configure the DNS according to this information:
_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
We disable the CentOS firewall and reboot:
reboot
We access the web interface:
https://freeipa.alfaexploit.com/ipa/ui
admin
.....
We create a test user:
As we explained at the beginning of the article, clients will connect to the wifi AP, which in turn will connect to the Radius server and this to the FreeIPA LDAP, visually it would be like this:
Client -> APWifi -> FreeRadius -> FreeIPA
We install the FreeRadius server:
We allow access from the Wifi APs, adding the necessary configuration to the default one:
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
}
The authentication against the FreeRadius backend is decided by the client, FreeRadius is only an intermediary. These authentication mechanisms are configured on the Wifi clients, and most devices should be configured with:
PEAP
MSCHAPV2
When using MS CHAPv2, FreeRadius will try to obtain an NTLM hash from FreeIPA, but this is not generated by default. We will have to perform additional configuration and change the users’ passwords:
ipa-adtrust-install
We accept the default parameters, except: 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
We check that the ipaNTHash field exists for the kr0m user, it will ask for the Directory Manager password:
dn: uid=kr0m,cn=users,cn=compat,dc=alfaexploit,dc=com
dn: uid=kr0m,cn=users,cn=accounts,dc=alfaexploit,dc=com
We see that it does not respond with the ipaNTHash, so we change the user’s password and see how it has generated the additional field:
We save the changes by clicking the Save button:
We check the ipaNTHash field again to verify that it now exists:
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==
NOTE: When we create users, the ipaNTHash is NOT generated, we have to create them and change their password.
To allow the Radius server to make queries, we must create a service account with read access to the ipaNTHash field:
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’
We assign a password to the service account by loading an ldif file into LDAP:
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
Load the ldif file, it will ask for the Directory Manager password:
Check that the PASSWORD_SERVICE_ACCOUNT password works:
It should respond with:
dn: krbprincipalname=radius/freeipa.alfaexploit.com@alfaexploit.com,cn=services,cn=accounts,dc=alfaexploit,dc=com
The LDAP Radius server object must have the member: krbprincipalname attribute. The easiest way to edit the LDAP tree is through the ShellDap tool:
~ > 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
As we can see, it does not have the member field, so we add it:
~ > 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
Enable the FreeRadius LDAP module:
Adjust the FreeRadius configuration to request the NT hash:
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'
}
Restart the service:
Manually check that the Radius LDAP module can access LDAP, it will ask for the PASSWORD_SERVICE_ACCOUNT password:
We set the default authentication mode to mschapv2:
default_eap_type = mschapv2
Manually start the Radius server in debug mode to test and see possible errors directly on the console:
radiusd -X
Another option is to start it but send the logs to a file:
tail -f /var/log/radius/logfile.log
Manually check that the user can log in, we must pay attention to the Received response field:
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
Start FreeRADIUS normally:
If we want to review the logs, we will do it in the following file:
As a final note, I leave some typical Android/Linux client configurations:
Android:
PEAP
MSCHAPV2
Linux:
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"
}
Start wpa_supplicant with the configuration:
EAPOL authentication completed - result=SUCCESS
Troubleshooting:
I found that one day without updating anything, FreeIPA stopped working, I don’t know if it was because the power supply was suddenly cut off or because it is a pretty sloppy software, but the following steps are necessary to start it:
chown -R dirsrv:dirsrv /var/lock/dirsrv/
service ipa.service start
service radiusd.service start
If after starting the conflicting services, the Wifi still does not work, it is recommended to restart all Wifi APs.