Radius with Google Authenticator/LDAP

Alan DeKok aland at deployingradius.com
Tue Jul 24 13:16:27 CEST 2018

On Jul 24, 2018, at 6:41 AM, Daniel Lumb <daniel.lumb at outlook.com> wrote:
> So, I’m looking to configure FreeRadius as an authentication source for a Cisco VPN with 2FA. I’d like to use Google authenticator for the second factor.

  It should work, with some careful configuration.

> There are plenty of guides on integrating Google authenticator with FreeRadius, which appear to point FreeRadius to use PAM and then add the Google authenticator config to the Radius PAM stack.

  That's how PAM works.  It's... obtuse, to be polite.

> In all of these examples, the OTP code must be entered on the end of the user password in the same input field, which is fine. The issue is that all of these examples use local linux users in the PAM stack, like this:

  If you don't want local users, then don't configure PAM to check that.  That's why the config files are editable...

> auth requisite pam_google_authenticator.so forward_pass

  That's all you need to check google authenticator.

> I currently have Radius setup to authenticate against LDAP (Through the FreeRadius config itself, nothing to do with PAM) - is there a way that I can use the LDAP account as a the second part of this 2FA rather than a local account?


> It seems that it will have to involve PAM because as part of the google authenticator setup you have to tell FreeRadius to use PAM in the authorize/authenticate config.


  The solution here is to split the password.  Typically people use the 6 digit google authenticator string, followed by the users actual password.  So you need to do the following:

- split User-Password into 6 digits + real password, using a regex

	if (User-Password =~ /^([0-9]{6})(.*)$/) {
		update request {
			# define this as "string" in raddb/dictionary
			Google-Password := "${1}"
			User-Password := "${2}"

- get the real password against LDAP.

  This is done via the normal config. You don't need to check much here.

- check real password && google password via PAM

authenticate {
	Auth-Type PAP {
		# this returns on fail / reject / etc.
		# PAM requires the password to be in User-Password, so rewrite that
		if (Google-Password) {
			update request {
				User-Password := "%{Google-Password}"

  And that should work.

  Alan DeKok.

More information about the Freeradius-Users mailing list