Pilot service for Yubikey two-factor authentication

February 23, 2016

Is a local authentication service necessary/desirable?

So far in this project, we’ve used Yubikeys (in standard Yubico OTP mode, and in their factory-default condition) to provide second factor authentication for both ssh and Cosign logins. There are, of course, service-specific configurations necessary in order to arrange such authentication but – purely regarding the implementation of the back-end authentication of the one-time passwords produced by the Yubikeys – we initially used the Yubico ‘cloud’ authentication service to perform this.

By now, we have also set up a local authentication service (still only in prototype form: the service uses hand-configured machines), and – after suitably reconfiguring our test Yubikeys – have used that service to perform back-end authentication. (See the previous post Yubikey authentication servers for some more general background on local authentication servers. Specifically, also, see Yubico’s Installation notes for a YK-VAL server and Installation notes for a YK-KSM server.)

As further background, recall that, whether ‘remote’ or ‘local’, the authentication server essentially implements a web service: a one-time password is passed over HTTPS, and the authentication server responds with a ‘valid’ or’ ‘not valid’ response. As well as being present and available at all times, it’s obvious that – to provide a usable service – the authentication server needs to respond quickly to every request it receives.

It is also important to note that the authentication servers do not contain, nor do they need to be informed of, any user-specific data – e.g. usernames, UIDs, etc. They have a shared secret with each Yubikey – namely, the Yubikey’s AES encryption key – and they use that encryption key, in conjunction with the public id of the Yubikey, to determine whether the one-time password being presented on behalf of any Yubikey is or is not valid. All of the user-specific data – and, specifically, the association of Yubikey public id to username/UID – remains at the ‘client’ server end.

We now have to decide which of these two types of authentication service – the Yubico ‘cloud’ service, or an in-house local one – we want to use when we start to use Yubikeys in earnest for second factor authentication. It’s not an obvious choice, so let’s try to summarize the pros and cons:

Yubico ‘cloud’ authentication service


  • Requires registration, but is free of charge, and essentially simple to use.
  • Is pre-configured with the as-delivered public ids and AES keys of all Yubikeys – so all Yubikeys can authenticate against the service ‘out of the box.’
  • Overall, much less work to set up and use than would be a local service.


  • Not guaranteed to be permanent: Yubico could disappear as a company tomorrow and, whilst all Yubikeys would continue to work, the Yubico ‘cloud’ authentication service could disappear.

    (But we have no reason to believe the service will disappear.)

  • Not guaranteed to remain free of charge.

    (But we have no reason to believe the service will become chargeable.)

  • Requires the Yubico cloud servers to be on-line.
  • Requires a working network in order to reach the Yubico cloud servers.
  • Potentially at more risk of sluggish response than is a local service acting under more deterministic conditions and load.

    (But our limited experience so far has shown no such problems when using the ‘cloud’ service.)

  • Necessarily transmits both data and metadata to a third-party, namely Yubico.

    (However, note that we are already implicitly trusting that third-party by choosing to use their hardware devices.)

  • Although Yubico don’t get sent any actual user data per se, the key’s public ID is enough to allow both Yubico – as well as anyone who can see their traffic or database – to track the user, and to correlate their activity over time.

    (However, note that the traffic will be encrypted over HTTPS and, if any other than Yubico has access to Yubico’s database, then a more serious security breach has probably occurred – see the following point.)

  • Yubico’s authentication servers present an attractive target for criminals. If those servers were compromised, and (public id, AES key) pairs stolen – and nobody noticed (or was suitably informed) that this had happened – then Yubikeys using the same (public id, AES key) pairs could be cloned. How useful such keys would be to a criminal would depend on where those keys were being used: information about authentication services for which any key is ‘good’ is not part of the key material, but it is possible that additional metadata – which in principle could be also stolen from Yubico – could give a clue.

Local authentication service


  • Maintains all server dependencies ‘in-house.’
  • Maintains all data and metadata ‘in-house.’
  • Does not require a working external network in order to provide authentication.


In our (i.e. the School of Informatics) environment, setting up a robust local Yubikey authentication service would require us to have the initial configuration and subsequent maintenance of both YK-VAL and YK-KSM servers managed via LCFG control, as far as possible. And, likewise, to similarly automate the maintenance of the keying data (public ids, AES keys) held by those servers. (As a detail: such data is held in PostgreSQL databases on out prototype YK-VAL and YK-KSM servers.)

The question is: what approach should we take here? The amount of work in setting up a local authentication service is definitely not trivial – so we need to decide if we want to (or, perhaps, need to) do it. This is really a policy question, but it also depends on what kinds of resources we might be planning to hide behind second factor authentication: we must avoid the possibility of having access to any critical resource at risk of being hampered by problems with the external network! (An example might be a resource, or information, to which we need access in order to fix a particular problem with the network. That is: we need to consider the possibility of ‘chicken and egg’ problems.)

Comments on this post are invited from anybody with an interest or an opinion; any such comments would be welcome. Thanks.

November 24, 2015

Cosign client configuration for Informatics ‘Theon’ websites

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 8:35 am
Tags: ,

As a brief note, internal to Informatics:

We’ve now set up two-factor Cosign authentication on a test ‘portal.theon’ website. Apart from pointing that client site at the appropriate test Cosign server, the only necessary configuration is the inclusion of appropriate CosignRequireFactor directives at suitable places within the Apache configuration hierarchy.

For testing, we’ve placed these directives using both Apache <Directory> stanzas, and also within .htaccess files. Both approaches work, and both therefore ‘switch on’ two-factor authentication at a directory level. (We assume – but have not tested – that <Files> stanzas could be used to make the authentication demarcations even more fine-grained. But, on the other hand, the simpler these demarcations are, the better.) Note, of course, that CosignRequireFactor directives placed within .htaccess files work if and only if the necessary Apache ‘Overrides’ declarations are in force.

Specifically, to populate the appropriate .htaccess files within the test ‘portal.theon’ website, the final approach taken has been to amend the relevant TP000...Access conduits so that a CosignRequireFactor INF.ED.AC.UK otp directive is appended as a verbatim gurgle %%footer statement.

November 22, 2015

Cosign ‘factors’ – a correction

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 3:12 pm
Tags: ,

In a previous post – ‘Cosign ‘factors’‘ – I wrote:

“Authorization by factor can be arranged via ‘AND‘ and ‘OR‘ combinations: a CosignRequireFactor directive which includes multiple factors implies that those factors are AND‘ed together; multiple CosignRequireFactor directives are OR‘ed.”

And, indeed, the “Cosign Multi-Factor Specification, 20 March 2006, Draft 6” contains the following statement:

“Filters may be configured with a list of required authentication factors. For Apache:

CosignRequireFactor UMICH.EDU OTP


CosignRequireFactor LEVEL2

would indicate that either ( UMICH.EDU & OTP ) or just LEVEL2 are required to satisfy the filter’s multi-factor authentication criteria.”

To correct this: my statement regarding the OR‘ing of multiple CosignRequireFactor directives was incorrect; and the above-mentioned statement in “Cosign Multi-Factor Specification, 20 March 2006, Draft 6” is possibly misleading.

In fact, currently, the Apache Cosign filter does not allow the specification that a user must satisfy factor A OR factor B.

Testing shows that, if multiple CosignRequireFactor directives are declared in any particular case, the most ‘recently defined’ CosignRequireFactor directive wins.

In fact, this is probably the behaviour that we actually want: it means that a top-level CosignRequireFactor directive is completely supplanted by one at a lower-level one, rather than being OR‘ed with the previous declaration. In this way, we can safely enforce ‘stricter’ authentication conditions at the lower level.

November 15, 2015

A brief diversion: Cosign and SPNEGO

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 9:44 am
Tags: ,

I mentioned in the previous post Some background: what’s Cosign, and how does it work? that:

… the ‘single sign-on’ can work even better than that. Since the underlying authentication protocol is assumed to be Kerberos, a web browser which is capable of using SPNEGO is able to use a user’s existing Kerberos tickets for the initial authentication sequence. The result is that access to institutional Cosign-protected websites is completely transparent.

In that same post, I also mentioned that:

… documentation pertaining to Informatics-specific local Cosign modifications is also rather scattered …

For reference purposes, here are a couple of relevant pieces of information:

  1. A post regarding SPNEGO authentication and fallback from the Cosign-discuss mailing list discusses the Javascript ‘trick’ which we (i.e. Informatics) use in our Cosign setup in order to use SPNEGO if possible – or to gracefully fallback, if SPNEGO doesn’t work.
  2. A blog post from Simon Wilkinson – the original author of both our solution, as well as the above post to Cosign-discuss -, which describes the same thing, namely Cosign and SPNEGO.
  3. For SPNEGO (and Kerberos ticket delegation) to work in Firefox, users will need to set appropriate values in the two about:config variables network.negotiate-auth.trusted-uris and network.negotiate-auth.delegation-uris.
    In cases where multiple URIs need to be specified for either of these variables (which might well be the case in the testing phase of any implementation, for example), note that the delimiter is ‘,‘ – i.e., a comma. Neither a space, or a semi-colon, will work!

November 10, 2015

A test Cosign service using Yubikey two-factor authentication

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 7:08 pm
Tags: ,

The previous posts regarding Cosign and Yubikey two-factor authentication are intended to record the investigations and thought processes which have taken place to date during the course of this project. As such, they might seem rather theoretical – but they’re a record for us and, with luck, they might also be of use to other people thinking of implementing the same thing.

However: in practice, where are we with this project right now?

At present:

  1. We have a working test Cosign server, customized with the standard Informatics look-and-feel, which is configured to implement two-factor authentication; the two factors being Kerberos username/password, and Yubikey OTP.
  2. We have a working test Cosign client website configured to authenticate against the two-factor server.
  3. Almost all of the configuration for both server and client has been tidily included in the corresponding LCFG profiles, and almost all of the necessary s/w has been packaged to our usual standards. (In that respect, some work remains to be done: for example the building and installation of the ‘universal Cosign PAM factor adaptor’ needs to be integrated into our ‘normal’ Cosign packages.)
  4. Two test users (currently, we have only two test Yubikeys available) have been verifying the service, with good results. We find that the two-factor authentication (including Kerberos SPNEGO) works intuitively, and we are able successfully to configure different sections of the client website to require differing levels of authentication: some single-factor; others two-factor; etc. (all this being arranged via appropriate CosignRequireFactor entries in Apache <Directory …> stanzas.)

In summary: the test service seems to provide what we want.


  1. The configuration for the Yubico PAM module is exactly the same as described in the previous post Towards two-factor Yubikey authentication with OpenSSH, namely:
    auth	required	/lib64/security/pam_yubico.so	id=<secret> key=<secret> authfile=/etc/yubikey_mappings debug 
  2. There is no specific ‘per-user’ treatment in the PAM configuration (as there is, for example, in the corresponding test ssh configuration described in the previous post mentioned above): anybody attempting to authenticate via a Yubikey is doing so because they want access to web content explicitly mediated via Yubikey authentication: such authentication either succeeds, or it doesn’t.

What we plan to do next:

  1. The current test client website is purely a proof of concept. We now plan to set up a test website to provide access to the School database (via ‘Theon’), in order to demonstrate two-factor access to ‘real’ data.
  2. We are purchasing more Yubikeys so that all members of the Computing staff – as well as any other interested parties – can participate in the trial.
  3. Currently, we associate Yubikey ID’s with School usernames via a map file – namely /etc/yubikey_mappings. That works, but isn’t particularly scaleable. We would like to investigate the use of LDAP to hold those mappings: the Yubico PAM modules supports that.
  4. Currently, we use the Yubico ‘Cloud’ service as the back-end authenticator. For any real service we will need to perform Yubikey authentication in-house – so that needs investigation. Failover and/or replication of any such service needs thought.
  5. Some further work is necessary to tweak the HTML and Javascript supporting the two-factor Cosign service.
  6. Amendments to building and packaging are necessary to incorporate the Universal PAM factor adaptor into LCFG.
  7. And other issues will undoubtedly arise in the course of the further testing to come …

A Yubikey Cosign authentication ‘factor’

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 3:34 pm
Tags: , , ,

Bearing the above specification in mind, we could now write a Cosign ‘factor’/authenticator which targets Yubikeys: we’d just need to feed it with the username, as well as the one-time-password produced by the Yubikey; have it perform the authentication – by slaving that off to a back-end authentication server; and then have it produce outputs as specified by the protocol.

However: we already have a Yubico PAM module which handles the details of the back-end authentication of the Yubikey one-time-password, and it turns out that a ‘universal Cosign PAM factor adaptor’ is available – see the relevant postings on the cosign-discuss mailing list. So we can use that instead.

The relevant C code file is now part of the Cosign download tarball, but it’s not autobuilt as part of the ./configure; make process. However:

  1. find it (as file pam_factor.c in the cgi/factors directory of the distribution);
  2. build it as follows:
    gcc -lpam -o pam_factor pam_factor.c
  3. copy the resulting binary factor to some suitable location, e.g., /usr/lib/cosign/factors; and
  4. edit /etc/cosign.conf to add the factor.

In the /etc/cosign.conf configuration file, all this finally takes the form:

factor /usr/lib/cosign/factors/otp login passcode

where otp is a symlink to the universal Cosign PAM factor adaptor pam_factor, and a new ‘otp‘ PAM service using the Yubico PAM module has also been declared.

Note: the name of the factor is significant, and is more than just, for example, self-documentation! Recall that the factor must, on successful authentication:

  • write the factor name to stdout; and
  • exit with 0.

The universal Cosign PAM ‘factor adaptor’ is coded to emit a factor name which corresponds to its basename – i.e. in our case, it will emit the factor name of ‘otp‘ on successful authentication. So the literal factor name ‘otp‘ is what the rest of the corresponding Cosign configuration client-side must be set up to expect.

In addition: the name of the corresponding local PAM service must match that of the factor: the factor is coded to call out to the local PAM service which corresponds to its basename.

Finally, however: why call this factor ‘otp‘ rather than, say, the more mnemonic name ‘yubikey‘? After all, both of the above-mentioned pieces of configuration could be fixed up accordingly. Well, as well as ‘leaking’ less internal configuration information, it turns out that the factor ‘otp‘ is already explicitly supported by the supporting HTML and Javascript distributed in the Cosign tarball. So ‘otp‘ is just better and easier all round.

Cosign ‘factors’ – continued …

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 3:06 pm
Tags: ,

Bearing in mind that ‘factor’ is an overloaded term within Cosign, the “Cosign Multi-Factor Specification, 20 March 2006, Draft 6” defines the necessary behaviour of a ‘factor’ as ‘external authenticator.’ Namely:

  1. External authenticator(s) are declared as follows in /etc/cosign.conf:
    factor <pathname> [-2] <form-field1> <formfield2> …
  2. Any such authenticator will be invoked if (and only if) all listed form-fields contain posted data.
  3. The value of each form-field is written to the authenticator on stdin, one per line, in the order in which they are listed in the configuration.
  4. If authentication is successful, the authenticator:
    • writes the factor name to stdout
    • exits with 0

    Otherwise, the authenticator:

    • writes an error message to stdout
    • exits with 1

The -2 option to the factor keyword means that this factor is only checked after another (non -2) factor has been satisfied. It’s intended for use with factors which are vulnerable to denial-of-service attacks due to repeated authentication failures.

Cosign ‘factors’

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 12:29 pm
Tags: ,

In Cosign, the word ‘factor’ fundamentally means an ‘authentication type.’ However, ‘factor’ is an overloaded term, which also refers to:

  • an arbitrary string which is returned by an external authenticator on success;
  • the external authenticator itself.

In addition, there are ‘Legacy factors’: e.g. if Kerberos is used to authenticate the account, the ‘factor’ is set to the Kerberos realm used.

(More information about all of this can be found in the “Cosign Multi-Factor Specification, 20 March 2006, Draft 6”.)

On the client Cosign website, authorization by factor is enforced by the Cosign filter directive CosignRequireFactor.

Authorization by factor can be arranged via ‘AND‘ and ‘OR‘ combinations: a CosignRequireFactor directive which includes multiple factors implies that those factors are AND‘ed together; multiple CosignRequireFactor directives are OR‘ed.

Edit: in fact, testing subsequent to this blog post shows it is not the case that “multiple CosignRequireFactor directives are OR‘ed”! It turns out that, in the case of multiple CosignRequireFactor directives, the most ‘recently defined’ CosignRequireFactor directive wins. See blog post Cosign ‘factors’ – a correction.

On Informatics sites, up until fairly recently CosignRequireFactor has typically been null – which means ‘accept any request which has been authenticated against any available factor.’

Nowadays, we generally declare

CosignRequireFactor INF.ED.AC.UK  

in order to allow Informatics users, but to exclude iFriend users.

Just to repeat: a null CosignRequireFactor means that authentication against any available factor is deemed sufficient. Be careful!

Cosign ‘multi-factor’ authentication

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 12:03 pm

I mentioned above that conventional Cosign authentication is based on Kerberos: i.e. usernames, and passwords.

However, it also turns out that, since v2, Cosign has had (some) support for multi-factor authentication. The relevant document to read is linked to from Cosign’s home page, and is “Cosign Multi-Factor Specification, 20 March 2006, Draft 6”.

That’s good news: it means that the necessary infrastructural support for ‘two-factor’ authentication is already present in Cosign.

Some background: what’s Cosign, and how does it work?

Filed under: Pilot service for Yubikey two-factor authentication — idurkacz @ 11:36 am

Cosign – see http://weblogin.org – is “an open source project originally designed to provide the University of Michigan with a secure single sign-on web authentication system.”

From the point of view of a user, a first visit to a Cosign-protected website results in redirection to an institutional authentication server which requests username and password via an HTTPS web form. Once authenticated, the user is then redirected back to the Cosign-protected website where – internal website authorization permitting – they can access content and resources, all mediated by the corresponding Cosign filter. Visits to further Cosign-protected websites then proceed transparently, using authentication cookies delivered via the initial visit to the institutional authentication server: that’s the ‘single sign-on’ in action.

In fact, the ‘single sign-on’ can work even better than that. Since the underlying authentication protocol is assumed to be Kerberos, a web browser which is capable of using SPNEGO (also known as ‘HTTP Negotiate Auth’ – see for example both RFC4559, and Microsoft’s HTTP-Based Cross-Platform Authentication by Using the Negotiate Protocol documentation) is able to use a user’s existing Kerberos tickets for the initial authentication sequence. The result in that case is that, provided the user has already authenticated via Kerberos, his/her subsequent access to institutional Cosign-protected websites is completely transparent.

Official Cosign documentation is unfortunately rather scattered. For a pictorial view of the authentication process, see the overview diagram at Cosign’s home website.

I might also mention that documentation pertaining to Informatics-specific local Cosign modifications is also rather scattered … but more on that later!

Next Page »

Theme: Rubric.