Use Google Authenticator to login to a Linux host


The Google Authenticator project includes implementations of one-time passcode generators for several mobile platforms, as well as a pluggable authentication module (PAM). One-time passcodes are generated using open standards developed by the Initiative for Open Authentication (OATH) (which is unrelated to OAuth).

These implementations support the HMAC-Based One-time Password (HOTP) algorithm specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm currently in draft.

This documentation will tell you how to setup a Debian based Linux box (others may vary a little bit) to use the Google Authenticator iPhone App (or any other implementation of it) to authenticate a user.

Install preriquisites

Depending on your system you need some packages on your machine before we begin. Since I wrote this documentation after I installed everything, it might be possible that I missed a dependency. If so, find out what is missing and install it. As far as I can remember I did:

sudo apt-get install checkinstall git libqrencode-dev libqrencode3 libpam0g-dev

Get the source

Make sure you can connect to the internet from your box., then create a folder on your hard drive and get the source via a Mercury Repository.

#mkdir compile
#cd compile
#hg clone google-authenticator
#hg clone

mkdir compile
cd compile
git clone

Modification for 64bit

If you use a 64bit installation and you get this error, you have to change the Makefile a little bit to get it working since it searches for in the wrong location.

First of all get the location of on your machine with the following command:

find /usr/lib -name

This results (on my system) in:


Now you have to change all instances of



/usr/lib/i386-linux-gnu/  (change this to fit your system)



On the latest Ubuntu systems you can use a variable to point to the correct location. Just use this sed command to do this:

cd compile/google-authenticator/libpam
sed -i "s@\(usr\/lib\/\\)\(libdl\.so\)@\1$(dpkg-architecture -qDEB_HOST_MULTIARCH)\/\2@g" Makefile

Modification of the login prompt

The original Login Prompt e.g. when using the Google Authenticator for SSH Logins is “Verification code: ”. If you want to change it, edit the following line in “pam_google_authenticator.c”

                                   .msg       = "Verification code: " };

and change it to whatever message you want to see, eg.:

                                   .msg       = "Google Authenticator Code: " };

Compile the source and create a debian package

A lot of tutorials will tell you how to make and install the code, but since we use a Debian system here, we like to have Debian package. Here is how to achieve this.

cd compile/google-authenticator/libpam
sudo checkinstall -y --maintainer=your@email.domain --install=no -D make install

The result should be a .deb package. You can use this package for installation.

Install the package

sudo dpkg -i libpam_20111115-1_i386.deb   (the name can be different on your system)

Associate a device with your login

Login as usual to your Linux box with your user account. Then start the following program:


After completing the wizard your useraccount has now a file ~/.google_authenticator with a content looking like this:

" RATE_LIMIT 3 30 12343463591

So if you configure your machine to use google authenticator, this file will be read for this specific user account.

If you want to have a prefix before your password that users have to enter and that is ignored by the pam module, change the following lines in


    // We are often dealing with a combined password and verification
    // code. Separate them now.

    // remove the prefix (0815) from the password
    if (strncmp(pw, "0815",4)==0) {

    int pw_len = strlen(pw);
    int expected_len = mode & 1 ? 8 : 6;

I added the following lines, you could change the prefix “0815” to whatever you like!

    // remove the prefix (0815) from the password
    if (strncmp(pw, "0815",4)==0) {

to ignore 4 characters from the left, so if your password would be 0815123456 it will be replaced with 123456 so the 0815 will be ignored. This way you can advise users to use a prefix when entering the password but ignore it later.

Security Hint

I would prefer using counter-based codes instead of time-based codes. counter-based codes cannot be deployed via QR-Code. Also when a code is used it is no longer valid. With counter-based codes you can reduce the possibility to duplicate the account on multiple devices.

Also take a look at this entry

Hint for SSH Logins

Some services e.g. SSH need an explicit configuration to use PAM. To be able to use the Google Authenticator PAM Module via SSH you have change/verify 2 lines in your SSH Daemon configuration file. On Ubuntu this is


Make sure the file contains the following 2 lines:

ChallengeResponseAuthentication yes
UsePAM yes

Before going live, make sure you have a second shell open where you can change back to the original settings if something fails

Enable Google Authenticator for PAM unix logins (optional)

Create package-supplied authentications profiles

Create the following file:


with the following content:

Name: Google Authenticator (all)
Default: yes
Priority: 900
Auth-Type: Primary

and a second file


with this content:  
Name: Google Authenticator (enough)
Default: yes
Priority: 900
Auth-Type: Primary

Reconfigure PAM authentication

Since we created authentication profiles we can simply use the following command

sudo pam-auth-update

to configure the central authentication policy for the system which now contains “Google Authenticator (all) and “Google Authenticator (enough)” as created before.

For Google Authenticator only:

[*] Google Authenticator (enough)              
[ ] Google Authenticator (all)
[ ] Unix authentication

For Google Authenticator OR password:

[*] Google Authenticator (enough)              
[ ] Google Authenticator (all)
[*] Unix authentication

For Google Authenticator AND password:

[ ] Google Authenticator (enough)              
[*] Google Authenticator (all)
[*] Unix authentication  

Enable PAM authentication via radius (optional)

Install Freeradius

We use the standard package for freeradius. (tested on Debian Squeeze. for Ubuntu use sudo)

apt-get install freeradius

Because freeradius will later call the google-authenticator PAM module which needs to impersonate the user that tries to logon, freeradius has to run with root privileges. This might be a security problem but I currently do not know a workarround. We have to change the following options in


The values with # are the original values

#user = freerad
#group = freerad
user = root
group = freerad

All other entries in this file were not changed.

Enable PAM authentication in Freeradius

To enable PAM authentication for users in freeradius, we add the following line at the end of /etc/freeradius/users

DEFAULT Auth-Type := PAM

The entire file /etc/freeradius/users (without comments) will look like this:

DEFAULT Framed-Protocol == PPP
        Framed-Protocol = PPP,
        Framed-Compression = Van-Jacobson-TCP-IP
        Framed-Protocol = SLIP,
        Framed-Compression = Van-Jacobson-TCP-IP
        Framed-Protocol = SLIP
DEFAULT Auth-Type := PAM

Enable PAM authentication in Freeradius default site

To be able to authenticate via PAM we have to enable it in the authentication-section of /etc/freeradius/sites-enabled/default

Search for the following section and remove the comment from “pam”:

authenticate {
        #  Pluggable Authentication Modules.

At the end the above section should look like this (comments removed)

authenticate {
        Auth-Type PAP {
        Auth-Type CHAP {
        Auth-Type MS-CHAP {

Activate PAM with freeradius and libpam of google-authenticator

During the installation of freeradius the file


has been created. It is NOT usable for us, so create a backup of it and then enter ONLY the following lines in your new file:

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

# Use the right 6 digits for google-authenticator (forward_pass)
auth requisite  forward_pass
# forward the rest (normal userpass) to
auth required use_first_pass

The default settings work, if you want to change the location of your .google_authentiator files PLEASE exactly READ the file


It explains in detail how you can point to a different location for the authentication file and also how to use variables (not all, but some) within the radiusd file. If you change the location you have to make sure, that only the user that tries to authenticate has access to his authentication file. Watch auth.log for errors!

Here is a sample file, I use in my environment, that works. (I had to provide the folder structure und /var/home/<username> and setup the correct user rights for each folder manually!

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

# Use the right 6 digits for google-authenticator (forward_pass)
# instead of the default location use an alternate authentication file (secret=).
# This is useful to authenticate non local users via pam_google_authenticator.
auth requisite secret=/var/home/${USER}/google_authenticator forward_pass
# forward the rest (normal userpass) to
auth required use_first_pass

PAM configuration for non local accounts

If you want to use the google-authenticator via radius and non local accounts the following way works.

  • Create a folder where all your authentication files will reside e.g. /var/google-authenticator
  • chown this folder to root:root

After that you have to add users with the google-authenticator binary:

google-authenticator -s /var/google-authenticator/<username>_google_authenticator


google-authenticator -s /var/google-authenticator/jonnyo_google_authenticator

Make sure, that the created file jonnyo_google_authenticator is at chmod 400 and owned by root:root.

Now change your /etc/pam.d/radiusd file a little bit.

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

# Use non local users. The authentication files reside
# in /var/google-authenticator/<username>_google_authenticator
# root must be owner of those files and chmod 400 on all of them
auth required user=root secret=/var/google-authenticator/${USER}_google_authenticator

So how does this work? Let's say, the user jonnyo wants to authenticate via google-authenticator, the google-authenticator pam module will take the user “root” as the caller (user=root) and look for the file /var/google-authenticator/jonnyo_google_authenticator to authenticate. - That's all.

!! Additional information for Ubuntu server !!

On my Ubuntu Server (Ubuntu 10.04.4 LTS x64)I had this error:

freeradius: pam_unix(radiusd:account): could not identify user (from getpwnam(username))

I had to change /etc/pam.d/radiusd to the following

account required /lib/security/ skip_first_pass
auth required user=root secret=/var/google-authenticator/${USER}_google_authenticator 

to avoid the error. The above is a “dummy account line” to skip the lookup of local user accounts.

Test your setup

To test your setup you should run freeradius in debug mode. So stop the service (if running) with

service freeradius stop

and then start freeradius manually with the debug option

freeradius -X

You should then see output like this:

...a lot of lines
} # server
radiusd: #### Opening IP addresses and Ports ####
listen {
        type = "auth"
        ipaddr = *
        port = 0
listen {
        type = "acct"
        ipaddr = *
        port = 0
listen {
        type = "auth"
        ipaddr =
        port = 18120
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on authentication address port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.  

!!! If you have errors here, first fix them before continuing. !!!

Now switch to a different session and try to authenticate with the following command:

radtest <user> <password><googlecode> 18120 testing123

so for example if you have user with username peter, with the password Peter$Pass, the google-authenticator code 345182 and the radius client secret is testing123, then the line is

radtest peter Peter\$Pass345182 18120 testing123


The result should look like this:

> radtest peter Peter\$Pass345182 localhost 18120 testing123
Sending Access-Request of id 206 to port 1812
        User-Name = "peter"
        User-Password = "Peter$Pass345182"
        NAS-IP-Address =
        NAS-Port = 18120
rad_recv: Access-Accept packet from host port 1812, id=206, length=20

Change the freeradius client password

Open the file /etc/freeradius/clients.conf and search for the line(s)

        #  The default secret below is only for testing, and should
        #  not be used in any real environment.
        secret          = testing123

Change “testing123” to a different password. From now on use the new password to client access to your freeradius server.


You could easily manage token creation via Webmin. Take this as an example:

Install Webmin

Create the following folder structure

├── /var/google-authenticator/disabled-tokens
├── /var/google-authenticator/scripts
└── /var/google-authenticator/tokens

Put the file create.cfg with the following content into /var/google-authenticator/scripts


Create a script /var/google-authenticator/scripts/create with the following content


#get values from configfile
# tokendir binary ratelimit ratetime qrmode prefix start stop
source $configfile

#create new token and strip of some data
echo "Username              : $prefix$start"
$binary -c -f -Q $qrmode -r $ratelimit -R $ratetime -l $prefix$start -s $tokendir$prefix$start -W | head -n 1

#prepare new values for configfile
start=$(echo $start| sed 's/^0*//') # remove leading zeros from variable start
newstart=$((start+1)) # do start = start +1

# How many zeros for a 6 digit number? add them in front of newstart
newstart=$(for((i=1;i<=$((6-${#newstart}));i++));do printf "%s" "0";done;printf "\n")$newstart

# make sure we are below 999999
if [ $newstart -le $stop ] ; then
   #write newstart back into create.cfg as new value for start
   sed -i "s#^start=.*#start=$newstart#g" ./create.cfg
   exit 1 # exit with error

Make the script executable.

Now you could create custom commands in webmin.

You could use my custom files from (webmin-google-custom.tar.gz) and place it in /etc/webmin/custom (Debian).

Maybe you have to check all the commands and adapt them to your local installation.

Software Tokens

Linux Bash

I wrote a small bash script that simulates a token. You need oathtool installed on your system.

while [ 1 = 1 ]; do
 password=$(oathtool --totp -b -s 30s $base32secret)
 seconds=$(date +%S)
 echo "##################################"
 echo "#     Google  Authenticator      #"
 echo "##################################"
 echo -n '#             '
 if [ "$seconds" -gt 56 ] ; then
    echo -n -e "\e[1;31m$password\e[0m"
 elif [ "$seconds" -gt 26 -a "$seconds" -lt 30 ]; then
    echo -n -e "\e[1;31m$password\e[0m"
    echo -n "$password"
    echo '             #'
 echo "##################################"
 echo ""
 if [ "$1" == "debug" ]; then
  echo "$(oathtool --totp -v -b -s 30s $base32secret)"
 sleep .1

For debian based systems you can pickup oathtool .deb files directly from the latest testing release (wheezy). They work without problems under stable.

public/linux/google-authenticator.txt · Last modified: 2015/08/11 08:20 (external edit)
CC Attribution-Share Alike 3.0 Unported
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0