|
|
# PKCS#11 in BIND 9
|
|
|
|
|
|
## Background
|
|
|
|
|
|
The PKCS#11 support in BIND 9 comes in two flavors:
|
|
|
|
|
|
1. The native PKCS#11 that interfaces directly with the HSM provided library via
|
|
|
PKCS#11 API. This allows BIND 9 to interact directly with the PKCS#11
|
|
|
provider for the public key cryptography (DNSSEC).
|
|
|
|
|
|
2. The OpenSSL-based PKCS#11 interfaces with the PKCS#11 provider indirectly via
|
|
|
pkcs11 engine provided by the OpenSC project.
|
|
|
|
|
|
This page describes the second method as it is more universal and doesn't
|
|
|
require BIND 9 to be recompiled.
|
|
|
|
|
|
## OpenSSL-based PKCS#11
|
|
|
|
|
|
engine_pkcs11 tries to fit the PKCS#11 API within the engine API of OpenSSL.
|
|
|
That is, it provides a gateway between PKCS#11 modules and the OpenSSL engine
|
|
|
API. One has to register the engine with OpenSSL and one has to provide the
|
|
|
path to the PKCS#11 module which should be gatewayed to. This can be done by
|
|
|
editing the OpenSSL configuration file, by engine specific controls, or by using
|
|
|
the p11-kit proxy module.
|
|
|
|
|
|
In this document, we'll describe how to compile, install and configure
|
|
|
engine_pkcs11 to be used with BIND 9. For simplicity, we use SoftHSM2 as a
|
|
|
PKCS#11 provider.
|
|
|
|
|
|
We'll assume that the installation path for BIND 9 is `/opt/bind9`.
|
|
|
|
|
|
### Installation
|
|
|
|
|
|
#### Installing SoftHSM2
|
|
|
|
|
|
[SoftHSM2](https://www.softhsm.org) can be either installed as a package or
|
|
|
installed from the source. The installation from the source is beyond the scope
|
|
|
of this document. On DEB-based Linux distributions, the package is called
|
|
|
`softhsm2`, on RPM-based Linux distributions, the package is called just
|
|
|
`softhsm`.
|
|
|
|
|
|
#### Installing engine_pkcs11
|
|
|
|
|
|
The engines_pkcs11 module has be merged into
|
|
|
[libp11](https://github.com/OpenSC/libp11) library. To use engines_pkcs11 with
|
|
|
BIND 9, you either need libp11 (>= 0.5.0) which contains necessary fixes and
|
|
|
hasn't been released yet, or use the version from the master branch of the
|
|
|
upstream repository. In this document, we'll show you how to use the most
|
|
|
current version of the engines_pkcs11. We assume that you have a working build
|
|
|
environment for BIND 9 and git installed.
|
|
|
|
|
|
1. Clone current version of libp11 sources:
|
|
|
|
|
|
```
|
|
|
git clone https://github.com/OpenSC/libp11.git
|
|
|
```
|
|
|
|
|
|
2. Bootstrap and compile:
|
|
|
|
|
|
```
|
|
|
cd libp11
|
|
|
./bootstrap
|
|
|
./configure --with-enginesdir=/opt/bind9/engines
|
|
|
```
|
|
|
|
|
|
3. After the compilation successfully finished, install the engines_pkcs11:
|
|
|
|
|
|
```
|
|
|
make install
|
|
|
```
|
|
|
|
|
|
The output should like something like this:
|
|
|
```
|
|
|
Making install in src
|
|
|
mkdir -p '/opt/bind9/engines'
|
|
|
/bin/sh ../libtool --mode=install install -c pkcs11.la '/opt/bind9/engines'
|
|
|
libtool: install: install -c .libs/pkcs11.dylib /opt/bind9/engines/pkcs11.dylib
|
|
|
libtool: install: install -c .libs/pkcs11.lai /opt/bind9/engines/pkcs11.la
|
|
|
[...]
|
|
|
```
|
|
|
|
|
|
### Configuration
|
|
|
|
|
|
#### Configuring SoftHSM2
|
|
|
|
|
|
We are going to create a private BIND 9 storage for SoftHSM2, but you might want
|
|
|
to keep the one installed by your package provider.
|
|
|
|
|
|
1. The location of the SoftHSM2 can be overriden with `SOFTHSM2_CONF`
|
|
|
environment variable. Make sure that you export this variable to your
|
|
|
workspace before launching any following commands:
|
|
|
|
|
|
```
|
|
|
export SOFTHSM2_CONF=/opt/bind9/etc/softhsm2.conf
|
|
|
```
|
|
|
|
|
|
2. Now, we need to prepare pristine configuration:
|
|
|
|
|
|
```
|
|
|
mkdir -m 0700 -p /opt/bind9/lib/tokens
|
|
|
echo "directories.tokendir = /opt/bind9/lib/tokens" > "${SOFTHSM2_CONF}"
|
|
|
echo "objectstore.backend = file" >> "${SOFTHSM2_CONF}"
|
|
|
echo "log.level = DEBUG" >> "${SOFTHSM2_CONF}"
|
|
|
```
|
|
|
|
|
|
3. And initialize **slot** for BIND 9:
|
|
|
|
|
|
```
|
|
|
softhsm2-util --init-token --free --pin 0000 --so-pin 0000 --label "bind9"
|
|
|
```
|
|
|
|
|
|
You should customize the `pin`, `so-pin` and `label` values, but please make
|
|
|
sure you use correct values when copying the examples below.
|
|
|
|
|
|
#### Configuring OpenSSL to use engine_pkcs11
|
|
|
|
|
|
The canonical documentation for configuring engine_pkcs11 is in the
|
|
|
[libp11/README.md](https://github.com/OpenSC/libp11/blob/master/README.md#pkcs-11-module-configuration),
|
|
|
but here's copy of working configuration with SoftHSM2 for your convenience:
|
|
|
|
|
|
1. We are going to use our own custom copy of OpenSSL configuration, again it's
|
|
|
driven by an environment variable, this time called `OPENSSL_CONF`. We are
|
|
|
going to copy the global OpenSSL configuration (often found in
|
|
|
``etc/ssl/openssl.conf``) and customize it to use engines_pkcs11.
|
|
|
|
|
|
```
|
|
|
cp /etc/ssl/openssl.cnf /opt/bind9/etc/openssl.cnf
|
|
|
```
|
|
|
|
|
|
and export the environment variable:
|
|
|
|
|
|
```
|
|
|
export OPENSSL_CONF=/opt/bind9/etc/openssl.cnf
|
|
|
```
|
|
|
|
|
|
2. Now add following line at the top of file, before any sections (in square
|
|
|
brackets) are defined:
|
|
|
|
|
|
```
|
|
|
openssl_conf = openssl_init
|
|
|
```
|
|
|
|
|
|
3. And add following lines at the bottom of the file:
|
|
|
|
|
|
```
|
|
|
[openssl_init]
|
|
|
engines=engine_section
|
|
|
|
|
|
[engine_section]
|
|
|
pkcs11 = pkcs11_section
|
|
|
|
|
|
[pkcs11_section]
|
|
|
engine_id = pkcs11
|
|
|
dynamic_path = /opt/bind9/engines/pkcs11.so
|
|
|
MODULE_PATH = /usr/lib/softhsm/libsofthsm2.so
|
|
|
init = 0
|
|
|
```
|
|
|
|
|
|
### Key Generation
|
|
|
|
|
|
We are going to assume that you already have a BIND 9 installed, either from a
|
|
|
package, or from the sources, and the tools are readily available in the
|
|
|
`$PATH`.
|
|
|
|
|
|
For generating the keys, we are going to use `pkcs11-tool` available from the
|
|
|
[OpenSC](https://github.com/OpenSC/OpenSC) suite. On both DEB-based and
|
|
|
RPM-based distributions, the package is called `opensc`.
|
|
|
|
|
|
1. Now we need to generate at least two RSA keys:
|
|
|
|
|
|
```
|
|
|
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l -k --key-type rsa:1280 --label example.net-ksk --pin 0000
|
|
|
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l -k --key-type rsa:1280 --label example.net-zsk --pin 0000
|
|
|
```
|
|
|
|
|
|
Remember that each key should have unique label and we are going to use that
|
|
|
label to reference the private key.
|
|
|
|
|
|
2. Convert the RSA keys stored in the HSM into a format that BIND 9 understands.
|
|
|
The `dnssec-keyfromlabel` tool from BIND 9 can link the raw keys stored in
|
|
|
the HSM with the `K<zone>+<alg>+<id>` files. You'll need to provide the
|
|
|
OpenSSL engine name (`pkcs11`), the algorithm (`RSASHA256`) and the PKCS#11
|
|
|
label that specify the token (we initialized it as `bind9`), the name of the
|
|
|
PKCS#11 object (called label when generating the keys using `pkcs11-tool`)
|
|
|
and the HSM PIN.
|
|
|
|
|
|
```
|
|
|
dnssec-keyfromlabel -E pkcs11 -a RSASHA256 -l "token=bind9;object=example.net-ksk;pin-value=0000" -f KSK example.net
|
|
|
```
|
|
|
|
|
|
and ZSK:
|
|
|
|
|
|
```
|
|
|
dnssec-keyfromlabel -E pkcs11 -a RSASHA256 -l "token=bind9;object=example.net-zsk;pin-value=0000" example.net
|
|
|
```
|
|
|
|
|
|
NOTE: you can use PIN stored on disk, by specifying `pin-source=<path_to>/<file>`, f.e.:
|
|
|
|
|
|
```
|
|
|
(umask 0700 && echo -n 0000 > /opt/bind9/etc/pin.txt)
|
|
|
```
|
|
|
|
|
|
and then use in the label specification:
|
|
|
|
|
|
```
|
|
|
pin-source=/opt/bind9/etc/pin.txt
|
|
|
```
|
|
|
|
|
|
3. Confirm that you have one KSK and one ZSK present in the current directory:
|
|
|
|
|
|
```
|
|
|
ls -l K*
|
|
|
```
|
|
|
|
|
|
The output should look like this (the second number will be different):
|
|
|
|
|
|
```
|
|
|
Kexample.net.+008+31729.key
|
|
|
Kexample.net.+008+31729.private
|
|
|
Kexample.net.+008+42231.key
|
|
|
Kexample.net.+008+42231.private
|
|
|
```
|
|
|
|
|
|
### Sign the zone as usual
|
|
|
|
|
|
The zone signing commences as usual, with only one small difference. Again, we
|
|
|
need to provide name of the OpenSSL engine using the `-E` command line option.
|
|
|
|
|
|
```
|
|
|
dnssec-signzone -E pkcs11 -S -o example.net example.net
|
|
|
```
|
|
|
|
|
|
and the output should like the usual thing:
|
|
|
|
|
|
```
|
|
|
Fetching example.net/RSASHA256/31729 (KSK) from key repository.
|
|
|
Fetching example.net/RSASHA256/42231 (ZSK) from key repository.
|
|
|
Verifying the zone using the following algorithms: RSASHA256.
|
|
|
Zone fully signed:
|
|
|
Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
|
|
|
ZSKs: 1 active, 0 stand-by, 0 revoked
|
|
|
example.db.signed
|
|
|
```
|
|
|
|
|
|
🎉 |