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.
|