Setting up FreeRADIUS + OpenLDAP on a Raspberry Pi for Network Device Authentication
One thing that I’ve been meaning to do is setup a central authentication/authorization server for my home network for easier management of network devices and other LDAP-aware software (oVirt). It helps that all of my network devices are either prosumer (Ubiquiti) or enterprise (Juniper/Cisco), so they allow for some form of external authentication via either LDAP or RADIUS. Both aren’t really resource intensive which makes the Raspberry Pi 3 a perfect candidate to run them. This guide covers Raspbian Stretch but can likely be used for any future or older versions of Raspbian.
The image above shows a quick network topology for visual reference. In this guide, the RootDN structure I will be using is home.clintonmetu.com, or dc=home,dc=clintonmetu,dc=com.
Installing and Configuring OpenLDAP
First, we need to install the openLDAP packages
apt-get install slapd ldap-utils
After installing OpenLDAP, it should prompt you to setup an admin password. You can type in anything for now, we’re going to reconfigure the package in a moment and you’ll get another chance to set the password. After typing in the admin password, run
dpkg-reconfigure slapd to go through the original configuration. We will setup OpenLDAP with the following settings:
Omit LDAP server configuration: No
DNS Domain Name: home.clintonmetu.com
Organizational Name: home
<enter in admin password>
Use MDB backend Purge database on slapd removal: No
Move old database: Yes
Once this is done, you should be able to run
ldapsearch -x -LLL -b dc=home,dc=clintonmetu,dc=com (or whatever you used as your RootDN) and see some output, similar to this:
This will confirm that the reconfiguration went smoothly. Now, we create an LDIF file to add a new user to our environment. Create a new blank file named
newuser.ldif and place these contents in the file:
This will create two new OU’s (Organizational Units) – People and Groups. The Groups OU will contain special groups that we want to add users to (ex. “net-device-users” group for users that have access to network devices, “splunk-users” for users that have access to Splunk, etc.) and the People OU will hold our actual user accounts. Next, we ingest this LDIF into our LDAP server using:
ldapadd -x -W -D cn=admin,dc=home,dc=clintonmetu,dc=com -f newuser.ldif
When it prompts for a password, type in the admin password you created above. Now we have our first user in LDAP, and assigned them to a group.
(Optional) Disable Anonymous LDAP Binding
By default, LDAP allows for anonymous binding so anyone can connect to it and view all of the objects (LDAP Hierarchy, groups you have configured, users, etc) stored within. I recommend disabling this feature to force users to authenticate before they can view the contents of your LDAP server. Create and a new filed named
disable_anon_bind.ldif and insert these contents in the file:
Now, import the LDIF with:
ldapmodify -H ldapi:/// -Y EXTERNAL -f disable_anon_bind.ldif
Anonymous binding is now disabled.
(Optional) Setup LetsEncrypt for Secure LDAP (LDAPS)
Since the LDAP server will be used in a home or lab environment, it’s not mandatory to install a CA trusted SSL certificate. I tried to go down the self-signed SSL cert route for LDAP and hit too many walls. If you go down the self-signed SSL route, one thing you’ll have to do is copy the self-signed CA certificate over to each device that will be querying the LDAP server via LDAPS. After going down this rabbit hole for a bit, I decided backtrack and rely on our good friends at Let’s Encrypt to generate certs that are trusted by any device without needing to mess around with the certificate store.
(Optional) Install phpLDAPadmin
phpLDAPadmin will provide a web-GUI for us to add new users and groups, and manage our existing users and groups so we won’t have to generate LDIF files for every LDAP change we make. If you don’t already have them, we’ll need to install Nginx, PHP, a few PHP modules, and two useful tools git and screen:
apt-get install nginx php-fpm php7.0-ldap php7.0-xml git screen
After these packages are installed, we need to generate a DH parameter file for key exchange. This may take awhile, so we can use screen to run this in the background while we do other things:
screen openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
This will launch the process, and then you can press
CTRL+A+D to exit out of the screen. In ~10 minutes you can use the
screen -r command to connect back to the screen and see if it is completed.
In the meantime, use your favorite editor to create a new vhost file for phpldapadmin. I created this new vhost in the file
/etc/nginx/sites-enabled/ldap with these contents:
Note: If you are not using an SSL, feel free to leave off the lines that begin with “ssl_”
Now, we fetch phpldapadmin and put it in in
Then use your favorite editor to edit
/var/www/html/phpldapadmin/config/config.php and make the following changes:
- Uncomment $config->custom->appearance[‘hide_template_warning’] and set it to true
- (Optional) Set a custom name for your LDAP server in $servers->setValue(‘server’,’name’,’Home LDAP Server’);
- Uncomment $servers->setValue(‘server’,’base’,array(”)); and replace it with the base dn that you used to create the server
The three lines should then look like:
Last, you need to either add your RootDN to your computer’s hosts file or to your DNS server. After that, you should be able to navigate to https://<your-root-dn>/phpldapadmin and it show the phpldapadmin page.
To log in, you use your admin DN (ex. cn=admin,dc=home,dc=clintonmetu,dc=com) as the LoginDN and then the admin password.
Installing and Configuring FreeRADIUS
To start, we install the FreeRADIUS and FreeRADIUS-LDAP packages:
apt-get install freeradius freeradius-ldap
With FreeRADIUS installed, we can now start configuring it to connect to our LDAP backend. The first thing we are going to do is edit the file
/etc/freeradius/3.0/sites-available/default and remove the comments in front of the LDAP authentication module so we can use it. On line 502, you should see the following text commented out:
Remove the comments from these 3 lines, and then save the file. Next, we’re going to edit
/etc/freeradius/3.0/mods-available/ldap to insert our LDAP details. We will need to modify/uncomment the following lines:
After making these modifications, we need to symlink our LDAP config from mods-available to mods-enabled:
ln -s /etc/freeradius/3.0/mods-available/ldap /etc/freeradius/3.0/mods-enabled/ldap
This makes the LDAP configuration available for use. With that done, it’s time to restart FreeRADIUS and test things:
systemctl restart freeradius
Then run a
radtest to test if FreeRADIUS is able to speak with the LDAP server by using your username and password that you created in the original LDIF using:
radtest <ldap user> <pass> 127.0.0.1 1 testing123
You should get output similar to above to show that it works. The “Access-Accept” message on the last line shows that the authentication was successful. The last thing we need to do is create a configuration entry for our clients (network devices) and then add some logic to the post-LDAP auth so it knows how to properly communicate to our clients that we have legitimate permission (authorization) to log in. First, edit the file
/etc/freeradius/3.0/clients.conf and add a a client block for each of your network devices:
Lastly, we then edit the
/etc/freeradius/3.0/sites-available/default file again, and uncomment “ldap” on line 726 (in the post-auth section), and then insert this code right underneath ldap, so the whole section looks like this:
You may have to look up your network device’s VSA (Vendor Specific Attribute) so RADIUS knows how to properly communicate back what your user’s access privileges should be. The two VSAs that I included work for Juniper, Cisco, and Ubiquiti devices to communicate that anyone in the “net-device-users” group should have all privileges on the device.
Now, the moment of truth. For this example, I will use my Juniper SRX 300 to verify authentication and authorization. I configured my SRX300 as such to use the RADIUS server to authenticate and authorize my LDAP user “clint”:
After logging into the SRX300 using my test LDAP user “clint” and the password “clinton123”, I’m successfully dropped into the CLI:
If everything is working, we can now configure all of our services to start on boot: