1
0
mirror of https://github.com/Yubico/yubikey-val.git synced 2025-02-27 06:54:16 +01:00

fixup formatting

This commit is contained in:
Klas Lindfors 2014-08-14 13:25:48 +02:00
parent 95642d3458
commit 71506a79ba
12 changed files with 444 additions and 563 deletions

View File

@ -14,16 +14,16 @@ flag, which speeds up generation, but is less secure! The command is run
as root (using sudo), since it needs to be able to read the database as root (using sudo), since it needs to be able to read the database
configuration stored in /etc/yubico/val/config-db.php. configuration stored in /etc/yubico/val/config-db.php.
```sh ....
user@val:~$ sudo ykval-gen-clients --urandom 5 user@val:~$ sudo ykval-gen-clients --urandom 5
1,l+/c/XfDPDHsaNKrpjwL+bf/Hgs= 1,l+/c/XfDPDHsaNKrpjwL+bf/Hgs=
2,LPGHqukoIAUGgDuOs7O0e1f8xD0= 2,LPGHqukoIAUGgDuOs7O0e1f8xD0=
3,K+gWRE0euOjVOiLD4Nm0wyHrHY8= 3,K+gWRE0euOjVOiLD4Nm0wyHrHY8=
4,+8LF+ADANTAHnwB82xkBb+mNEFs= 4,+8LF+ADANTAHnwB82xkBb+mNEFs=
5,URc6oabcuRV8OWW1Hs1cYym3ba4= 5,URc6oabcuRV8OWW1Hs1cYym3ba4=
user@val:~$ user@val:~$
``` ....
== Testing the clients == == Testing the clients ==
The above clients can now be used with the validation server. If you have The above clients can now be used with the validation server. If you have
@ -31,29 +31,29 @@ a YubiKey validation client, you can easily test this now. For example,
using the ykclient command (available in the ykclient-dev package, which is using the ykclient command (available in the ykclient-dev package, which is
in Debian as well as Ubuntu): in Debian as well as Ubuntu):
```sh ....
user@val:~$ ykclient --url "http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s" --apikey LPGHqukoIAUGgDuOs7O0e1f8xD0= 2 cccccccccccdutfiljtbignbgckhgdtfigbdricugdrv user@val:~$ ykclient --url "http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s" --apikey LPGHqukoIAUGgDuOs7O0e1f8xD0= 2 cccccccccccdutfiljtbignbgckhgdtfigbdricugdrv
Input: Input:
validation URL: http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s validation URL: http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s
client id: 2 client id: 2
token: cccccccccccdutfiljtbignbgckhgdtfigbdricugdrv token: cccccccccccdutfiljtbignbgckhgdtfigbdricugdrv
api key: LPGHqukoIAUGgDuOs7O0e1f8xD0= api key: LPGHqukoIAUGgDuOs7O0e1f8xD0=
Verification output (1): Yubikey OTP was bad (BAD_OTP) Verification output (1): Yubikey OTP was bad (BAD_OTP)
user@val:~$ user@val:~$
``` ....
Note that even though the response was BAD_OTP (since the key used is in fact Note that even though the response was BAD_OTP (since the key used is in fact
a bad OTP), the verification worked as expected. Compare it to the next example: a bad OTP), the verification worked as expected. Compare it to the next example:
```sh ....
user@val:~$ ykclient --url "http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s" --apikey not_a_real_secret 3 cccccccccccdutfiljtbignggckhgdtfigbdricugdrvInput: user@val:~$ ykclient --url "http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s" --apikey not_a_real_secret 3 cccccccccccdutfiljtbignggckhgdtfigbdricugdrvInput:
validation URL: http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s validation URL: http://127.0.0.1/wsapi/2.0/verify?id=%d&otp=%s
client id: 3 client id: 3
token: cccccccccccdutfiljtbignggckhgdtfigbdricugdrv token: cccccccccccdutfiljtbignggckhgdtfigbdricugdrv
api key: not_a_real_secret api key: not_a_real_secret
Verification output (106): Server response signature was invalid (BAD_SERVER_SIGNATURE) Verification output (106): Server response signature was invalid (BAD_SERVER_SIGNATURE)
user@val:~$ user@val:~$
``` ....
In the above example, the server actually noticed that the client secret was In the above example, the server actually noticed that the client secret was
incorrect, and responded as it should. The response is signed with the correct incorrect, and responded as it should. The response is signed with the correct

View File

@ -1,7 +1,7 @@
Getting Started Writing Clients Getting Started Writing Clients
=============================== ===============================
## Introduction == Introduction
While the canonical description of the validation protocol is While the canonical description of the validation protocol is
documented in link:ValidationProtocolV20[ValidationProtocolV20], it may be difficult to grasp the documented in link:ValidationProtocolV20[ValidationProtocolV20], it may be difficult to grasp the
@ -12,7 +12,7 @@ the replicated protocol.
If you want to make your own client implementation, here is the If you want to make your own client implementation, here is the
quickest way to get started: quickest way to get started:
## API key == API key
API key is used to optionally sign the OTP validation request and to API key is used to optionally sign the OTP validation request and to
verify the OTP validation response. We recommend all production verify the OTP validation response. We recommend all production
@ -29,17 +29,15 @@ To get an API key, first use our online API key generator. It will
assign you an ID and create a shared key. You can use the shared key assign you an ID and create a shared key. You can use the shared key
to authenticate that the API responses do come from Yubico. to authenticate that the API responses do come from Yubico.
## Capture an OTP == Capture an OTP
Capture an OTP output from your YubiKey. You can do that by opening Capture an OTP output from your YubiKey. You can do that by opening
a text editor and simply pressing the button on the YubiKey. The OTP is a a text editor and simply pressing the button on the YubiKey. The OTP is a
simple string of characters, like this: simple string of characters, like this:
``` vvvvvvcurikvhjcvnlnbecbkubjvuittbifhndhn
vvvvvvcurikvhjcvnlnbecbkubjvuittbifhndhn
```
## Validate OTP format == Validate OTP format
Prudent clients should validate the data entered by the user so that Prudent clients should validate the data entered by the user so that
it is what the software expects. YubiKey OTPs consists of 32-48 it is what the software expects. YubiKey OTPs consists of 32-48
@ -51,7 +49,7 @@ other Dvorak layouts as well. For this reason, our recommendation is
that clients only check that the input consists of 32-48 printable that clients only check that the input consists of 32-48 printable
characters. characters.
## Send OTP to our server == Send OTP to our server
Send the authentication request to our servers following the protocol Send the authentication request to our servers following the protocol
specified below. Your request should include the verifier ID (a number specified below. Your request should include the verifier ID (a number
@ -61,48 +59,42 @@ make the request unique. The request is part of the HTTP GET URL,
encoded using normal parameter/value pairs. For example (broken into encoded using normal parameter/value pairs. For example (broken into
two lines for legibility): two lines for legibility):
``` http://api2.yubico.com/wsapi/2.0/verify?id=1&otp=cccccccbcjdifc\
http://api2.yubico.com/wsapi/2.0/verify?id=1&otp=cccccccbcjdifc\ trndncchkftchjlnbhvhtugdljibej&nonce=aef3a7835277a28da831005c2ae3b919e2076a62
trndncchkftchjlnbhvhtugdljibej&nonce=aef3a7835277a28da831005c2ae3b919e2076a62
```
The servers that we provide are: The servers that Yubico provides are:
``` api.yubico.com
api.yubico.com api2.yubico.com
api2.yubico.com api3.yubico.com
api3.yubico.com api4.yubico.com
api4.yubico.com api5.yubico.com
api5.yubico.com
```
These servers are hosted in different places and by different organizations. These servers are hosted in different places and by different organizations.
## Parse response == Parse response
You will recieve a response back from the server, a string of text You will recieve a response back from the server, a string of text
that resembles the following: that resembles the following:
``` h=vjhFxZrNHB5CjI6vhuSeF2n46a8=
h=vjhFxZrNHB5CjI6vhuSeF2n46a8= t=2010-04-23T20:34:51Z0678
t=2010-04-23T20:34:51Z0678 otp=cccccccbcjdifctrndncchkftchjlnbhvhtugdljibej
otp=cccccccbcjdifctrndncchkftchjlnbhvhtugdljibej nonce=aef3a7835277a28da831005c2ae3b919e2076a62
nonce=aef3a7835277a28da831005c2ae3b919e2076a62 sl=75
sl=75 status=OK
status=OK
```
You can check the authenticity of this response by checking that the You can check the authenticity of this response by checking that the
OTP and nonce was the same as the one you requested validation for and OTP and nonce was the same as the one you requested validation for and
verify the HMAC-SHA-1 signature. verify the HMAC-SHA-1 signature.
## Make a decision == Make a decision
Use the `status=` codes to make a decision whether to authenticate Use the `status=` codes to make a decision whether to authenticate
your user or not. All the status codes and their meanings are your user or not. All the status codes and their meanings are
described by the protocol specification, see below. described by the protocol specification, see below.
## Binding an OTP to an Identity == Binding an OTP to an Identity
Since a valid OTP on its own is not terribly useful, you need to Since a valid OTP on its own is not terribly useful, you need to
connect it to a user in some way. This is normally not something the connect it to a user in some way. This is normally not something the
@ -129,7 +121,7 @@ different identities with the only differ being case of the prefix.
Typically you would store the association between the user and the Typically you would store the association between the user and the
YubiKey prefix in a database. YubiKey prefix in a database.
## The End == The End
There are some more subtle matters that can be important, so please There are some more subtle matters that can be important, so please
read the entire protocol specification for all the details. Further, read the entire protocol specification for all the details. Further,

View File

@ -15,35 +15,35 @@ the *clients* table of the database.
The infomation here covers exporting existing clients to a file, and importing The infomation here covers exporting existing clients to a file, and importing
the clients from that file into another database. For generating clients, see the clients from that file into another database. For generating clients, see
[[GeneratingClients|Generating Clients]]. link:GeneratingClients.html[GeneratingClients]
To export client data, you can use the following command (Replace C5B8D4EA with To export client data, you can use the following command (Replace C5B8D4EA with
the key of the recipient of the data): the key of the recipient of the data):
```sh ....
user@val:~$ sudo ykval-export-clients | gpg -a --encrypt -r C5B8D4EA -s > yk-client-info.asc user@val:~$ sudo ykval-export-clients | gpg -a --encrypt -r C5B8D4EA -s > yk-client-info.asc
You need a passphrase to unlock the secret key for You need a passphrase to unlock the secret key for
user: "YK-KSM import key" user: "YK-KSM import key"
2048-bit RSA key, ID C5B8D4EA, created 2013-01-28 2048-bit RSA key, ID C5B8D4EA, created 2013-01-28
user@val:~$ user@val:~$
``` ....
To import the client data exported above, you can use: To import the client data exported above, you can use:
```sh ....
user@val:~$ gpg < yk-client-info.asc | sudo ykval-import-clients user@val:~$ gpg < yk-client-info.asc | sudo ykval-import-clients
You need a passphrase to unlock the secret key for You need a passphrase to unlock the secret key for
user: "YK-KSM import key" user: "YK-KSM import key"
2048-bit RSA key, ID 9372DC00, created 2013-01-28 (main key ID C5B8D4EA) 2048-bit RSA key, ID 9372DC00, created 2013-01-28 (main key ID C5B8D4EA)
gpg: encrypted with 2048-bit RSA key, ID 9372DC00, created 2013-01-28 gpg: encrypted with 2048-bit RSA key, ID 9372DC00, created 2013-01-28
"YK-KSM import key" "YK-KSM import key"
gpg: Signature made Tue 29 Jan 2013 04:18:21 PM CET using RSA key ID C5B8D4EA gpg: Signature made Tue 29 Jan 2013 04:18:21 PM CET using RSA key ID C5B8D4EA
gpg: Good signature from "YK-KSM import key" gpg: Good signature from "YK-KSM import key"
Successfully imported clients to database Successfully imported clients to database
user@val:~$ user@val:~$
``` ....
== Yubikey Counter Data == == Yubikey Counter Data ==
@ -54,27 +54,28 @@ Yubikeys, such as their various counter values. This data is stored in the
To export Yubikey counter data, you can use the following command (Replace To export Yubikey counter data, you can use the following command (Replace
C5B8D4EA with the key of the recipient of the data): C5B8D4EA with the key of the recipient of the data):
```sh ....
user@val:~$ sudo ykval-export | gpg -a --encrypt -r C5B8D4EA -s > yk-counter-data.asc user@val:~$ sudo ykval-export | gpg -a --encrypt -r C5B8D4EA -s > yk-counter-data.asc
You need a passphrase to unlock the secret key for You need a passphrase to unlock the secret key for
user: "YK-KSM import key" user: "YK-KSM import key"
2048-bit RSA key, ID C5B8D4EA, created 2013-01-28 2048-bit RSA key, ID C5B8D4EA, created 2013-01-28
user@val:~$ user@val:~$
``` ....
To import the counter data exported above, you can use: To import the counter data exported above, you can use:
```sh ....
user@val:~$ gpg < yk-counter-data.asc | sudo ykval-import user@val:~$ gpg < yk-counter-data.asc | sudo ykval-import
You need a passphrase to unlock the secret key for You need a passphrase to unlock the secret key for
user: "YK-KSM import key" user: "YK-KSM import key"
2048-bit RSA key, ID 9372DC00, created 2013-01-28 (main key ID C5B8D4EA) 2048-bit RSA key, ID 9372DC00, created 2013-01-28 (main key ID C5B8D4EA)
gpg: encrypted with 2048-bit RSA key, ID 9372DC00, created 2013-01-28
"YK-KSM import key"
gpg: Signature made Tue 29 Jan 2013 04:18:21 PM CET using RSA key ID C5B8D4EA
gpg: Good signature from "YK-KSM import key"
Successfully imported yubikeys to database
user@val:~$
....
gpg: encrypted with 2048-bit RSA key, ID 9372DC00, created 2013-01-28
"YK-KSM import key"
gpg: Signature made Tue 29 Jan 2013 04:18:21 PM CET using RSA key ID C5B8D4EA
gpg: Good signature from "YK-KSM import key"
Successfully imported yubikeys to database
user@val:~$
```

View File

@ -15,11 +15,11 @@ remote YK-KSM and get the URL to it, or install your own YK-KSM.
Currently there are two recommended implementations of a YK-KSM. If you have a YubiHSM hardware dongle and want improve security, we recommend using Python-PyHSM: Currently there are two recommended implementations of a YK-KSM. If you have a YubiHSM hardware dongle and want improve security, we recommend using Python-PyHSM:
[https://github.com/Yubico/python-pyhsm] https://github.com/Yubico/python-pyhsm
Otherwise we recommend the "soft" YK-KSM: Otherwise we recommend the "soft" YK-KSM:
[https://github.com/Yubico/yubikey-ksm/] https://github.com/Yubico/yubikey-ksm/
The YK-KSM can be on the same machine as the validation server, but The YK-KSM can be on the same machine as the validation server, but
for improved security we recommend to use different machines for the for improved security we recommend to use different machines for the
@ -29,7 +29,7 @@ The OTP validation service is delivered through web service API.
There's no web-based HTML form interface involved. The protocol is There's no web-based HTML form interface involved. The protocol is
defined at: defined at:
[http://www.yubico.com/developers/api/] http://www.yubico.com/developers/api/
For redundancy it is possible to set up multiple instances of the For redundancy it is possible to set up multiple instances of the
YubiKey Validation Server. The intent is that clients should be able YubiKey Validation Server. The intent is that clients should be able
@ -57,14 +57,14 @@ upgrades if prompted.
First you should download and install the latest YK-VAL release: First you should download and install the latest YK-VAL release:
```sh ....
user@val:~$ sudo apt-get install git make user@val:~$ sudo apt-get install git make
... ...
user@val:~$ git clone git://github.com/Yubico/yubikey-val.git user@val:~$ git clone git://github.com/Yubico/yubikey-val.git
... ...
user@val:~$ cd yubikey-val user@val:~$ cd yubikey-val
user@val:~/yubikey-val$ sudo make install user@val:~/yubikey-val$ sudo make install
``` ....
The rest of this documentation will assume you have YK-VAL available The rest of this documentation will assume you have YK-VAL available
in the default installation targets. You can override the paths, see in the default installation targets. You can override the paths, see
@ -74,9 +74,7 @@ the Makefile.
You also need to install a web server with PHP5, php5-curl and php-pear. You also need to install a web server with PHP5, php5-curl and php-pear.
```sh user@val:~$ sudo apt-get install apache2 php5 php5-curl php-pear
user@val:~$ sudo apt-get install apache2 php5 php5-curl php-pear
```
Any web server with PHP support should work. Any web server with PHP support should work.
@ -90,94 +88,76 @@ PostgreSQL or MySQL here.
Install the required packages: Install the required packages:
```sh user@val:~$ sudo apt-get install mysql-server php5-mysql
user@val:~$ sudo apt-get install mysql-server php5-mysql
```
The installation asks you for a MySQL "root" password, and I recommend 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 to specify one. To avoid having to specify a password when using the
'mysql' tool interactively, you can store the password in ~/.my.cnf, 'mysql' tool interactively, you can store the password in ~/.my.cnf,
see /usr/share/doc/mysql-server-5.0/README.Debian.gz. For example: see /usr/share/doc/mysql-server-5.0/README.Debian.gz. For example:
```sh user@val:~$ cat > .my.cnf
user@val:~$ cat > .my.cnf [client]
[client] user = root
user = root password = YOURPASSWORD
password = YOURPASSWORD user@val:~$ chmod go-r .my.cnf
user@val:~$ chmod go-r .my.cnf user@val:~$
user@val:~$
```
Note the 'chmod' to protect your password from non-root users. Note the 'chmod' to protect your password from non-root users.
The database needs to be initialized as follows: The database needs to be initialized as follows:
```sh user@val:~$ echo 'create database ykval' | mysql
user@val:~$ echo 'create database ykval' | mysql user@val:~$ mysql ykval < /usr/share/doc/yubikey-val/ykval-db.sql
user@val:~$ mysql ykval < /usr/share/doc/yubikey-val/ykval-db.sql user@val:~$
user@val:~$
```
You also need to create a database user for the verifier interface, You also need to create a database user for the verifier interface,
normally called 'ykval_verifier': normally called 'ykval_verifier':
```sh user@val:~$ mysql --silent ykval
user@val:~$ mysql --silent ykval mysql> CREATE USER 'ykval_verifier'@'localhost'; \
mysql> CREATE USER 'ykval_verifier'@'localhost'; \ GRANT SELECT,INSERT,UPDATE(modified, yk_counter, yk_low, yk_high, yk_use, nonce) ON ykval.yubikeys TO 'ykval_verifier'@'localhost'; \
GRANT SELECT,INSERT,UPDATE(modified, yk_counter, yk_low, yk_high, yk_use, nonce) ON ykval.yubikeys TO 'ykval_verifier'@'localhost'; \ GRANT SELECT(id, secret, active) ON ykval.clients TO 'ykval_verifier'@'localhost'; \
GRANT SELECT(id, secret, active) ON ykval.clients TO 'ykval_verifier'@'localhost'; \ GRANT SELECT,INSERT,UPDATE,DELETE ON ykval.queue TO 'ykval_verifier'@'localhost'; \
GRANT SELECT,INSERT,UPDATE,DELETE ON ykval.queue TO 'ykval_verifier'@'localhost'; \ SET PASSWORD FOR 'ykval_verifier'@'localhost' = PASSWORD('yourpassword'); \
SET PASSWORD FOR 'ykval_verifier'@'localhost' = PASSWORD('yourpassword'); \ FLUSH PRIVILEGES;
FLUSH PRIVILEGES; mysql> \q
mysql> \q user@val:~$
user@val:~$
```
==== Step 3B: PostgreSQL Installation ==== ==== Step 3B: PostgreSQL Installation ====
Install the required packages: Install the required packages:
```sh user@val:~$ sudo apt-get install postgresql php5-pgsql
user@val:~$ sudo apt-get install postgresql php5-pgsql ...
... user@val:~$
user@val:~$
```
The database needs to be initialized as follows: The database needs to be initialized as follows:
```sh user@val:~$ sudo su postgres
user@val:~$ sudo su postgres postgres@val:~$ createdb ykval
postgres@val:~$ createdb ykval postgres@val:~$ psql ykval < /usr/share/doc/yubikey-val/ykval-db.sql
postgres@val:~$ psql ykval < /usr/share/doc/yubikey-val/ykval-db.sql postgres@val:~$
postgres@val:~$
```
You also need to create a database user for the verifier interface, You also need to create a database user for the verifier interface,
normally called 'ykval_verifier': normally called 'ykval_verifier':
```sh postgres@val:~$ psql ykval -q
postgres@val:~$ psql ykval -q ykval=# CREATE USER ykval_verifier PASSWORD 'yourpassword';
ykval=# CREATE USER ykval_verifier PASSWORD 'yourpassword'; ykval=# GRANT SELECT,INSERT,UPDATE ON yubikeys TO ykval_verifier;
ykval=# GRANT SELECT,INSERT,UPDATE ON yubikeys TO ykval_verifier; ykval=# GRANT SELECT ON clients TO ykval_verifier;
ykval=# GRANT SELECT ON clients TO ykval_verifier; ykval=# GRANT SELECT, INSERT, UPDATE, DELETE ON queue TO ykval_verifier;
ykval=# GRANT SELECT, INSERT, UPDATE, DELETE ON queue TO ykval_verifier; ykval=# \q
ykval=# \q postgres@val:~$
postgres@val:~$
```
Don't forget to switch back to your normal user Don't forget to switch back to your normal user
```sh
postgres@val:~$ exit postgres@val:~$ exit
user@val:~$ user@val:~$
```
During installation and debugging it may be useful to watch the During installation and debugging it may be useful to watch the
database log entries: database log entries:
```sh user@val:~$ sudo tail -F /var/log/postgresql/postgresql-*-main.log &
user@val:~$ sudo tail -F /var/log/postgresql/postgresql-*-main.log &
```
=== Step 4: Setup Verify OTP Interface === === Step 4: Setup Verify OTP Interface ===
@ -187,13 +167,11 @@ can place the script under any URL, but we recommend serving it as
the symlinks is to invoke 'make symlink' in your YK-VAL source tree. the symlinks is to invoke 'make symlink' in your YK-VAL source tree.
Like this: Like this:
```sh user@val:~/yubikey-val$ sudo make symlink
user@val:~/yubikey-val$ sudo make symlink install -d /var/www/wsapi/2.0
install -d /var/www/wsapi/2.0 ln -sf /usr/share/yubikey-val/ykval-verify.php /var/www/wsapi/2.0/verify.php
ln -sf /usr/share/yubikey-val/ykval-verify.php /var/www/wsapi/2.0/verify.php ln -sf /usr/share/yubikey-val/ykval-sync.php /var/www/wsapi/2.0/sync.php
ln -sf /usr/share/yubikey-val/ykval-sync.php /var/www/wsapi/2.0/sync.php user@val:~/yubikey-val$
user@val:~/yubikey-val$
```
If you want to do it manually, you can invoke the above commands If you want to do it manually, you can invoke the above commands
manually. manually.
@ -203,25 +181,21 @@ manually.
Set the include path for the queue daemon by creating a file Set the include path for the queue daemon by creating a file
/etc/default/ykval-queue with the following content: /etc/default/ykval-queue with the following content:
```sh user@val:~$ sudo sh -c 'cat > /etc/default/ykval-queue'
user@val:~$ sudo sh -c 'cat > /etc/default/ykval-queue' DAEMON_ARGS="/etc/yubico/val:/usr/share/yubikey-val"
DAEMON_ARGS="/etc/yubico/val:/usr/share/yubikey-val" user@val:~$
user@val:~$
```
You also need to set the include path for the PHP scripts running via You also need to set the include path for the PHP scripts running via
Apache, using a .htaccess file: Apache, using a .htaccess file:
```sh user@val:~$ sudo sh -c 'cat > /var/www/wsapi/2.0/.htaccess'
user@val:~$ sudo sh -c 'cat > /var/www/wsapi/2.0/.htaccess' RewriteEngine on
RewriteEngine on RewriteRule ^([^/\.\?]+)(\?.*)?$ $1.php$2 [L]
RewriteRule ^([^/\.\?]+)(\?.*)?$ $1.php$2 [L] <IfModule mod_php5.c>
<IfModule mod_php5.c> php_value include_path ".:/etc/yubico/val:/usr/share/yubikey-val"
php_value include_path ".:/etc/yubico/val:/usr/share/yubikey-val" </IfModule>
</IfModule> user@val:~$ sudo ln -s 2.0/.htaccess /var/www/wsapi/.htaccess
user@val:~$ sudo ln -s 2.0/.htaccess /var/www/wsapi/.htaccess user@val:~$
user@val:~$
```
The .htaccess file also sets up rewriting from the non-.PHP suffix URL The .htaccess file also sets up rewriting from the non-.PHP suffix URL
name to the right script. name to the right script.
@ -236,10 +210,8 @@ included in YK-VAL package as ykval-config.php
A template is typically installed in /etc/yubico/val/ykval-config.php-template. A template is typically installed in /etc/yubico/val/ykval-config.php-template.
```sh user@val:~$ sudo cp /etc/yubico/val/ykval-config.php-template /etc/yubico/val/ykval-config.php
user@val:~$ sudo cp /etc/yubico/val/ykval-config.php-template /etc/yubico/val/ykval-config.php user@val:~$ sudo emacs -nw /etc/yubico/val/ykval-config.php
user@val:~$ sudo emacs -nw /etc/yubico/val/ykval-config.php
```
Be careful about the user permissions and ownership so that unrelated Be careful about the user permissions and ownership so that unrelated
users on the system cannot read the database password. users on the system cannot read the database password.
@ -251,43 +223,35 @@ otp2ksmurls function.
An example DSN for a MySQL setup: An example DSN for a MySQL setup:
```php $baseParams['__YKVAL_DB_DSN__'] = "mysql:dbname=ykval;host=127.0.0.1";
$baseParams['__YKVAL_DB_DSN__'] = "mysql:dbname=ykval;host=127.0.0.1";
```
An example DSN for a PostgreSQL setup: An example DSN for a PostgreSQL setup:
```php $baseParams['__YKVAL_DB_DSN__'] = "pgsql:dbname=ykval;host=127.0.0.1";
$baseParams['__YKVAL_DB_DSN__'] = "pgsql:dbname=ykval;host=127.0.0.1";
```
We recommend to add the hosts in YKVAL_SYNC_POOL as entries in '/etc/hosts' to avoid network delays caused by DNS-lookups. For example: We recommend to add the hosts in YKVAL_SYNC_POOL as entries in '/etc/hosts' to avoid network delays caused by DNS-lookups. For example:
```sh user@val:~$ sudo sh -c 'cat >> /etc/hosts'
user@val:~$ sudo sh -c 'cat >> /etc/hosts' 1.2.3.4 api1.example.com
1.2.3.4 api1.example.com 2.3.4.5 api2.example.com
2.3.4.5 api2.example.com user@val:~$
user@val:~$
```
To improve database performance you can use persistent database connection so that each request doesn't require a new connection to be setup. To enable this modify '__YKVAL_DB_OPTIONS__' as follows: To improve database performance you can use persistent database connection so that each request doesn't require a new connection to be setup. To enable this modify '__YKVAL_DB_OPTIONS__' as follows:
```php $baseParams['__YKVAL_DB_OPTIONS__'] = array(PDO::ATTR_PERSISTENT => true);
$baseParams['__YKVAL_DB_OPTIONS__'] = array(PDO::ATTR_PERSISTENT => true);
```
=== Step 7: Apache configuration === === Step 7: Apache configuration ===
Create an apache web configuration file for the normal HTTP interface Create an apache web configuration file for the normal HTTP interface
like this: like this:
``` ....
user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval' user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval'
<VirtualHost *:80> <VirtualHost *:80>
ServerName api.example.com ServerName api.example.com
ServerAdmin support@example.com ServerAdmin support@example.com
DocumentRoot /var/www/ DocumentRoot /var/www/
<Directory /> <Directory />
Options FollowSymLinks Options FollowSymLinks
@ -306,9 +270,9 @@ user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval'
CustomLog /var/log/apache2/ykval-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" CustomLog /var/log/apache2/ykval-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\""
ServerSignature On ServerSignature On
</VirtualHost> </VirtualHost>
user@val:~$ user@val:~$
``` ....
HTTPS is strictly speaking not required, but we strongly recommend it. HTTPS is strictly speaking not required, but we strongly recommend it.
@ -319,19 +283,17 @@ both, but you will need to decide which one to use.
You will need to create a key/certificate for your server using normal You will need to create a key/certificate for your server using normal
tools like GnuTLS "certtool". A small howto for !GoDaddy is available tools like GnuTLS "certtool". A small howto for !GoDaddy is available
from from
[http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/4062]. http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/4062.
==== Step 7A: HTTPS via mod_gnutls ==== ==== Step 7A: HTTPS via mod_gnutls ====
First install and enable the mod_gnutls module: First install and enable the mod_gnutls module:
```sh user@val:~$ sudo apt-get install libapache2-mod-gnutls
user@val:~$ sudo apt-get install libapache2-mod-gnutls user@val:~$ sudo a2enmod gnutls
user@val:~$ sudo a2enmod gnutls Enabling module gnutls.
Enabling module gnutls. Run '/etc/init.d/apache2 restart' to activate new configuration!
Run '/etc/init.d/apache2 restart' to activate new configuration! user@val:~$
user@val:~$
```
You will need to place the private key in You will need to place the private key in
/etc/ssl/private/api.example.com-key.pem and the certificate chain in /etc/ssl/private/api.example.com-key.pem and the certificate chain in
@ -339,10 +301,10 @@ You will need to place the private key in
Create Apache web configuration files: Create Apache web configuration files:
``` ....
user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl' user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl'
Listen 443 Listen 443
<VirtualHost *:443> <VirtualHost *:443>
ServerName api.example.com ServerName api.example.com
ServerAdmin support@example.com ServerAdmin support@example.com
@ -369,29 +331,27 @@ Listen 443
CustomLog /var/log/apache2/ykval-ssl-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" CustomLog /var/log/apache2/ykval-ssl-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\""
ServerSignature On ServerSignature On
</VirtualHost> </VirtualHost>
user@val:~$ user@val:~$
``` ....
==== Step 7B: HTTPS via mod_ssl ==== ==== Step 7B: HTTPS via mod_ssl ====
The mod_ssl module is typically installed by default, but you need to The mod_ssl module is typically installed by default, but you need to
enable it. enable it.
```sh user@val:~$ sudo a2enmod ssl
user@val:~$ sudo a2enmod ssl Enabling module ssl.
Enabling module ssl. Run '/etc/init.d/apache2 restart' to activate new configuration!
Run '/etc/init.d/apache2 restart' to activate new configuration! user@val:~$
user@val:~$
```
You will need to place the private key in You will need to place the private key in
/etc/ssl/private/api.example.com-key.pem and the certificate chain in /etc/ssl/private/api.example.com-key.pem and the certificate chain in
/etc/ssl/private/api.example.com-chain.pem. /etc/ssl/private/api.example.com-chain.pem.
``` ....
user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl' user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl'
<VirtualHost *:443> <VirtualHost *:443>
ServerName api.example.com ServerName api.example.com
ServerAdmin support@example.com ServerAdmin support@example.com
@ -418,28 +378,26 @@ user@val:~$ sudo sh -c 'cat > /etc/apache2/sites-available/ykval-ssl'
CustomLog /var/log/apache2/ykval-ssl-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" CustomLog /var/log/apache2/ykval-ssl-access.log "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\""
ServerSignature On ServerSignature On
</VirtualHost> </VirtualHost>
user@val:~$ user@val:~$
``` ....
==== Common Apache Configuration ==== ==== Common Apache Configuration ====
This step is the same for both mod_gnutls and mod_ssl. This step is the same for both mod_gnutls and mod_ssl.
```sh user@val:~$ sudo a2enmod rewrite
user@val:~$ sudo a2enmod rewrite Enabling module rewrite.
Enabling module rewrite. Run '/etc/init.d/apache2 restart' to activate new configuration!
Run '/etc/init.d/apache2 restart' to activate new configuration! user@val:~$ sudo a2dissite default
user@val:~$ sudo a2dissite default Site default disabled.
Site default disabled. Run '/etc/init.d/apache2 reload' to activate new configuration!
Run '/etc/init.d/apache2 reload' to activate new configuration! user@val:~$ sudo a2ensite ykval ykval-ssl
user@val:~$ sudo a2ensite ykval ykval-ssl Enabling site ykval.
Enabling site ykval. Enabling site ykval-ssl.
Enabling site ykval-ssl. Run '/etc/init.d/apache2 reload' to activate new configuration!
Run '/etc/init.d/apache2 reload' to activate new configuration! user@val:~$ sudo /etc/init.d/apache2 restart
user@val:~$ sudo /etc/init.d/apache2 restart user@val:~$
user@val:~$
```
=== Step 8: Logging === === Step 8: Logging ===
@ -448,13 +406,11 @@ facility is LOG_LOCAL0. To place these messages in a separate file,
you can add the following to /etc/syslog.conf, or if you use rsyslog, you can add the following to /etc/syslog.conf, or if you use rsyslog,
create a file /etc/rsyslog.d/ykval.conf with this content: create a file /etc/rsyslog.d/ykval.conf with this content:
```sh user@val:~$ sudo sh -c 'cat > /etc/rsyslog.d/ykval.conf'
user@val:~$ sudo sh -c 'cat > /etc/rsyslog.d/ykval.conf' local0.* -/var/log/ykval.log
local0.* -/var/log/ykval.log user@val:~$ sudo /etc/init.d/rsyslog restart
user@val:~$ sudo /etc/init.d/rsyslog restart ...
... user@val:~$
user@val:~$
```
The '-' before the filename avoids syncing the file after each write, The '-' before the filename avoids syncing the file after each write,
which is recommended for performance. which is recommended for performance.
@ -463,10 +419,9 @@ 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 rotation of log files. Here is an example that rotates the log file
weekly. Create a file /etc/logrotate.d/ykval like this: weekly. Create a file /etc/logrotate.d/ykval like this:
```sh user@val:~$ sudo sh -c 'cat > /etc/logrotate.d/ykval'
user@val:~$ sudo sh -c 'cat > /etc/logrotate.d/ykval' /var/log/ykval.log {
/var/log/ykval.log { weekly
weekly
dateext dateext
compress compress
missingok missingok
@ -475,9 +430,8 @@ user@val:~$ sudo sh -c 'cat > /etc/logrotate.d/ykval'
postrotate postrotate
invoke-rc.d rsyslog reload > /dev/null invoke-rc.d rsyslog reload > /dev/null
endscript endscript
} }
user@val:~$ user@val:~$
```
You may want to modify the default /etc/logrotate.d/apache2, useful You may want to modify the default /etc/logrotate.d/apache2, useful
things to add are 'dateext' and 'compress' and change 'rotate' to things to add are 'dateext' and 'compress' and change 'rotate' to
@ -494,39 +448,37 @@ rules. To avoid YK-VAL log entries in these other files, you must
modify the default rules. For example, edit the following lines of modify the default rules. For example, edit the following lines of
/etc/rsyslog.conf (or /etc/syslog.conf if you don't use rsyslog): /etc/rsyslog.conf (or /etc/syslog.conf if you don't use rsyslog):
``` ....
*.=debug;\ *.=debug;\
auth,authpriv.none;\ auth,authpriv.none;\
news.none;mail.none -/var/log/debug news.none;mail.none -/var/log/debug
*.*;auth,authpriv.none -/var/log/syslog *.*;auth,authpriv.none -/var/log/syslog
*.=info;*.=notice;*.=warn;\ *.=info;*.=notice;*.=warn;\
auth,authpriv.none;\ auth,authpriv.none;\
cron,daemon.none;\ cron,daemon.none;\
mail,news.none -/var/log/messages mail,news.none -/var/log/messages
``` ....
Change them into: Change them into:
``` ....
*.=debug;\ *.=debug;\
auth,authpriv.none;\ auth,authpriv.none;\
news.none;mail.none;local0.none -/var/log/debug news.none;mail.none;local0.none -/var/log/debug
*.*;auth,authpriv.none,local0.none -/var/log/syslog *.*;auth,authpriv.none,local0.none -/var/log/syslog
*.=info;*.=notice;*.=warn;\ *.=info;*.=notice;*.=warn;\
auth,authpriv.none;\ auth,authpriv.none;\
cron,daemon.none;\ cron,daemon.none;\
local0.none;\ local0.none;\
mail,news.none -/var/log/messages mail,news.none -/var/log/messages
``` ....
Idempotent commands to speed this up: Idempotent commands to speed this up:
```sh user@host:~$ sudo perl -pi -e 's/;auth,authpriv.none/;auth,local0.none,authpriv.none/' /etc/rsyslog.conf
user@host:~$ sudo perl -pi -e 's/;auth,authpriv.none/;auth,local0.none,authpriv.none/' /etc/rsyslog.conf user@host:~$ sudo perl -pi -e 's/news.none;mail.none/news.none;local0.none;mail.none/' /etc/rsyslog.conf
user@host:~$ sudo perl -pi -e 's/news.none;mail.none/news.none;local0.none;mail.none/' /etc/rsyslog.conf user@host:~$ sudo perl -pi -e 's/cron,daemon.none/cron,daemon.none;local0.none/' /etc/rsyslog.conf
user@host:~$ sudo perl -pi -e 's/cron,daemon.none/cron,daemon.none;local0.none/' /etc/rsyslog.conf user@host:~$ sudo /etc/init.d/rsyslog restart
user@host:~$ sudo /etc/init.d/rsyslog restart
```
=== Step 9: Start Sync Daemon === === Step 9: Start Sync Daemon ===
@ -535,9 +487,7 @@ daemon running to ensure that data is synchronized between the servers in
the pool. The easiest way of running this is to simply invoke ykval-queue the pool. The easiest way of running this is to simply invoke ykval-queue
in a shell: in a shell:
```sh user@val:~$ sudo ykval-queue
user@val:~$ sudo ykval-queue
```
However, the recommended approach is to automate running this process in However, the recommended approach is to automate running this process in
the background, by use of an init script or similar. Instructions on doing the background, by use of an init script or similar. Instructions on doing
@ -556,25 +506,24 @@ address(es) to __YKVAL_ALLOWED_SYNC_POOL__.
Once these permissions have been configured, you can initiate the full sync Once these permissions have been configured, you can initiate the full sync
by running the following command from the new server: by running the following command from the new server:
```sh
user@val:~$ ykval-synchronize http://<IP or hostname of existing server>/wsapi/2.0/resync all user@val:~$ ykval-synchronize http://<IP or hostname of existing server>/wsapi/2.0/resync all
```
=== Step 11: Test it === === Step 11: Test it ===
You can test the service by requesting a URL. Using wget, for You can test the service by requesting a URL. Using wget, for
example: example:
```sh ....
user@val:~$ wget -q -O - 'http://localhost/wsapi/2.0/verify?id=1&nonce=asdmalksdmlkasmdlkasmdlakmsdaasklmdlak&otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh' user@val:~$ wget -q -O - 'http://localhost/wsapi/2.0/verify?id=1&nonce=asdmalksdmlkasmdlkasmdlakmsdaasklmdlak&otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh'
h=/QVWkl5VlcX+Or1A2b3vOeoLEwI= h=/QVWkl5VlcX+Or1A2b3vOeoLEwI=
t=2010-05-17T14:48:15Z0355 t=2010-05-17T14:48:15Z0355
otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh
nonce=asdmalksdmlkasmdlkasmdlakmsdaasklmdlak nonce=asdmalksdmlkasmdlkasmdlakmsdaasklmdlak
status=NO_SUCH_CLIENT status=NO_SUCH_CLIENT
user@val:~$ user@val:~$
``` ....
Naturally, you will need to import client keys into the database for Naturally, you will need to import client keys into the database for
the verify function to work properly. the verify function to work properly.
@ -582,5 +531,5 @@ the verify function to work properly.
=== The End === === The End ===
You now have a YK-VAL up and running. See You now have a YK-VAL up and running. See
[https://github.com/Yubico/yubikey-ksm/wiki/ServerHardening] on how to https://github.com/Yubico/yubikey-ksm/wiki/ServerHardening on how to
improve security of your system. improve security of your system.

View File

@ -1,12 +1,12 @@
Maintainer instructions for making releases Maintainer instructions for making releases
=========================================== ===========================================
## Introduction == Introduction
The point of this document is to describe all steps required to make a The point of this document is to describe all steps required to make a
proper release of the yubikey-personalization project. proper release of the yubikey-personalization project.
## Dependencies == Dependencies
Making a release requires the following packages: Making a release requires the following packages:
@ -16,7 +16,7 @@ which can be installed (under Ubuntu) by running:
sudo apt-get install make git gnupg git2cl sudo apt-get install make git gnupg git2cl
## Details == Details
* Make sure the doc/ sub-directory uses the latest revision. Confirm with: * Make sure the doc/ sub-directory uses the latest revision. Confirm with:
cd doc && git checkout master && git pull && git diff cd doc && git checkout master && git pull && git diff

View File

@ -23,41 +23,35 @@ before they can be used. First create a Munin configuration file to
make sure the plugins can access the YK-VAL ykval-config.php make sure the plugins can access the YK-VAL ykval-config.php
configuration file: configuration file:
```sh user@val:~$ sudo sh -c 'cat > /etc/munin/plugin-conf.d/ykval'
user@val:~$ sudo sh -c 'cat > /etc/munin/plugin-conf.d/ykval' [ykval_ksmlatency]
[ykval_ksmlatency] group www-data
group www-data [ykval_vallatency]
[ykval_vallatency] group www-data
group www-data [ykval_queuelength]
[ykval_queuelength] group www-data
group www-data user@val:~$
user@val:~$
```
Then check that they are working properly: Then check that they are working properly:
```sh user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength autoconf
user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength autoconf yes
yes user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength config
user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength config graph_title YK-VAL queue size
graph_title YK-VAL queue size graph_vlabel sync requests in queue
graph_vlabel sync requests in queue graph_category ykval
graph_category ykval queuelength.label sync requests
queuelength.label sync requests queuelength.draw AREA
queuelength.draw AREA user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength
user@val:~$ sudo /usr/sbin/munin-run --servicedir /usr/share/munin/plugins ykval_queuelength queuelength.value 0
queuelength.value 0 user@val:~$
user@val:~$
```
Enable the plugin as follows: Enable the plugin as follows:
```sh user@val:~$ sudo munin-node-configure --shell | sudo sh
user@val:~$ sudo munin-node-configure --shell | sudo sh user@val:~$ sudo /etc/init.d/munin-node restart
user@val:~$ sudo /etc/init.d/munin-node restart Stopping Munin-Node: done.
Stopping Munin-Node: done. Starting Munin-Node: done.
Starting Munin-Node: done. user@val:~$
user@val:~$
```
After some time, you should see new graphs on your Munin master. After some time, you should see new graphs on your Munin master.

View File

@ -1,4 +1,4 @@
= Introduction = == Introduction
The YK-VAL server has an optional interface that can be used to The YK-VAL server has an optional interface that can be used to
enable/disable validation of particular YubiKeys from a remote server. enable/disable validation of particular YubiKeys from a remote server.
@ -7,55 +7,45 @@ This document explains how to configure and set up that service.
Currently authorization is based on IP address of client, which may Currently authorization is based on IP address of client, which may
not be secure unless you take additional pre-cautions. not be secure unless you take additional pre-cautions.
= Installation = == Installation
```sh user@val:~/yubikey-val$ sudo make revoke
user@val:~/yubikey-val$ sudo make revoke user@val:~/yubikey-val$
user@val:~/yubikey-val$
```
= Configuration = == Configuration
Add the following to your /etc/yubico/val/ykval-config.php: Add the following to your /etc/yubico/val/ykval-config.php:
```php # For the revoke service.
# For the revoke service. $baseParams['__YKREV_IPS__'] = array('10.0.0.1', '2000:1:2:3::4');
$baseParams['__YKREV_IPS__'] = array('10.0.0.1', '2000:1:2:3::4');
```
Obviously you need to modify the IP address. Obviously you need to modify the IP address.
You also need to grant additional rights to the database, for MySQL: You also need to grant additional rights to the database, for MySQL:
``` user@val:~$ mysql --silent ykval
user@val:~$ mysql --silent ykval mysql> GRANT UPDATE(active) ON ykval.yubikeys to 'ykval_verifier'@'localhost'; \
mysql> GRANT UPDATE(active) ON ykval.yubikeys to 'ykval_verifier'@'localhost'; \ FLUSH PRIVILEGES;
FLUSH PRIVILEGES; mysql> \q
mysql> \q user@val:~$
user@val:~$
```
For PostgreSQL this should already be working, through this command: For PostgreSQL this should already be working, through this command:
``` postgres@val:~$ psql ykval -q
postgres@val:~$ psql ykval -q ykval=# GRANT UPDATE ON yubikeys TO ykval_verifier;
ykval=# GRANT UPDATE ON yubikeys TO ykval_verifier; ykval=# \q
ykval=# \q postgres@val:~$
postgres@val:~$
```
= Testing = == Testing
Test the installation like this: Test the installation like this:
```sh user@revoke:~$ wget -q -O - 'http://api.example.com/wsapi/revoke?yk=dteffujehknh&do=enable'
user@revoke:~$ wget -q -O - 'http://api.example.com/wsapi/revoke?yk=dteffujehknh&do=enable' OK Processed dteffujehknh with enable
OK Processed dteffujehknh with enable user@revoke:~$
user@revoke:~$
```
Use 'disable' instead of 'enable' to test disabling of the YubiKey. Use 'disable' instead of 'enable' to test disabling of the YubiKey.
= The End = == The End
You now have the YK-VAL Revocation Service up and running. You now have the YK-VAL Revocation Service up and running.

View File

@ -9,9 +9,7 @@ validation server can talk to any of the other validation server using
the Server Replication Protocol. The validation servers are the Server Replication Protocol. The validation servers are
authenticated by the use of certificates. authenticated by the use of certificates.
``` val A <-> val B <-> val C <-> val A
val A <-> val B <-> val C <-> val A
```
See the ValidationProtocolV20 for definition of the client to server See the ValidationProtocolV20 for definition of the client to server
protocol. The protocol described here is the server to server protocol. The protocol described here is the server to server
@ -22,31 +20,21 @@ implementation algorithm that uses this protocol.
A sync request is issued with a HTTP get call, like this: A sync request is issued with a HTTP get call, like this:
``` https://apiX.yubico.com/wsapi/sync?otp=xyz&modified=1264430686&nonce=foobar&yk_identity=foo&yk_counter=42&yk_use=17&yk_high=10&yk_low=5
https://apiX.yubico.com/wsapi/sync?otp=xyz&modified=1264430686&nonce=foobar&yk_identity=foo&yk_counter=42&yk_use=17&yk_high=10&yk_low=5
```
The following parameters are used The following parameters are used
[options="header"]
{| |=============================
! parameter !! type !! values | parameter |type |values
|- | otp | string | one-time password (for logging purposes)
| otp || string || one-time password (for logging purposes) | modified | integer | unix timestamp of when OTP was received
|- | nonce | string | nonce from client request
| modified || integer || unix timestamp of when OTP was received | yk_identity | modhex | YubiKey OTP identity in question
|- | yk_counter | integer | last seen session counter by sender
| nonce || string || nonce from client request | yk_use | integer | last seen session use by sender
|- | yk_high | integer | OTP internal high time value
| yk_identity || modhex || !YubiKey OTP identity in question | yk_low | integer | OTP internal low time value
|- |==============================
| yk_counter || integer || last seen session counter by sender
|-
| yk_use || integer || last seen session use by sender
|-
| yk_high || integer || OTP internal high time value
|-
| yk_low || integer || OTP internal low time value
|}
Input values for yk_counter, yk_use, yk_high and yk_low are always Input values for yk_counter, yk_use, yk_high and yk_low are always
positive except for -1 which indicates that the requesting server did positive except for -1 which indicates that the requesting server did
@ -54,35 +42,27 @@ not have any earlier information about the !YubiKey.
An example response is An example response is
```sh modified=1264430686
modified=1264430686 nonce=aspodkaaspdokas
nonce=aspodkaaspdokas yk_identity=cccccccccccf
yk_identity=cccccccccccf yk_counter=api2 session counter
yk_counter=api2 session counter yk_use=api2 session use counter
yk_use=api2 session use counter yk_high=value
yk_high=value yk_low=value
yk_low=value
```
The values returned are: The values returned are:
{| [options="header"]
! parameter !! type !! values |====================
|- | parameter |type |values
| modified || integer || timestamp of when last OTP was received | modified | integer | timestamp of when last OTP was received
|- | nonce | string | nonce from client for last OTP
| nonce || string || nonce from client for last OTP | yk_identity | modhex | YubiKey OTP identity in question
|- | yk_counter | integer | last seen session counter
| yk_identity || modhex || !YubiKey OTP identity in question | yk_use | integer | last seen session use
|- | yk_high | integer | last seen high time value
| yk_counter || integer || last seen session counter | yk_low | integer | last seen low time value
|- |========================
| yk_use || integer || last seen session use
|-
| yk_high || integer || last seen high time value
|-
| yk_low || integer || last seen low time value
|}
Output values for modified, yk_counter, yk_use, yk_high and yk_low are Output values for modified, yk_counter, yk_use, yk_high and yk_low are
always positive except for -1 which indicates that the server did not always positive except for -1 which indicates that the server did not

View File

@ -14,16 +14,14 @@ The typical way to use this is either manually or to run it in a cron
job and output the hash to a file that can be downloaded by a remote job and output the hash to a file that can be downloaded by a remote
monitor system such as Nagios. monitor system such as Nagios.
```sh user@val:~$ sudo sh -c 'cat > /etc/cron.hourly/run-ykval-checksum-clients'
user@val:~$ sudo sh -c 'cat > /etc/cron.hourly/run-ykval-checksum-clients' #!/bin/sh
#!/bin/sh FILE=/var/www/checksum-clients.txt
FILE=/var/www/checksum-clients.txt (date --utc +%s; ykval-checksum-clients) > $FILE.tmp
(date --utc +%s; ykval-checksum-clients) > $FILE.tmp mv $FILE.tmp $FILE
mv $FILE.tmp $FILE user@val:~$ sudo chmod +x /etc/cron.hourly/run-ykval-checksum-clients
user@val:~$ sudo chmod +x /etc/cron.hourly/run-ykval-checksum-clients
```
If you notice mismatches, you may want to run ykval-checksum-clients If you notice mismatches, you may want to run ykval-checksum-clients
with the '-v' parameter on the different hosts and then use 'diff -ur' with the '-v' parameter on the different hosts and then use 'diff -ur'
or similar tool to compare the outputs. This should make it possible or similar tool to compare the outputs. This should make it possible
to identify the missmatching entries easily. to identify the missmatching entries easily.

View File

@ -15,9 +15,7 @@ tables.
If 'ykval-export' crashes, you may be running into a compatibility If 'ykval-export' crashes, you may be running into a compatibility
problem between PHP, curl and libpq. See problem between PHP, curl and libpq. See
[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=411982] for more http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=411982 for more
information. The workaround is simple: information. The workaround is simple:
``` user@val:~$ sudo mv /etc/php5/conf.d/curl.ini /etc/php5/conf.d/z_curl.ini
user@val:~$ sudo mv /etc/php5/conf.d/curl.ini /etc/php5/conf.d/z_curl.ini
```

View File

@ -13,23 +13,23 @@ Val X receives an OTP verify request and needs to update the other
validation servers on the last seen counter values. The procedure is validation servers on the last seen counter values. The procedure is
as follows as follows
# Val X parses validation request, retrieves the client key for the client id from local database and checks the request signature. . Val X parses validation request, retrieves the client key for the client id from local database and checks the request signature.
# Val X decrypts the OTP using a KSM and reads out the modified/counters from the internal database -- if the YubiKey identity doesn't exist in the database, add it with counter/use/high/low=-1. . Val X decrypts the OTP using a KSM and reads out the modified/counters from the internal database -- if the YubiKey identity doesn't exist in the database, add it with counter/use/high/low=-1.
# Val X checks the OTP/Nonce against local database, and replies with REPLAYED_REQUEST if local information is identical. . Val X checks the OTP/Nonce against local database, and replies with REPLAYED_REQUEST if local information is identical.
# Val X checks the OTP counters against local counters, and rejects OTP as replayed if local counters are higher than or equal to OTP counters. . Val X checks the OTP counters against local counters, and rejects OTP as replayed if local counters are higher than or equal to OTP counters.
# Val X updates the internal database with counters/nonce from request. . Val X updates the internal database with counters/nonce from request.
# Val X queues a sync request in a sync queue for each validation server in the validation server pool (manually configured). . Val X queues a sync request in a sync queue for each validation server in the validation server pool (manually configured).
# Val X requests the queued requests (otp, modified, nonce, yk_identity, yk_counter, yk_use, yk_high, yk_low) to be sent out, by sending parallel sync requests to all other validation servers. . Val X requests the queued requests (otp, modified, nonce, yk_identity, yk_counter, yk_use, yk_high, yk_low) to be sent out, by sending parallel sync requests to all other validation servers.
# Each validation server receiving a sync request updates its own internal database with received information to use the highest counter. . Each validation server receiving a sync request updates its own internal database with received information to use the highest counter.
# Each remote server responds with a sync response (modified, nonce, yk_identity, yk_counter, yk_use, yk_high, yk_low) using data from its internal database. . Each remote server responds with a sync response (modified, nonce, yk_identity, yk_counter, yk_use, yk_high, yk_low) using data from its internal database.
# Val X waits for a sync response (up until timeout, or when sufficient number of sync responses indicating valid OTP and no sync response indicating invalid OTP) from the other validation servers to which it sent a sync request. For each response that arrives the corresponding entry in the sync queue is removed and the following is checked . Val X waits for a sync response (up until timeout, or when sufficient number of sync responses indicating valid OTP and no sync response indicating invalid OTP) from the other validation servers to which it sent a sync request. For each response that arrives the corresponding entry in the sync queue is removed and the following is checked
## If the sync response counters have higher values than val X internal database, the internal database is updated with new information, AND .. If the sync response counters have higher values than val X internal database, the internal database is updated with new information, AND
## If the sync response counter have higher values as val X internal database the response is considered to mark the OTP as invalid, AND .. If the sync response counter have higher values as val X internal database the response is considered to mark the OTP as invalid, AND
## If the sync response have equal counter values and nonce as val X internal database the response is considered to mark the OTP as valid, AND .. If the sync response have equal counter values and nonce as val X internal database the response is considered to mark the OTP as valid, AND
## If the sync response have equal counter values and different nonce as val X internal database the response is considered to mark the OTP as invalid, AND .. If the sync response have equal counter values and different nonce as val X internal database the response is considered to mark the OTP as invalid, AND
## If the sync response counter have smaller values than val X had in its internal database before the validation attempt the server logs a warning, and the response is considered to mark the OTP as valid. .. If the sync response counter have smaller values than val X had in its internal database before the validation attempt the server logs a warning, and the response is considered to mark the OTP as valid.
# Val X construct validation response. Validation is successful if the Verification Algorithm below is successful. . Val X construct validation response. Validation is successful if the Verification Algorithm below is successful.
# Val X marks the remaining entries in the sync queue as marked with timestamp=NULL. . Val X marks the remaining entries in the sync queue as marked with timestamp=NULL.
Any remaining sync requests in the sync queue are from now on handled Any remaining sync requests in the sync queue are from now on handled
by a background daemon which re-sends them at regular intervals by a background daemon which re-sends them at regular intervals
@ -37,30 +37,30 @@ by a background daemon which re-sends them at regular intervals
=== Verification algorithm === === Verification algorithm ===
```sh ....
Input: Input:
otp - the otp otp - the otp
nonce - the nonce from the request nonce - the nonce from the request
yk:counter - the session counter yk:counter - the session counter
yk:use - the session use counter yk:use - the session use counter
yk:high - the high timestamp yk:high - the high timestamp
yk:low - the low timestamp yk:low - the low timestamp
modified - when the counters were last modified modified - when the counters were last modified
Output: Output:
Error code. Error code.
``` ....
Val X requires that SL % of the sent sync requests gives a response Val X requires that SL % of the sent sync requests gives a response
marking the OTP as valid, and that none of the responses indicate the marking the OTP as valid, and that none of the responses indicate the
OTP is invalid, in order to consider the OTP to be valid. OTP is invalid, in order to consider the OTP to be valid.
# If internal database counters are equal to otp counters AND nonce is identical, then return REPLAYED_REQUEST. . If internal database counters are equal to otp counters AND nonce is identical, then return REPLAYED_REQUEST.
# If internal database counters are higher/equal to otp counters, then return REPLAYED_OTP. . If internal database counters are higher/equal to otp counters, then return REPLAYED_OTP.
# If any counter in sync response are higher/equal to otp counters, then return REPLAYED_OTP. . If any counter in sync response are higher/equal to otp counters, then return REPLAYED_OTP.
# If insufficient number of sync responses are received, then return NOT_ENOUGH_ANSWERS. . If insufficient number of sync responses are received, then return NOT_ENOUGH_ANSWERS.
# (optional: if phishing test fails, return DELAYED_OTP) . (optional: if phishing test fails, return DELAYED_OTP)
# return OK . return OK
=== Warning algorithm === === Warning algorithm ===
@ -102,33 +102,29 @@ queued requests.
The sync queue will loop the following algorithm. The sync queue will loop the following algorithm.
# Get a list of all remote server from the database; S1, S2, ... . Get a list of all remote server from the database; S1, S2, ...
# For each remote server S in the list S1, S2, ... do . For each remote server S in the list S1, S2, ... do
## For each entry in the queue table for S which have a queued_time==NULL or a timestamp older than a configured period (e.g., one minute) do .. For each entry in the queue table for S which have a queued_time==NULL or a timestamp older than a configured period (e.g., one minute) do
### Send one request, using a configured timeout value (e.g., 30 seconds). ... Send one request, using a configured timeout value (e.g., 30 seconds).
### If the request is unsuccessful (or times out), quit to the outer loop. ... If the request is unsuccessful (or times out), quit to the outer loop.
### The request was successful so the sync daemon receives counter/nonce values from the remote server. ... The request was successful so the sync daemon receives counter/nonce values from the remote server.
### If the sync response counters are lower, give a warning ... If the sync response counters are lower, give a warning
### If the sync response counters are equal and nonce different, give a warning ... If the sync response counters are equal and nonce different, give a warning
### If the sync response counter have higher than or equal values as val X internal database had at the moment of request creation a warning is logged. ... If the sync response counter have higher than or equal values as val X internal database had at the moment of request creation a warning is logged.
### The sync daemon updates the internal database to use the highest counter values: {{{UPDATE yubikeys SET counter = X, sessionUse = Y, high = P, low = Q, nonce = N, accessed = D WHERE publicName = ID AND ((counter < X) OR (counter = X AND sessionUse < Y))}}} ... The sync daemon updates the internal database to use the highest counter values: {{{UPDATE yubikeys SET counter = X, sessionUse = Y, high = P, low = Q, nonce = N, accessed = D WHERE publicName = ID AND ((counter < X) OR (counter = X AND sessionUse < Y))}}}
### The corresponding entry in the sync queue is removed. ... The corresponding entry in the sync queue is removed.
= Logging matrix = == Logging matrix
Available parameters in comparisons are the following. Available parameters in comparisons are the following.
{| |================
| local || Local parameters at time of comparison | local | Local parameters at time of comparison
|- | otp | Parameters from OTP provided in validation request
| otp || Parameters from OTP provided in validation request | response | Parameters in sync respone
|- | request | Parameters in sync request
| response || Parameters in sync respone | validation | Local parameters when OTP vaildation request arrived
|- |================
| request || Parameters in sync request
|-
| validation || Local parameters when OTP vaildation request arrived
|}
Parameters could be counters, modified, nonce. Parameters could be counters, modified, nonce.
== Non-queued Sync response logging == == Non-queued Sync response logging ==
@ -137,21 +133,16 @@ We compare reponse parameters against validation parameters since we
are interested in if the server is in sync at the moment when the are interested in if the server is in sync at the moment when the
validation request arrives. validation request arrives.
{| [options="header"]
! condition !! level !! action !! message |=============
|- | condition |level |action |message
| response.counters < validation.counters || Notice || None || Remote server out of sync. | response.counters < validation.counters | Notice | None | Remote server out of sync.
|- | response.counters > validation.counters | Notice | None |Local server out of sync.
| response.counters > validation.counters || Notice || None ||Local server out of sync. | response.counters = validation.counters and response.nonce != validation.nonce | Notice | None | Servers out of sync. Nonce differs.
|- | response.counters = validation.counters and response.modified != validation.modified | Notice | None | Servers out of sync. Modified differs.
| response.counters = validation.counters and response.nonce != validation.nonce || Notice || None || Servers out of sync. Nonce differs. | response.counters > otp.counters | Warning | OTP marked as invalid |OTP is replayed. Sync response counters higher than OTP counters
|- | response.counter = otp.counters and response.nonce != otp.nonce | Warning | OTP marked as invalid | OTP is replayed. Sync response counters equal to OTP counters and nonce differs.
| response.counters = validation.counters and response.modified != validation.modified || Notice || None || Servers out of sync. Modified differs. |=============
|-
| response.counters > otp.counters || Warning || OTP marked as invalid ||OTP is replayed. Sync response counters higher than OTP counters
|-
| response.counter = otp.counters and response.nonce != otp.nonce || Warning || OTP marked as invalid || OTP is replayed. Sync response counters equal to OTP counters and nonce differs.
|}
== Sync request logging == == Sync request logging ==
@ -159,35 +150,27 @@ Both an original sync and a queued sync looks the same so we can not
determine if the sync is original or queued. Therefore the logging is determine if the sync is original or queued. Therefore the logging is
the same in both cases. the same in both cases.
{| [options="header"]
! condition !! level !! message !! note |==============
|- | condition |level |message |note
| request.counters < local.counters || Warning || Remote server out of sync. || | request.counters < local.counters | Warning | Remote server out of sync. |
|- | request.counters = local.counters and request.modified = local.modifed and request.nonce = local.nonce | Notice | Sync request has been unnecessarily resent. | This could happen frequently whenever a syncentry is queued but the syncprocess terminates before the resonse to the syncentry arrives (since SL level was already achived).
| request.counters = local.counters and request.modified = local.modifed and request.nonce = local.nonce || Notice || Sync request has been unnecessarily resent. || This could happen frequently whenever a syncentry is queued but the syncprocess terminates before the resonse to the syncentry arrives (since SL level was already achived). | request.counters = local.counters and request.modified != local.modified and request.nonce = local.nonce | Warning | We might have a replay. 2 events at different times have generated the same counters. The time difference is X seconds |
|- | request.counters = local.counters and request.nonce != local.nonce | Warning | Remote server has received a request to validate an already validated OTP |
| request.counters = local.counters and request.modified != local.modified and request.nonce = local.nonce || Warning || We might have a replay. 2 events at different times have generated the same counters. The time difference is X seconds || |===================
|-
| request.counters = local.counters and request.nonce != local.nonce || Warning || Remote server has received a request to validate an already validated OTP ||
|}
== Queued sync response logging == == Queued sync response logging ==
What do we want to warn for here. Out of sync at time of OTP What do we want to warn for here. Out of sync at time of OTP
validation request or out of sync compared to current local counters? validation request or out of sync compared to current local counters?
{| [options="header"]
! condition !! level !! message !! note |==============
|- | condition |level |message |note
| response.counters < validation.counters || Notice || Remote server out of sync compared to counters at validation request time. || | response.counters < validation.counters | Notice | Remote server out of sync compared to counters at validation request time. |
|- | response.counters > validation.counters | Notice | Local server out of sync compared to counters at validation request time. |
| response.counters > validation.counters || Notice || Local server out of sync compared to counters at validation request time. || | response.counters < local.counters | Warning | Remote server out of sync compared to current local counters. |
|- | response.counters > local.counters | Warning | Local server out of sync compared to current local counters. Local server updated. |
| response.counters < local.counters || Warning || Remote server out of sync compared to current local counters. || | response.counters > otp.counters | Error | Remote server has higher counters than OTP. This response would have marked the OTP as invalid. |
|- | response.counter = otp.counters and response.nonce != otp.nonce | Error | Remote server has equal counters as OTP and nonce differs. This response would have marked the OTP as invalid. |
| response.counters > local.counters || Warning || Local server out of sync compared to current local counters. Local server updated. || |===============
|-
| response.counters > otp.counters || Error || Remote server has higher counters than OTP. This response would have marked the OTP as invalid. ||
|-
| response.counter = otp.counters and response.nonce != otp.nonce || Error || Remote server has equal counters as OTP and nonce differs. This response would have marked the OTP as invalid. ||
|}

View File

@ -5,42 +5,38 @@ This file holds data used in the YubiKey OTP validation phase.
Each of the lines in the file follows the following format: Each of the lines in the file follows the following format:
``` active,created,modified,yk_publicname,yk_counter,yk_use,yk_low,yk_high,nonce,notes
active,created,modified,yk_publicname,yk_counter,yk_use,yk_low,yk_high,nonce,notes
```
Any empty line, or a line beginning with a # is ignored. Any empty line, or a line beginning with a # is ignored.
The meaning are as follows: The meaning are as follows:
``` ....
active active
the YubiKey state, 1 if active, 0 if not the YubiKey state, 1 if active, 0 if not
created created
unix timestamp of when the YubiKey entry was created, decimal integer unix timestamp of when the YubiKey entry was created, decimal integer
modified modified
unix timestamp of when the YubiKey entry was last modified, decimal integer unix timestamp of when the YubiKey entry was last modified, decimal integer
yk_publicname yk_publicname
the public id of the YubiKey, modhex string the public id of the YubiKey, modhex string
yk_counter yk_counter
the YubiKey session counter, decimal integer the YubiKey session counter, decimal integer
yk_use yk_use
the YubiKey use counter, decimal integer the YubiKey use counter, decimal integer
yk_low yk_low
the low part of the YubiKey timestamp counter, decimal integer the low part of the YubiKey timestamp counter, decimal integer
yk_high yk_high
the high part of the YubiKey timestamp counter, decimal integer the high part of the YubiKey timestamp counter, decimal integer
nonce nonce
the nonce used for the last validation request, ascii printable string the nonce used for the last validation request, ascii printable string
notes notes
not used, printable ascii string not used, printable ascii string
``` ....
An example of a valid data line: An example of a valid data line:
``` 1,1359470658,1359470658,cccccccccccb,2,1,32729,4,aoincuhfuahs
1,1359470658,1359470658,cccccccccccb,2,1,32729,4,aoincuhfuahs
```
For an example of importing and exporting YubiKey Info data, please see For an example of importing and exporting YubiKey Info data, please see
`ImportExportData.adoc`. link:ImportExportData.html[ImportExportData]