All corny early 90's hip hop jokes aside, if you're not down with OTP or One-Time Password by now, then this is definitely the place to be. By the time you finish this two part series you will understand and be able to deploy a complex OTP policy complete with error handling. We will start with the basics in part one and then drive it home in part two.

Like many, my first experience with OTP and APM on the BIG-IP was guided by fellow F5'er, Per Boe's excellent write up from a post that none other than the illustrious, Jason Rahm shared with us way back in early 2011. As with all things tech, 3 years later things have changed quite a bit and although fundamentally OTP has not changed that much, our implementation has been streamlined. For instance, the once necessary iRule has been integrated and we can do some really cool new things with embedded dropdown options on the logon page. Cody's great Cookbook article here demonstrates the very popular dropdown use-case for domain selection.

In part one we will review all of the necessary objects and configuration of those objects. Then we will start with a functional OTP Access Policy that leverages the objects we created to get familiar with the basic concepts. This will be very similar to the write up from 2011 but with an open-source SMS Gateway that anyone can use free of cost. Finally, we will wrap things up in part two with a deeper dive into OTP as a technology and create a more complex OTP policy. This policy will include a logon page dropdown (new in 11.5.x) that can dynamically select the use of SMTP and SMS delivery mechanisms, with full error handling, based on available AD attributes or logon page selection.

By the end of these articles you will be more than down with OTP, I promise!! In fact you should be floored with all of the possibilities that VPE can provide by implementing policy branches to customize the UX....which is what it's all about right??  Well maybe...after SUX - the (Secure User Experience) of course :)

BTW: This lab demonstration was a blast to build out and if you are anything like me, then the first time you hear that SMS alert come in on your phone, you will definitely smile. Try it out, have fun and post feedback!


You will need the following before proceeding with Part 1:

  • A client to test from (Windows, MAC or Linux with any browser)
  • Active Directory with the following attributes available and set with values; (mobile, mail)
  • A BIG-IP with APM provisioned. (v11.x) - recommended 11.5.x.
  • Your BIG-IP must be able to get to the Internet.
  • A device capable of receiving SMS

Part 1:

Creating the Virtuals

We will begin by configuring the Virtual Servers that will host the APM Access Policy.
All you technically need is a standard virtual server listening on port 443 with an http and client side ssl profile applied.
Given you are working in the Common partition, create your virtuals with the following commands.

tmsh create ltm virtual /Common/ {destination /Common/:443 ip-protocol tcp mask profiles add { /Common/clientssl {context clientside} /Common/http { } /Common/tcp { } } source translate-address enabled translate-port enabled }

Optional: Create a port 80 redirect so you don't have to remember to type "https"

tmsh create ltm virtual /Common/ { destination /Common/:80 ip-protocol tcp mask profiles add { /Common/http { } /Common/tcp { } } rules { /Common/_sys_https_redirect }}

Verifying Resources

AD - Do not move on until you can authenticate with an account (preferably a service account but any will do for this lab as long as it can authenticate and read). Instructions for validating authentication can be found below in Figure 1.

Configure your Active Directory Object under:

Access Policy >> AAA Servers


Figure 1. Configuring AAA AD Servers

To verify the above configuration before moving forward you can use the "adtest" command.
*The special characters in the password are escaped with "\".
adtest -t auth  -h "" -r "" -u serviceacct -w p\@\$\$w0rd1
[root@bigip1:Active:Standalone] config # adtest -t auth  -h "" -r "" -u user1 -w p\@\$\$w0rd1
Test done: total tests: 1, success=1, failure=0
Tip: use the debug option if you have failures. -d 1

adtest -t auth  -h "" -r "" -u serviceacct -w p\@\$\$w0rd1 -d 1

Once authentication is verified we can create our OTP HTTP Form, also found under Access Policy >> AAA Servers

Figure 2. Configuring AAA HTTP Form

A quick word on textbelt, a free open source SMS gateway and brain child of Ian Webster, a Software Engineer at Google. We all owe him a debt of gratitude and possibly a donation for maintaining a free, awesome and downright user friendly SMS service. There are a few limitations that you can get familiar with here: but in general this sublime open source SMS service can't be beat for ease of use and lab testing. Thanks Ian!

Take a close look at the Form Method, Form Action, Hidden Form Parameters/Values and Successful Logon Detection Match Type and Value fields in Figure 2.

Most of the parameters/values were dictated by the textbelt API and are included on the textbelt homepage but the Hidden Form Parameters/Values field has some unique customizations so that APM can insert custom variables per the session.


Let's break down the variables in the string for the Hidden Form Parameters/Values field:
Values will be learned during certain stages of policy execution. For example, when the AD Query action takes place the "mobile" attribute will be learned and stored in memory as a session variable. When the OTP Generate action takes place then the value will be determined for that session variable.

number=%{}&message=OTP %{session.otp.assigned.val} Expires after use or in %{session.otp.assigned.ttl} seconds.              

The variable "{}" will pull the value from the Active Directory Attribute for "mobile".

The variable "{session.otp.assigned.val}" will pull the value from a secure memory space and insert it into the message body.

The variable "{session.otp.assigned.ttl}" will display the timeout value in seconds for the OTP as configured in your policy.

Ultimately the message will look like this when it is sent to the SMS Gateway:

number=555123456&message=OTP 786341 Expires after use or in 300 seconds

If you have problems, Ian also listed some troubleshooting commands that you can utilize. Make sure to check those out, assign all fields per the image above and move on once you have the syntax correct which should be fine as long as you followed the steps above.
That's it for the pre-requisites. Now time for the fun part...tying it all together in VPE with an Access Policy.

Access Policy Configuration

Head on over to Access Policy>>Access Profiles>>Access Profiles List and click the "+". Create an APM/LTM type profile and take all of the defaults. Choose your language and hit "Finished".

Now edit your policy. You should be here:

Figure 3. Creating the Access Policy


Add a logon page and take the defaults.

Add an AD Auth object and set your AD Server.

Figure 4. Adding AD Auth
Add a message box or MB, off of the successful branch and keep the successful ending at deny.

APM Pro Tip: This MB will serve as your successful ending alert and prevent you from having to manually clear sessions constantly during the policy testing phase.

Figure 5. Adding a Message Box (MB)


Your policy should now look like this:      


Figure 6. Visual Policy



Now apply your new Access Policy to the Port 443 Virtual Server and test. If all goes well you should see this positive affirmation after successful authentication:

Figure 7. Message Box - Positive Affirmation



Adding the OTP Macro    


Figure 8. Adding the OTP Macro


Add an Ad Query object, name it appropriately and choose your AD server.
Set the Required Attributes to "mobile" and "mail". (We will only use mobile in Part 1 of this series)
Figure 9. Adding AD Query & Required Attribs


Edit the Branch Rules and delete the default expression "Primary User Group 100".
Figure 10. Editing AD Query Branch Rules



Add an OTP Generate object and take the defaults. Your policy should now look like this:

Figure 11. Verify the Visual Policy - OTP Macro


 After the OTP Generate object add a variable assign object:

Custom Variable: session.user.otp.pwd = session.user.otp.pwd
Custom Expression: expr {[mcget {}]}
Figure 12. Variable Assign - Secure OTP

(Select Secure from the list to define the session variable as secure. A secure session variable is variable that is encrypted in the session database. The secure session variable value is not displayed in the session report, or logged by the logging agent.) 


Next we are going to call on that HTTP AAA Form that we created earlier. Add an HTTP Auth Agent:

Figure 13. Adding HTTP Auth Agent



Add another logon page so the client has a place to enter their OTP password:

Figure 14. Adding the OTP Logon Page



Add an OTP Verify Object.

Your policy should look like this:

Figure 15. Verify Visual Policy - OTP Macro



Edit your terminals to indicate success or failure:

Figure 16. Editing Terminals



You may need to add a new one. Make sure that the default stays on top:

Figure 17. Adding New Terminals



Now add the Macro to your main policy between the AD Auth and the MB:

Figure 18. Adding the Macrocall
Here is the final policy. We will keep the allowed ending set to "deny" for now until we are ready to go prime time with the site.
Figure 19. Verify Visual Policy - Complete


As long as you have your mobile number set under the AD Attribute and given your BIG-IP has outbound connectivity, then you should now be able to successfully test your new service and receive a SMS that, when received, looks like this:

Figure 20. IOS - SMS Message Received


If you successfully authenticate you should reach your affirmation again.


Figure 21. Congratulations!
Not only have you achieved success, you have completed part 1! Great job.            
Please be sure to check out part 2 where we will dive even deeper into APM and this OTP policy.

Here's a sneak peak at the macro:


You didn't think I was going to show you the whole thing yet did you?!!?

‘til next time…