Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology

APM with google authenticator


When I set it up for myself I thought the guides I found was not very clear so I wrote one of my own after managing to set it up:


Hope it helps someone!


Rate this Discussion
Comments on this Discussion
Comment made 10-Jul-2016 by Saravanan M K

Great work. Thanks Patrik.

Comment made 11-Jul-2016 by Patrik Jonsson 3251

Thank you Saravanan! :)

Comment made 11-Jul-2016 by Nathaneil0227 375

Thanks for this Patrik, will try this on my LAB :))

Comment made 11-Jul-2016 by Nathaneil0227 375

Patrik Hi, Very useful than you very much! :)


Comment made 09-Sep-2016 by Matthieu Dierick

Great job !!!

Comment made 13-Oct-2016 by Montaser Omer Sawi 1

Perfect, I tried and it is working successfully.

Comment made 14-Jan-2017 by ebeng 72

Thanks man!!!

Comment made 01-Mar-2017 by Christoph Langer 74

great article!

Comment made 13-Mar-2017 by BillyL 0

Thanks for posting this! I used this today in combination with an older MFA/SSL-VPN lab to create a nice demo environment in vLab.

Comment made 5 months ago by oogabooga 69

Good stuff... One question... Why not save the key into the data-group programmatically rather than manually?

Comment made 5 months ago by Patrik Jonsson 3251

Because the scope of the project would increase to writing that functionality. :)


Replies to this Discussion



this is a nice article.

the only issue with google auth implementation with irule event is this is not usable within a macro with loop.

if the user enter a wrong password (not synchronized or typing error), the user is redirected to deny page.

to prompt again the user to enter the google auth code, the only solution is to create a macro with logon page and authentication box (in this case, this is the irule) and ending the authentication failure to loop ending.

the problem with irule events is when the same APM session variable is set or modified. the first occurence is applied in VPE, next are not.

So google with irule event is not the best way to authenticate users.

for one customer, I updated the existing google authenticator irule to convert it to HTTP auth server : https://devcentral.f5.com/codeshare/apm-google-authenticator-http-api-914

this irule allowed me to prompt again the user for google auth when first authentication failed.

Comments on this Reply
Comment made 08-Sep-2016 by Patrik Jonsson 3251


How many attempts does the user get to input the right code?


Comment made 09-Sep-2016 by Stanislas Piron 6289

The HTTP auth does not support multiple attempts.

you must insert logon page and HTTP auth in a macro with option :

maximum macro loop count : 3 (to allow 3 wrong password before deny)

and connect http auth failure branch to loop terminal

Comment made 09-Sep-2016 by Patrik Jonsson 3251

Nice, thank you for your input. I'm sure it will help a lot of people!


Comment made 09-Sep-2016 by Kai Wilke 6273

Hey Stanislas,

you may workaround the APM session variable caching behavior (see sol13296) by using a different variable after each single Loop iteration.

Cheers, Kai

Comment made 09-Sep-2016 by Stanislas Piron 6289


the API mode also allow to provide to the irule all parameters.

in the irule event, in the link provided by Patrik, you must configure which variable contains the user key.

with the irule I wrote, user key is sent to the API as HTTP parameter. the variable which contains the user key is defined in the HTTP auth object.


Comment made 14-Oct-2016 by Kai Wilke 6273

Hi Stanislas,

just a silly idea. Do you think it would be possible to run the Google Authenticator Verification directly in a VPE expression?

Cheers, Kai

Comment made 15-Oct-2016 by Stanislas Piron 6289

Hi Kai,

I saw your irule with optimized code (50 times quicker than mine) and it is a good beginning of the google auth solution.

In a new version of my API (not published yet), I manage user key encrypted in ldap attribute, and the next step is to store last successful authentication date in a session table to prevent code reuse.

APM variable assign language is TCL but with limited commands. irule commands like CRYPTO are not available in variable assign.

So I think this is not possible yet to do it with variable assign.

Comment made 16-Oct-2016 by Kai Wilke 6273

Hi Stanislas,

I'm aware of the VPE TCL limitations. But it should be possible to port the old code base to a VPE syntax, isnt it?

Well, if you're going to extent the functionality even further to include a true one time functionality and even account lockouts to secure the usage of long clock skews, then you have to use the iRule/API approach. Since I dont think that a VPE LocalDB tracking will be as flexible as the table command.

Note: The CRYPTO syntax and the new Base32 decoder is a huge step forward for this solution. It makes the code much more cleaner and faster. Fell free to adopt the code in your new iRule. ;-)

Cheers, Kai

Comment made 21-Oct-2016 by Stanislas Piron 6289

Hi Kai,

I tried to solve your chalenge, but I am stopped with the last command :-(

sha1 is not supported in VPE.

I created the following variable assign:

session.auth.clock =

expr { [clock seconds] / 30 }

session.auth.clockbin =

binary format W* [mcget {session.auth.clock}]

session.auth.key =

return {abcdefghijklmnop}

session.auth.key_binary =

string map -nocase [list A 00000 B 00001 C 00010 D 00011 E 00100 F 00101 G 00110 H 00111 I 01000 J 01001 K 01010 L 01011 M 01100 N 01101 O 01110 P 01111 Q 10000 R 10001 S 10010 T 10011 U 10100 V 10101 W 10110 X 10111 Y 11000 Z 11001 2 11010 3 11011 4 11100 5 11101 6 11110 7 11111 = "" 0 01110 1 01000 8 00001 " " "" "%09" "" "\n" ""] [ mcget {session.auth.key} ]

session.auth.keybin =

binary format B[expr { int( [string length [ mcget {session.auth.key_binary} ]] / 8 ) * 8 }] [ mcget {session.auth.key_binary} ]

session.auth.code =

    set ipad "";
    set opad "";
    set secret [mcget {session.auth.keybin}];
    for { set j 0 } { $j < [string length $secret] } { incr j } {
            binary scan $secret @${j}H2 k;
            set o [expr 0x$k ^ 0x5C];
            set i [expr 0x$k ^ 0x36];
            append ipad [format %c $i];
            append opad [format %c $o];
    while { $j < 64 } {
            append ipad 6;
            append opad \\;
            incr j;
    binary scan [sha1 $opad[sha1 ${ipad}[mcget {session.auth.clockbin}]]] H* result;
    return $result;

I found a tcl sha1 proc which can be supported, but there is 120 lines to calculate sha1 and we need to do it twice. I am not sure VPE is the best place to do it.

Comment made 27-Oct-2016 by Kai Wilke 6273

Hi Stanislas,

+1 Kudos for accepting the challenge ;-)

You're right, the SHA1 commands are iRule-Only features, so we have to recycle certain tcllib snippets to make the existing HMAC iRule VPE aware.

Performance-wise it will cost a plenty CPU cycles to implement the SHA1 and HMAC within VPE expressions and on a second thought I share your opinion that this is simply not worth in exchange of a slightly streamlined deployment...

Cheers, Kai


Patrik, Your Guide is very useful. It would be interesting to see similar guide for AD integration instead of local DB. Overall good guide.


Thanks Alex! The original guide(s) covers that, right? I would add it as well, but I don't have an active directory in my home lab.



Hey Patrik,

Very nice article, many thanks, this is just what I was looking for.