Documentation

User and Admin Guides

Quick Install & Test
Quickstart Guide
Advanced Guide
winOTP Guide
mobileOTP Guide

Application Notes

Netscreen IPsec VPN

Whitepapers

Software Architecture
Passcode Guessing
 

TRI-D Quickstart Guide

v2.0 (2008/01/30)

Overview

This guide is a primer on installing, testing and configuring the TRI-D Systems OTP server software. This guide is sufficient to get you started but is not a substitute for the man pages and other documentation included with our software.

If you are evaluating OTP systems, we encourage you to download and try our software. It is very easy to setup and test, and should generally take only 5 to 15 minutes.

Software architecture

A detailed explanation of the TRI-D Systems software architecture can be read in our software architecture whitepaper. The following is a summary to aid in deployment.

First an existing authentication server is required (for deployment, but not necessarily for initial testing), such as FreeRADIUS or PAM. TRI-D Systems does not provide this software directly because we believe in enhancing already existing standards based authentication servers. Instead we provide plugins for existing servers and encourage the development of third-party plugins. Our software then acts as an adjunct to the existing authentication server to provide OTP functionality.

The primary component that we provide is otpd, the One-Time Password authentication daemon. Your existing authentication server talks to this daemon via the supplied plugin interface. otpd will need to be installed directly on any authentication server which wishes to authenticate users with One-Time Passwords.

Besides doing the work of verifying OTPs, otpd also manages token state locally. State is data such as last used passcode, number of consecutive failures, etc. There is another server, gsmd, which we provide as part of our Enterprise Edition, which manages state globally and allows multiple otpds to use a common state database. This is a requirement for a distributed environment.

Compiling and installing the server software

Obviously, you must first download the otpd software. Version numbers for all our software are of the form MAJOR.MINOR.PATCH. In the descriptions below we simply use x.y.z to indicate the latest version.

For Professional and Enterprise Edition customers, we additionally provide pre-built packages which you can just install, skipping the compilation step. (Or you can choose to compile if you need to customize certain settings.)

Linux

On RPM-based systems, simply run rpmbuild -tb otpd-x.y.z.tar.gz and you will end up with an rpm that you can install.

On debian-based systems, first you must unpack the downloaded tarball and cd into its top level directory. Then run dpkg-buildpackage -rfakeroot.

Other Unix

For all other unices, or if you want to compile by hand anyway, simply use the standard CMMI (configure, make, make install) method. When compiling by hand, you must also create the runtime socket directory /var/run/otpd, and will need to create and install an init script. You can use the redhat, debian or solaris init scripts as starting points.

Testing the server software

For the purpose of testing, you do not need to change the default configuration settings for otpd.

First, create an /etc/otppasswd file and add a test user. Consult the otppasswd(5) man page for details. Also, create the /etc/otpstate directory.

Then, start otpd in debug mode (otpd -D).

Lastly, use otpauth to attempt trial authentications. In the window where you started otpd, watch the debug output for messages. (Note that the output below is slightly modified from the actual server output, for presentation reasons).

$ cat /etc/otppasswd
# sample data, the exact values do not matter
test:trid-soft-hotp-d6-e4:fedcba9876543210fedcba987654321000000000
$ otpauth -u test -s /var/run/otpd/socket -p 123456
3 (authentication error)

[in otpd window]
otpd: accept_thread: plugin accept fd=5
otpd: work_thread: tid=5, fd=5
otpd: work_thread(5,5): handling plugin request for [test]
otpd: state_parse: null state data for [test]
otpd: verify: [test], challenge t:0 e:0 011c836e00000000, response 217338
otpd: verify: [test], challenge t:0 e:1 011c836e01000000, response 029459
otpd: verify: [test], challenge t:0 e:2 011c836e02000000, response 621115
otpd: verify: [test], challenge t:0 e:3 011c836e03000000, response 779722
otpd: verify: [test], challenge t:1 e:0 011c836d00000000, response 310252
otpd: verify: [test], challenge t:1 e:1 011c836d01000000, response 941373
otpd: verify: [test], challenge t:1 e:2 011c836d02000000, response 108972
otpd: verify: [test], challenge t:1 e:3 011c836d03000000, response 546893
otpd: verify: user [test] authentication failed
otpd: work_thread(5,5): plugin disconnect

The first thing to notice is that otpauth prints '3' as its output. This is the error code that otpd returned to it. The exact values are not important for this exercise, except that '0' is a successful authentication. Now of course, this authentication failed because we don't actually have a token and don't know what the OTP should be. The point is just to verify that otpd accepts authentication requests and responds correctly. In fact, if the authentication had succeeded, it would be worrisome.

The line "null state data" indicates that state did not previously exist for user "test". This is expected, since this is the very first time otpd has ever seen an authentication for that user. But now that an authentication request has been made, you can see the state data in /etc/otpstate/test (if you care to look).

Before explaining the rest of otpd's output, we need to present some background material on OTP authentication.

All (for our purposes) OTP systems work by transforming some input value (a challenge) into some output value (a response). The transformation is either an encryption or a hash of the plaintext challenge, and a printable/typable encoding of the ciphertext response. The encoding of the response becomes the OTP. In order for the "OT" requirement in OTP to be met, the challenge must change after every successful authentication. This was classically accomplished with challenge/response systems, where the authentication server presents a challenge (interactively) to the user, and the user enters the response.

However, the UI for challenge/response is poor: the user has to enter the challenge into a device which is typically either bulky, or if in a small form factor, then difficult to use. Entering the challenge value into a small handheld device is also prone to error.

Thus, the synchronous challenge was born. With a sync challenge, the OTP device and the OTP server independently generate what they consider to be the "next challenge". This can be based on previous challenges, previous responses, number of uses, or for the best compromise between usability and security, the current time. All OTP devices made today use synchronous challenges.

Because the token and the server generate the challenge independently, they can get out of sync with each other. Therefore, otpd has to try multiple challenges (within a limited range) before deciding that an OTP is incorrect. In the output above, you can see how otpd increments the time and event counters to generate each successive challenge. The t: and e: numbers are relative time and event counters (they always start at 0 for any given authentication) and the long hex string is the challenge value generated from those counters. For the example above, the type of token we configured in /etc/otppasswd is a time+event synchronous token, and therefore both the time and event counters increment as otpd attempts to authenticate the user.

What we really care about in the debug output is the response value. Actually otpd doesn't show the true response, it only shows the result after encoding it into an OTP. Note that PINs are never shown in any otpd debug output. In our example this doesn't matter because we didn't assign the user a PIN.

Instead of using 123456 as the password (given to otpauth), if we had used 217338, or any of the other 7 responses shown, we would have successfully authenticated. However, if you do that now, it is likely to fail again. That is because our example token is time synchronous, and time has moved forward if you've been testing while reading along.

So now, to verify that otpd will successfully authenticate a user, use otpauth twice, quickly, the first time with a random OTP and the second time with an OTP from the debug output. otpauth will print '0' the second time, indicating a successful authentication. You will also want to try the correct OTP twice in a row, to verify that otpd does not allow re-use of a passcode. Thirdly, you might like to wait a couple of minutes and try again, to verify that all of the possible OTPs have changed (since time has moved on).

Now, this doesn't really test that otpd can successfully authenticate an actual token. All we've done is to show that if we enter what otpd was expecting, we will be authenticated. This is still important, as we have demonstrated that the communication between an authentication server (in this case, simulated by otpauth) and otpd does work correctly.

Configuring the authentication server

After getting otpd installed and running, you will need to put an authentication server in front of it. Any authentication server which accepts plugins or is extensible (i.e., most of them) can be a frontend for otpd. Currently, we provide a PAM plugin and directly support FreeRADIUS (which already includes our plugin).

FreeRADIUS

TRI-D Systems recommends that you use a version of FreeRADIUS >= 1.1.5. Many OSes come with FreeRADIUS, however not all OSes come with the rlm_otp module. If it is missing, you will need to recompile FreeRADIUS.

Once you have FreeRADIUS and the rlm_otp module installed, OTP configuration is trivial. Just edit /etc/raddb/radiusd.conf to uncomment the line in the modules stanza which includes otp.conf. Then add the otp authentication type to both the authorize and authenticate stanzas.

modules {
  $INCLUDE ${confdir}/otp.conf
}

authorize {
  otp
}

authenticate {
  otp
}

PAM

Our PAM module, pam_otp_auth, works like any other. It only supports PAM authentication and no other PAM functionality (account, session, password), since for OTP only the authentication component makes sense.

When using PAM, just like when using any other authentication server, otpd must be running on the same server. Since PAM is generally used for local authentication, pam_otp_auth is almost always inappropriate, just because every server will have its own copy of the state database and therefore passcode reuse will be possible (across servers).

pam_otp_auth does have a place in specific configurations, but almost always what you really want is pam_radius on all your application servers, pointing to a central FreeRADIUS server where otpd/lsmd are running.