One-time passwords

Every once in a while (not too often) I leave the house without my trusty laptop or maybe I’m just in a place with no wifi available to me. In such cases I sometimes need access to one of my servers or perhaps just my e-mail, but I’ve always felt uncomfortable entering my password on strange computers, especially ones running Windows. You never know what kind of key loggers or other kinds of spyware they might be infected with. Every time I’ve done it, I’ve always changed my password on said servers the next time I’m using my own laptop which I quite trust. This procedure gets quite annoying. Enter OPIE.


OPIE is a free implementation of the S/KEY (one time password) specifications (RFC 1760 and RFC 2289). The idea is that each password is only usable once so it doesn’t matter if anyone grabs it as it’ll be useless when they try to use it.

Setting it up was quite simple:

  • Install the opie-server package.
  • Add pam_opie to your pam configuration. If you haven’t tweaked your pam configuration at all, you can just copy /usr/share/doc/libpam-opie/examples/pam.d/common-auth to /etc/pam.d/common-auth. You’ll still be able to log in as you’ve always done it, but also with your shiny new one-time-password setup.
  • Now, as your regular user, run opiepasswd. You’ll see a prompt like this:
    Adding sh:
    You need the response from an OTP generator.
    New secret pass phrase:
            otp-md5 499 bi0617

    Now, in another terminal, run the command shown (in this case otp-md5 499 bi0617). This will look something like this:

    $ otp-md5 499 bi0617
    Using the MD5 algorithm to compute response.
    Reminder: Don't use opiekey from telnet or dial-in sessions.
    Enter secret pass phrase: 

    Your passphrase will have to be 10 characters or more. Now, enter that (“DARE LAID BUM TAB PI BURY”) into the opiepasswd session from before.

    Adding sh:
    You need the response from an OTP generator.
    New secret pass phrase:
            otp-md5 499 bi0617
            Response: DARE LAID BUM TAB PI BURY
    ID test OTP key is 499 bi0617

    And that’s it. From now on, you can log in using these one time passwords. Try su - yourusername and just press enter on the well-known “password:” prompt, and you’ll be prompted for a one-time-password.

All that’s left is a way to get your hands on these one-time passwords when you need them. You can either use the otp-md5 tool to generate a bunch of passwords, print them, and carry them with you (see the man page for otp-md5 for details on the -n option), or you can install a generator on your mobile phone (there are several options available) or your Nokia 770 if you are lucky enough to own one of those.


As I mentioned in the beginning, I needed this for webmail, but as you might know, when using PHP based webmail systems every page load means a new login to the IMAP server, but when your passwords are only good for one login, you’re not going to have a very enjoyable experience with this setup. But if we add imapproxy to the mixture we’re back in business.

imapproxy was created to offload imap servers from these excessive logins, but at the same time, it resolves our problem. When connecting for the first time, imapproxy passes your authentication credentials on to the imap server, and if succesfully authenticated, it remembers your password for a configurable amount of time while keeping the connection to the imap server open… so the webmail app will keep using your (almost-but-not-quite-)one-time password to authenticate against imapproxy. Make sure you configure a relatively short cache_expiration_time so that the window of opportunity for an attacker is as narrow as possible. I’ve set it to 70 seconds since my webmail system refreshes every minute, so 70 seconds leaves a bit of time for different delays and such.

A word of warning:If you’re writing an e-mail from the webmail system, it might not be refreshing every minute anymore, so if you’re writing a long e-mail, make sure you do it in a different window so that when you click send, you won’t be rejected because the connection from your imapproxy to your imap server has been dropped and hence your password has expired.

The configuration file for imapproxy is heavily commented, but here’s is mine(stripped for comments and blank lines) if you’re interested:

server_hostname localhost
cache_size 3072
listen_port 144
server_port 143
cache_expiration_time 70
proc_username nobody
proc_groupname nogroup
stat_filename /var/run/pimpstats
protocol_log_filename /var/log/imapproxy_protocol.log
syslog_facility LOG_MAIL
send_tcp_keepalives no
enable_select_cache no
foreground_mode no
force_tls no
enable_admin_commands no

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>