Monday 31 July 2017

Cisco ASA with Google Authenticator

Install FreeRADIUS and other Necessary Packages

sudo bash
apt-get update
apt-get install build-essential libpam0g-dev freeradius git libqrencode3 

Download Google Authenticator Pam Module Source

cd ~
git clone
cd google-authenticator/libpam/
make install

Configure Local Unix Groups

We will need to add a group called 'radius-disabled' to drop users in, when you want to disable access (rather than removing them entirely)

addgroup radius-disabled

Configure FreeRADIUS

FreeRADIUS must run as root for this to work.  Yeah, I know it's not good practice, but thats the way this works.  In other words, you may want to limit the use of this box to FreeRADIUS authentication only.  The reason for this is so that FreeRADIUS can access the .google_authenticator token in each home directory.  Otherwise FreeRADIUS does not have access.

First, edit /etc/freeradius/radusd.conf

You need to locate the following lines:

# user/group: The name (or #number) of the user/group to run radiusd as.
#   If these are commented out, the server will run as the user/group
#   that started it.  In order to change to a different user/group, you
#   MUST be root ( or have root privleges ) to start the server.
#   We STRONGLY recommend that you run the server with as few permissions
#   as possible.  That is, if you're not using shadow passwords, the
#   user and group items below should be set to radius'.
#  NOTE that some kernels refuse to setgid(group) when the value of
#  (unsigned)group is above 60000; don't use group nobody on these systems!
#  On systems with shadow passwords, you might have to set 'group = shadow'
#  for the server to be able to read the shadow password file.  If you can
#  authenticate users while in debug mode, but not in daemon mode, it may be
#  that the debugging mode server is running as a user that can read the
#  shadow info, and the user listed below can not.
#  The server will also try to use "initgroups" to read /etc/groups.
#  It will join all groups where "user" is a member.  This can allow
#  for some finer-grained access controls.
user = freerad
group = freerad

and then change the user & group lines to look like the following

user = root
group = root

Once you have done this, save and close the file.

Next edit, /etc/freeradius/users

You need to locate the following lines:

# Deny access for a group of users.
# Note that there is NO 'Fall-Through' attribute, so the user will not
# be given any additional resources.

We will start by creating a group that you can add users to and disable their access.

Directly after these lines add the following code:

DEFAULT         Group == "radius-disabled", Auth-Type := Reject
                Reply-Message = "Your account has been disabled."

Now, we will add the default rule to use the PAM libraries to authenticate users

Directly after the previous lines of code, add the following:

DEFAULT        Auth-Type := PAM

Now edit, /etc/freeradius/sites-enabled/default

Locate the following lines of code:

authenticate {
        #  PAP authentication, when a back-end database listed
        #  in the 'authorize' section supplies a password.  The
        #  password can be clear-text, or encrypted.
        Auth-Type PAP {

        #  Most people want CHAP authentication
        #  A back-end database listed in the 'authorize' section
        #  MUST supply a CLEAR TEXT password.  Encrypted passwords
        #  won't work.
        Auth-Type CHAP {

        #  MSCHAP authentication.
        Auth-Type MS-CHAP {

        #  If you have a Cisco SIP server authenticating against
        #  FreeRADIUS, uncomment the following line, and the 'digest'
        #  line in the 'authorize' section.

        #  Pluggable Authentication Modules.
#       pam

        #  See 'man getpwent' for information on how the 'unix'
        #  module checks the users password.  Note that packets
        #  containing CHAP-Password attributes CANNOT be authenticated
        #  against /etc/passwd!  See the FAQ for details.
        #  For normal "crypt" authentication, the "pap" module should
        #  be used instead of the "unix" module.  The "unix" module should
        #  be used for authentication ONLY for compatibility with legacy
        #  FreeRADIUS configurations.

        # Uncomment it if you want to use ldap for authentication
        # Note that this means "check plain-text password against
        # the ldap database", which means that EAP won't work,
        # as it does not supply a plain-text password.
#       Auth-Type LDAP {
#               ldap
#       }

        #  Allow EAP authentication.

        #  The older configurations sent a number of attributes in
        #  Access-Challenge packets, which wasn't strictly correct.
        #  If you want to filter out these attributes, uncomment
        #  the following lines.
#       Auth-Type eap {
#               eap {
#                       handled = 1
#               }
#               if (handled && (Response-Packet-Type == Access-Challenge)) {
#                       handled  # override the "updated" code from attr_filter
#               }
#       }
Uncomment the line with "pam" so it should look like this:

        #  Pluggable Authentication Modules.

Configure PAM

PAM must be configured to use the local Unix password in combination with the Google Authenticator password.

Edit /etc/pam.d/radiusd

Currently the file should look like this:

# /etc/pam.d/radiusd - PAM configuration for FreeRADIUS                                                                                  

# We fall back to the system default in /etc/pam.d/common-*                                                                              

@include common-auth
@include common-account
@include common-password
@include common-session

We need to comment out all the lines that start with @ and then add the following code:

auth requisite forward_pass
auth required use_first_pass

So in the end, the file should look like this:

# /etc/pam.d/radiusd - PAM configuration for FreeRADIUS                                                                      

# We fall back to the system default in /etc/pam.d/common-*                                                                  

#@include common-auth                                                                                                        
#@include common-account                                                                                                     
#@include common-password                                                                                                    
#@include common-session                                                                                                     

auth requisite forward_pass
auth required use_first_pass

Setup a local test user

adduser test

choose a easy password to remember, for this example I used "test123"

cd /home/test/
su test

If everything worked right you should see something that looks like this:

test@FreeDualFactor:~$ google-authenticator 

Do you want authentication tokens to be time-based (y/n) y|0&cht=qr&chl=otpauth://totp/test@FreeDualFactor%3Fsecret%3DXQH7L6A7W6OK3JYS
Your new secret key is: XQH7L6A7W6OK3JYS
Your verification code is 158428
Your emergency scratch codes are:

Do you want me to update your "/home/test/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) n

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y

You can configure yours how you see fit.

Scan once you get your custom QR Code, scan it in to your Google Authenticator App.

The App should generate a rotating code that you can use for your dual factor authentication.

Test your Configuration

service freeradius restart

You will want to use a command called "radtest" to test your configuration.

radtest <username> <unix_password><google_auth> localhost 18120 testing123

testing123 is a default secret for the localhost client, used for testing purposes.  You can find this in /etc/freeradius/clients.conf

so since my password is "test123" and the current google authenticator key is "696720" my test looks like this:

radtest test test123696720 localhost 18120 testing123

If it works right, you should get something like this:

root@FreeDualFactor:~# radtest test test123696720 localhost 18120 testing123
Sending Access-Request of id 154 to port 1812
User-Name = "test"
User-Password = "test123696720"
NAS-IP-Address =
NAS-Port = 18120
rad_recv: Access-Accept packet from host port 1812, id=154, length=20