Installation and Configuration of Yubikey KSM

The Yubikey KSM module is responsible for storing AES keys and providing two interfaces:

  • Decrypting an OTP

  • Adding new AES keys

It is intentionally not possible to extract the AES keys or to make modifications to the database content, see Design Goals.

The installation procedure documented below applies to any Unix-like environment, although it was written for Debian GNU/Linux version 5.0 (aka "lenny").

Since version 1.1 of the YK-KSM, any database supported by the PHP PDO interface is supported by the YK-KSM. To give concrete examples, we will here explain how to set it up using MySQL or PostgreSQL. Note that you only need to install either MySQL or PostgreSQL (or any other supported database), not both!

Step 1: YK-KSM Installation

First you should download and install the latest YK-KSM release:

user@ksm:~$ sudo apt-get install wget make help2man
user@ksm:~$ wget
user@ksm:~$ wget
user@ksm:~$ gpg --verify yubikey-ksm-1.15.tgz.sig
user@ksm:~$ tar xfz yubikey-ksm-1.15.tgz
user@ksm:~$ cd yubikey-ksm-1.15
user@ksm:~/yubikey-ksm-1.15$ sudo make install

Alternatively, you may also check out YK-KSM from its source code repository. For example:

user@ksm:~$ sudo apt-get install git make help2man
user@ksm:~$ git clone git://
user@ksm:~$ cd yubikey-ksm
user@ksm:~/yubikey-ksm$ sudo make install

The rest of this documentation will assume you have installed the YK-KSM with make install.

Step 2: Install web server and PHP

You will need to install a web server with PHP5 and the PHP mcrypt interface:

user@ksm:~$ sudo apt-get install apache2 php5 php5-mcrypt

Any web server with PHP support should work.

Step 3A: MySQL Installation

Install the required packages:

user@ksm:~$ sudo apt-get install mysql-server php5-mysql libdbd-mysql-perl

The installation asks you for a MySQL "root" password, and I recommend to specify one.

To avoid having to specify a password when using the mysql tool interactively, you can store the password in ~/.my.cnf, see /usr/share/doc/mysql-server-5.0/README.Debian.gz. For example:

user@ksm:~$ cat > .my.cnf
user = root

First create the database and the tables as follows:

user@ksm:~$ echo 'create database ykksm' | mysql
user@ksm:~$ mysql ykksm < /usr/share/doc/yubikey-ksm/ykksm-db.sql

You should also create database users for the decrypt and import interfaces, normally called ykksmreader and ykksmimporter:

user@ksm:~$ mysql --silent ykksm
mysql> CREATE USER 'ykksmreader';
mysql> GRANT SELECT ON ykksm.yubikeys TO 'ykksmreader'@'localhost';
mysql> SET PASSWORD FOR 'ykksmreader'@'localhost' = PASSWORD('yourpassword');
mysql> CREATE USER 'ykksmimporter';
mysql> GRANT INSERT ON ykksm.yubikeys TO 'ykksmimporter'@'localhost';
mysql> SET PASSWORD FOR 'ykksmimporter'@'localhost' = PASSWORD('otherpassword');
mysql> \q

Step 3B: PostgreSQL Installation

Install some packages:

user@ksm:~$ sudo apt-get install postgresql php5-pgsql libdbd-pg-perl

The database needs to be initialized as follows:

user@ksm:~$ sudo su postgres
postgres@ksm:~$ createdb ykksm
postgres@ksm:~$ psql ykksm < /usr/share/doc/yubikey-ksm/ykksm-db.sql

You also need to create a user for the decrypt interface, normally called ykksmreader:

postgres@ksm:~$ psql ykksm -q
ykksm=# CREATE USER ykksmreader PASSWORD 'yourpassword';
ykksm=# GRANT SELECT ON yubikeys TO ykksmreader;
ykksm=# CREATE USER ykksmimporter PASSWORD 'otherpassword';
ykksm=# GRANT INSERT ON yubikeys TO ykksmimporter;
ykksm=# \q

During installation and debugging it may be useful to watch the database log entries:

user@ksm:~$ sudo tail -F /var/log/postgresql/postgresql-*-main.log &

Step 4: Include path configuration

Set the include path by creating a file /etc/php5/conf.d/ykksm.ini with the following content:

user@ksm:~$ sudo sh -c 'cat > /etc/php5/conf.d/ykksm.ini'
include_path = "/etc/yubico/ksm:/usr/share/yubikey-ksm"
user@ksm:~$ sudo /etc/init.d/apache2 restart

The paths are the default, if you installed the YK-KSM in some other place you need to modify the paths.

Step 5: Logging

The PHP interface uses syslog for logging of incoming requests. The facility is set in ykksm-config.php but defaults the LOG_LOCAL0. To place these messages in a separate file, you can add the following to /etc/syslog.conf, or if you use rsyslog, create a file /etc/rsyslog.d/ykksm.conf with this content:

user@ksm:~$ sudo sh -c 'cat > /etc/rsyslog.d/ykksm.conf'
local0.* -/var/log/ykksm.log
user@ksm:~$ sudo /etc/init.d/rsyslog restart

The - before the filename avoids syncing the file after each write, which is recommended for performance.

The log file can grow large quickly, so it is a good idea to setup rotation of log files. Here is an example that rotates the log file weekly. Create a file /etc/logrotate.d/ykksm like this:

user@ksm:~$ sudo sh -c 'cat > /etc/logrotate.d/ykksm'
/var/log/ykksm.log {
  rotate 9999
    invoke-rc.d rsyslog reload > /dev/null

Step 5.1: Fix default log (optional)

Unfortunately, most default syslog configuration, including the syslog.conf configuration file on Debian, will also log all entries to /var/log/syslog and/or /var/log/messages.

I am not aware of any way to avoid this without modifying these other rules. To avoid YK-KSM log entries in these other files, you must modify the default rules. For example, edit the following lines of /etc/rsyslog.conf (or /etc/syslog.conf if you don’t use rsyslog):

*.*;auth,authpriv.none          -/var/log/syslog
        mail,news.none          -/var/log/messages

Change them into:

*.*;auth,authpriv.none,local0.none              -/var/log/syslog
        mail,news.none          -/var/log/messages

Step 6: Decrypt OTP Interface

The interface to decrypt OTPs is implemented using a PHP script. You can place the script under any URL, but we recommend serving it as The simplest way is to use the symlink rule in our makefile:

user@ksm:~$ sudo make -f /usr/share/doc/yubikey-ksm/ symlink
install -d /var/www/wsapi
ln -sf /usr/share/yubikey-ksm/.htaccess /var/www/wsapi/.htaccess
ln -sf /usr/share/yubikey-ksm/ykksm-decrypt.php /var/www/wsapi/decrypt.php

You may also run the commands manually.

Step 7: YK-KSM Configuration

You need to edit the ykksm-config.php script. An example file is included in YK-KSM as ykksm-config.php. It is normally installed as /etc/yubico/ksm/ykksm-config.php:

user@ksm:~$ sudo cat /etc/yubico/ksm/ykksm-config.php
$db_dsn      = "mysql:dbname=ykksm;host=";
$db_username = "ykksmreader";
$db_password = "yourpassword";
$db_options  = array();
$logfacility = LOG_LOCAL0;

Be careful about the user permissions and ownership so that unrelated users on the system cannot read the database password.

Typically you only need to modify the database password, and possibly the database definition in $db_dsn. Example DSN for a MySQL setup:

$db_dsn      = "mysql:dbname=ykksm;host=";

An example DSN for a PostgreSQL setup:

$db_dsn      = "pgsql:dbname=ykksm;host=";

The End

You now have a YK-KSM up and running. You can test the service by requesting a URL. Using wget, for example:

user@ksm:~$ sudo apt-get install wget
user@ksm:~$ wget -q -O - 'http://localhost/wsapi/decrypt?otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh'
ERR Unknown yubikey

You will need to import keys into the database for the decrypt function to do anything useful. See Server Hardening on how to improve security of your system. Likely next steps are Generate KSM Key, Generate Keys and/or Import Keys To KSM.