Yubikey One-Time-Password Authentication with APM

yubikey_4Well my Yubikey 4 arrived today so I had a chance to play around with their one-time-password capabilities – read about their U2F and APM capabilities here. The primary benefit about OTP over U2F is it’s supported across almost every major browser and OS.  This makes the Yubikey 4 a little more palatable for enterprises – note the Yubikey 4 supports both OTP and U2F.

Jason Rahm posted an article on DevCentral regarding 2FA using Yubikey, YubiCloud and BIG-IP LTM  back in 2013.  I’ve adapted this iRules to use APM Agent Events so we can leverage Yubikeys for 2FA in APM.  For more information on Yubikey OTP clients check out the Getting Started Writing Clients page.


  1. To configure this you’ll need to add the iRule below to your BIG-IP and XXXXXX with your YubiCloud client ID and Secret Key.
  2. Add a data group (yubikey_users) and populate it with username:serial pairs
  3. add an iRule event to your APM VPE
    1. set the name to OTP Valid
    2. set the ID to “otp_verify”
    3. add a branch rule
      1. name it Yes
      2. add an advanced expression of:

expr { [mcget {session.custom.otp_valid} ] == 1}


No too difficult.  Some ways that we could extend this code would be to try multiple cloud instances (api1.yubico.com-api5.yubico.com) and provide a self enrollment page if the user’s serial number is not in our data group – I’m writing an example of this with Google Authenticator and iRules LX so stay tuned.

U2F Authentication with F5 APM and Duo Security

Security-Key-by-Yubico-1000-2016-444x444I’ve been working on Universal 2nd Factor (U2F) authentication today and it’s a very interesting concept.  There is no requirement to enter a 6-digit code for 2nd factor authentication.  The website I’m logging into detects my Yubikey and the key button flashes a blue light.  Press the button and you’re automatically authenticated.

I’ve configured it with some of the websites I use and I’m going to give it a try for the next few weeks to see what I think.  Now, how to make sure I don’t lose it since I don’t normally carry my key chain around…

See the demo below with F5 APM and Duo Security:

iRules LX – AFM/APM Dynamic Firewall Rules

One of the iRules LX projects I’ve been working on is the ability to dynamically open firewall rules based upon a user’s APM Access Session.  In this example the user is external trying to access internal server resources but is blocked by AFM’s default firewall policies.  The user then logs into an APM policy and upon successful login AFM allows that external user access to internal resources.  See the video below for a demo:

iRules do not have direct access to control plane settings.  So prior to TMOS 12.1 this wasn’t easily doable without some serious iRule foo around sideband connections. However, with the introduction of iRules LX we can leverage Node.js to help us interact with the control plane via API calls.

So how does it work?

You still leverate iRules in iRules LX but a new set of commands allow you to pass data from TMM (data plane) to Node.js (control plane) and process that data via javascript – more information in the Getting Started With iRules LX series on DevCentral.

So what does this look like?

Your iRules do not change much except for the addition of the ILX commands:

  • ILX::init – invokes the specified node methods
  • ILX::call – establishes a communication path from an iRules to the node process
  • ILX::notify  – sends a message to the specified node method but does not wait for a response

As an example I’ve included the  iRule used in the AFM/APM dynamic firewall rule project below:

Notice the ILX::init on line 7 – this is configured with the iRules LX plugin name and the iRules LX extension inside our workspace.


What about Node.js

Next, you provide the Node.js methods your iRule calls in the index.js file

Not too hard and it offers a world of possibilities with the inclusion of NPM modules.

Where’s the rest of the code?

For a complete view of the iRules LX code please visit the Github repository.

iRules LX – 5 Tips to Get You Started

iRules LX is now GA with the release of TMOS 12.1.  I’ve been using iRules LX over the past two weeks working on some cool projects I hope to share in the near future.  In the meantime I wanted to provide some tips I’ve picked up while learning Node.JS and iRules LX.

1 – NPM makes life easier

Wow… I was speechless when I first heard that iRules LX would have native access to NPM.  I’ve seen some pretty cool internal projects that leverage publically available NPM tool sets and now you have the power of NPM inside TMOS.  So what does this mean… well for all you APM fans out that you can now read/write to SQL!  NPM allows you to quickly create applications and features without having to write everything from scratch.  This opens up a new world of possibilities for F5’s advance modules like APM and AFM.  More to come on this in the near future.

2 – Learn Node.js or make friends with a developer

There are probably more Node.js developers in your city than there are TCL developers in your state.. and probably your surrounding states.  So I was happy to hear F5 was opening up our development capabilities to a wider audience.  If you’re new to Node.JS I highly recommend Code School or if your organization has a membership to Safari Books  they have some great resources as well.

I’m also a big fan of test driven development. Mocha and Chai are great tools and supper easy to learn.  The benefit of TDD is you always know your code works.  If any update breaks something, the TDD process will find it.I also like developing the Node.js code on my laptop so TDD helps me verify that my java libraries work before I upload them to the BIG-IP for integration with iRules.

3 – DevCentral

Eric Flores over on DevCentral publish a great 5 part Getting Started with iRules LX series.  Between this and the Node.js video tutorial in the Safari Books online library I was ready to go.  DevCentral is also a great place to ask question and get assistance.  With over 250,000+ members it’s definitely a site you should familiarize yourself with.

4 – {}; or {}

Okay, so I’ve written some Node.js code and I’m finishing my iRules code to glue the processes together and when I hit the “Reload from Workspace” button I get a slew of iRule error…. guess what I did wrong 🙂  Can’t write JavaScript in iRules

Syntax issues bit me several times as I moved between iRules and JavaScript so be sure you keep an eye on this.  Some of the most common issues:

Accessing a variable in iRules requires a $, in JavaScript it does not
JavaScript uses a semicolon (;) at the end of a statement, iRules does not

5 – Callback hell

One of the hardest things for me to wrap my head around while learning Node.js is the concept of synchronous vs asynchronous processes.  I’ve always been use to writing code in a synchronous way so it stumped me why my functions would not return a value or my debug statements were always empty.

An easy way to think about it:

if you’re reading/writing to a filesystem or a web server then use an asynchronous process
if you’re reading/writing to a local function, say generating a secret key for Google Authenticator, then use a synchronous process
Also, in your Mocha test framework you’ll need to use the break() function for any process that are synchronous.

I hope these tips help you has your dive into iRules LX.  I’ve definitely enjoyed working with iRules LX over the past two weeks and I’ll share my projects with you once they’re publically available.

Prepopulate APM Username From O365 Login

emojiF5’s Access Policy Manager (APM) offers many compelling security and optimization features for Microsoft’s Active Directory Federation Services (ADFS) – more info in the APM/ADFS Deployment Guide.  Odds are if you’re deploying ADFS you’re also using or looking at Office 365.  Normally, when you login to O365 you will be redirect to a Home Realm Discovery page, login.microsoftonline.com.  This page does 2 things:

  1. determines if you’re a federated users (i.e. you use another authentication source like F5, MS ADFS, Okta, …. <insert long list of IDMs on the market today>).
  2. if you’re not a federated user, authenticate you against Azure AD.
Office 365 Empty Login Page

So when you type in your email address Microsoft parses the domain name and automatically redirects you to your local APM/ADFS environment for authentication – pretty nice! However, when you land at the APM login page you notice the username field is empty and you have to enter your username or email address (depending on how APM is configured for authentication) again.

You can fix this by customizing the APM Visual Policy Editor to look for O365 to ADFS logins and prepopulate the username.

Username Prepopulated from O365

So what does the APM configuration look like?

Final VPE

Step 1: Create an object to detect O365 to ADFS Login 

  1. Click the (+) button on the Start fallback branch
  2. In the search box type empty and select the Empty resource then click “Add Item”
  3.  Name the resource O365 Login
  4. Click on the “Branch Rules” tab and click “Add Branch Rule”
  5. Name the branch “Yes” and add the following expression via the advance tab
    • expr {[mcget {session.server.landinguri}] contains “username=”}
  6. Click Save


Detect O365 Login


Step 2: Extract the Username from the O365 Redirect Request

When the user enters their email address into the O365 login this data is included in the GET request back to the APM/ADFS environment.

O365 Login with Federation Redirect
O365 Redirecting to APM/ADFS

To capture this data we’ll need to create perform the following steps:

  1. Click the (+) button on the Yes branch off of O365 Login
  2. In the search box type variable and select the Variable Assign resource then click “Add Item”
  3. Name the resource “set username from O365” and add the following variables

session.logon.last.username = expr {[string range [mcget {session.server.landinguri}] [mcget {session.custom.pos_username}] [mcget {session.custom.pos_at_sign}]] }

session.custom.pos_at_sign = expr {[string first “%40” [mcget {session.server.landinguri}]] – 1}

session.custom.pos_username = expr {[string first “username=” [mcget {session.server.landinguri}]] + 9}

Click “Finished” and then click “Save”

Set Custom Variables

Step 3: Customize the APM Logon Page

Now that we have the username we need to prepopulate it on the APM Logon page and set the form variable to read only.

  1. Click the (+) button on the “set username from O365” fallback branch
  2. Select “Logon Page’ then click “Add Item”
  3. Name the resource “O365 Logon Page”
  4. Change the “Read Only” setting for field 1 to “Yes”
  5. Click  “Save”
APM Logon Page

The remainder of the VPE configurations are basic and are not covered in this article to keep it from being a novel.

That’s it!  Now you’re user’s only have to enter their information once which will definitely make them happier.