Introduction
Fortanix Data Security Manager (DSM) can be used to protect the TLS private key for your NGINX and Apache server, keeping the private key secure even if the host running these servers is compromised.
This article describes how to set up your NGINX and Apache server running on Red Hat to use a TLS private key stored in Fortanix DSM.
Prerequisites
The following software components are required. The procedure described here was tested with the versions mentioned below:
- NGINX:
- Redhat Enterprise Linux Server (7.6)
- NGINX (1.18.0)
- OpenSSL (1.0.2-k)
- OpenSC (0.19.0)
- OpenSSL PKCS11 engine (0.4.10)
- Apache:
- Red Hat Enterprise Linux Server (8.2)
- Apache (2.4.37)
- mod_ssl (2.4.37)
- OpenSSL (1.1.1-c)
- OpenSC (0.19.0)
- OpenSSL PKCS11 engine (0.4.10)
- Red Hat Enterprise Linux Server (7.8)
- Apache (2.4.6)
- mod_nss (1.0.14)
- nss-tools (3.44.0)
- OpenSSL (1.0.2k)
- OpenSC (0.19.0)
- OpenSSL PKCS11 engine (0.4.10)
- Red Hat Enterprise Linux Server (8.2)
- Fortanix PKCS11 library (3.19.1348)
Installing Prerequisites
- NGINX
If you need to install NGINX, please refer to the instructions in the URL:
https://www.nginx.com/resources/wiki/start/topics/tutorials/install/ - Apache and mod_ssl
If you need to install Apache, install it by running:
On Red Hat 8 you will need to install “mod_ssl” and on Red Hat 7 you will need to install “mod_nss”.
sudo yum install httpd
Red Hat 8
sudo yum install mod_ssl
Red Hat 7
sudo yum install mod_nss
sudo yum install nss-tools - OpenSC
Run the following command to run OpenSC. This package provides PKCS#11 tools and PKCS#11 engine plugin for the OpenSSL library which allows accessing PKCS#11 modules in a semi-transparent way.sudo yum install opensc
- Install OpenSSL PKCS#11 engine using the following command:
wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/o/openssl-pkcs11-0.4.10-1.el7.x86_64.rpm
sudo rpm -i openssl-pkcs11-0.4.10-1.el7.x86_64.rpm - Fortanix PKCS#11 library
Download Fortanix PKCS#11 library RPM package from the following URL:
https://support.fortanix.com/hc/en-us/articles/360018312391-PKCS-11
Install it by running the following command:sudo rpm -i <package name>, for example
sudo rpm -i fortanix-pkcs11-3.19.1348-0.x86_64.rpm
Setting Up Fortanix Data Security Manager
For this integration, create a group and app in Fortanix DSM. For instructions on creating a group and app in Fortanix DSM please check the Getting Started Guide.
Note the API key of the app you added. We will need this in the next steps where API_KEY
is mentioned.
Setting Up OpenSSL to Use PKCS#11
- Save the current OpenSSL configuration file (
openssl.cnf
) before making changes:sudo cp /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl.cnf.bak
- Now set up OpenSSL configuration file as follows to have the PKCS#11 engine section.
# PKCS11 engine config openssl_conf = openssl_def [openssl_def] engines = engine_section [req] distinguished_name = req_distinguished_name [req_distinguished_name] # empty [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = pkcs11 dynamic_path = /usr/lib64/openssl/engines/libpkcs11.so MODULE_PATH = /opt/fortanix/pkcs11/fortanix_pkcs11.so PIN = API_KEY init = 1
Testing Setup
Use the following commands to verify the setup is correct:
Testing the Engine Operation
- To verify that the engine is properly operating run the following command.
openssl engine pkcs11 -t
(pkcs11) pkcs11 engine
[ available ]
Testing the PKCS#11 Library
- Export the following environment variables (replace values as appropriate for your environment) and use pkcs11-tool as shown below:
export OPENSSL_CONF=/etc/pki/tls/openssl.cnf
export FORTANIX_API_ENDPOINT=https://<fortanix_dsm_url>/
export FORTANIX_API_KEY=API_KEY
Verify PKCS#11 Library
Run the following command to verify if the PKCS#11 library works correctly:
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so -I
This should return the output as follows:
*** Cryptoki library has already been initialized ***
Cryptoki version 2.40
Manufacturer Fortanix
Library Fortanix PKCS11 3.19.1348 (ver 3.19)
Using slot 0 with a present token (0x0)
List Keys from Fortanix Data Security Manager
Run the following command to list keys from Fortanix DSM.
This should return keys that are already there in the group:
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so --login --pin $FORTANIX_API_KEY -O
Generate a Key in Fortanix Data Security Manager
Run the following command to generate an RSA key in Fortanix DSM:
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so --login --pin $FORTANIX_API_KEY -k --id `uuidgen | tr -d -` --label "Test RSA key" --key-type rsa:2048
On success the output will be as follows:
*** Cryptoki library has already been initialized ***
Using slot 0 with a present token (0x0)
Key pair generated:
Private Key Object; RSA
label: Test RSA key
ID: bc017c71c51447aeaa3af6c38a42f810
Usage: decrypt, sign, unwrap
Public Key Object; RSA 2048 bits
label: Test RSA key
ID: bc017c71c51447aeaa3af6c38a42f810
Usage: encrypt, verify, wrap
Verify that this command succeeds, and the RSA key is generated in Fortanix DSM. You can verify by looking at the Security Objects page in the WebUI or running the pkcs11-tool command mentioned earlier.
Note the Key ID returned from this command. We will need it in the next steps for verification.
Testing the OpenSSL with PKCS#11 Library
Now we will verify if OpenSSL with Fortanix PKCS#11 library is working correcting by performing some cryptographic operations using the key we generated earlier in Fortanix DSM.
Encrypting Data with the Key in Fortanix Data Security Manager
Run the following command to encrypt some data with the key we created in the previous step. For ID here, use the Key ID you got in the previous step (in this example, it is bc017c71c51447aeaa3af6c38a42f810
).
- Create an input text file that will be used for encryption. For example, you can do the following:
cat > input.txt
- Test the encryption.
- Press CTRL+C to complete the creation of the file.
- Run the following command to encrypt the file:
openssl rsautl -engine pkcs11 -in input.txt -out cipher.data -encrypt -keyform engine -inkey 1:bc017c71c51447aeaa3af6c38a42f810
cipher.data
” which contains the encrypted data. You can also verify that the key in Fortanix DSM was used for this operation by looking at the event log for the key. - You can also use the following command to decrypt the data and verify that decryption also works:
openssl rsautl -engine pkcs11 -in cipher.data -out output.txt -decrypt -keyform engine -inkey 1:bc017c71c51447aeaa3af6c38a42f810
Importing TLS Key and Certificate into Fortanix Data Security Manager
You can import your existing TLS key and certificate into Fortanix DSM either using WebUI or using the pkcs11-tool.
Import Using WebUI
To import using the WebUI, do the following:
- Log in to the Fortanix DSM UI and select the Security Objects
icon from the left panel and then the
icon to open a new security object form.
- Provide a name for the key and select IMPORT option to import a key. (Note this name, we will need to specify this in the NGINX configuration file).
- Select RSA in the Choose a type section for the security object type.
- Select Base64 for the value format and upload your key.
- Associate the key to the previously created group.
- Click IMPORT to create the security object. (See example screenshot below).
Figure 1: Import Security Object
Import Using PKCS#11-Tool
To import using the pkcs11-tool, do the following:
Assuming that you have the private key in a file key.pem
, you can use the following commands to import the key into Fortanix DSM.
openssl rsa -inform pem -outform der -in key.pem -out key.der
pkcs11-tool --module $PKCS11_LIBRARY --login --pin <API key> --write-object key.der --type privkey --id `uuidgen | tr -d -` --label "YOUR_PRIVATE_KEY_LABEL"
Note the Key ID value from the output of this command. You will need it when importing a TLS certificate. For the examples mentioned in this document, the key label value will be “SDKMS_Nginx_Private_Key”.
For Apache running on Red Hat 7, you will also need to import your TLS certificate and associate this certificate to the private key you imported. Assuming that you have the certificate in a file cert.pem
, you can use the following commands to import the certificate into Fortanix DSM. Please note the ID_VALUE
in this command is the Key ID that was displayed when you imported the private key in the previous command.
openssl rsa -inform pem -outform der -in cert.pem -out cert.der
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so --login --pin <API Key> --write-object cert.der --type cert --id ID_VALUE --label "SDKMS_Apache_Certificate"
For the examples mentioned in this document, the key label value will be “SDKMS_Nginx_Private_Key
”.
Configuring NGINX to Use Key From Fortanix Data Security Manager
Assuming you already have NGINX server configured to use TLS keys, the following steps will guide to you to make changes so that while the certificate file is stored locally, (in this example - /etc/nginx/certificate.crt
) the corresponding key is securely stored in Fortanix DSM and all crypto operations with this private key are offloaded to Fortanix DSM.
If you do not already have TLS keys and would like to generate TLS keys in Fortanix DSM and generate CSR, you can use OpenSSL and pkcs11-tool to accomplish that. Please see the details at Generating a TLS key and importing a CA-issued certificate.
Update NGINX Configuration File
Update the NGINX configuration file (/etc/nginx/nginx.conf
) file to specify the SSL private key which needs to be accessed using the PKCS#11 engine. The highlighted key name after the word ‘label
’ corresponds to the name of the key in Fortanix DSM when you imported it (in this example : SDKMS_Nginx_Private_Key
). The lines to be edited are shown in the following snippet:
##
# SSL Settings
##
ssl_certificate /etc/nginx/certificate.crt;
ssl_certificate_key engine:pkcs11:label_key_name;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
Update NGINX Startup File
Update the NGINX service start-up file to pass the necessary environment variables for integration with Fortanix DSM. These environment variables allow the PKCS#11 engine and PKCS#11 library to work and point to your Fortanix DSM URL.
Edit the file /usr/lib/systemd/system/nginx.service
and add the environment variables under the “service
” section as follows (see highlighted text). Please update the value of FORTANIX_API_ENDPOINT
to point to your instance of Fortanix DSM.
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Environment="OPENSSL_CONF=/etc/pki/tls/openssl.cnf"
Environment="FORTANIX_API_ENDPOINT=https://<fortanix_dsm_url>/"
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
Restarting NGINX
Now, to restart NGINX and make it use the key stored in Fortanix DSM, do the following:
sudo systemctl daemon-reload
sudo systemctl restart nginx
Verification
To verify that the configuration is working correctly, connect to your NGINX server using a browser. You should be able to connect successfully. You can also check the key usage event logs in Fortanix DSM to verify that the key is being used as you connect to your NGINX server.
Configuring Apache to Use Key From Fortanix Data Security Manager
This section describes how to configure Apache on Red Hat 8 and mod_ssl and on Red Hat 7 using mod_nss.
Assuming that you already have an Apache server configured to use TLS keys, the following steps will guide you to make changes so that the private key is securely stored in Fortanix DSM and all crypto operations with this private key are offloaded to Fortanix DSM.
- In case of Red Hat 8, in this example certificate file is stored locally, (
/etc/pki/tls/certs/localhost.crt
) - In case of Red Hat 7, in this example, we store certificates as well in Fortanix DSM.
If you do not already have TLS keys and would like to generate TLS keys in Fortanix DSM and generate CSR, you can use OpenSSL and pkcs11-tool to accomplish that. Please see the details at Generating a TLS key and importing a CA-issued certificate.
Create PKCS11 Config File
Create PKCS11 config file /etc/pkcs11/pkcs11.conf
and add the following configuration:
api_key = "Your App API Key"
api_endpoint = "Your DSM URL"
Red Hat 7 - Set up Mod nss and Update nss Configuration File
On Red Hat 7 mod_nss is used. You need to set up NSS and update the Apache mod_nss configuration file (/etc/httpd/conf.d/nss.conf
) to specify the SSL certificate and the key needs to be fetched using the PKCS#11 engine.
Run the following commands to set up NSS:
sudo mkdir /etc/nss
sudo certutil -N -d /etc/nss --empty-password
sudo modutil -add pkcs11 -libfile /opt/fortanix/pkcs11/fortanix_pkcs11.so -dbdir /etc/nss -force
sudo modutil -enable pkcs11 -dbdir /etc/nss -force
sudo chown -R apache:apache /etc/nss
Create a PIN file that contains the Fortanix Token and its Pin by creating a file “etc/nss/pin.txt
” with the content as follows:
Fortanix Token:API_KEY
For example,
sudo su
echo Fortanix Token: NmM4YjZhOTQtYmEzZS00N....h3 > /etc/nss/pin.txt
Edit the NSS configuration file (/etc/httpd/conf.d/nss.conf
) and make the following changes:
- Update the pass phrase gathering process by changing the value of “
NSSPassPhraseDialog
” as follows:NSSPassPhraseDialog file:/etc/nss/pin.txt
- Update the server certificate database by changing the value of “
NSSCertificateDatabase
” as follows:NSSCertificateDatabase /etc/nss
- Update the SSL certificate Nickname by changing the value of “
NSSNickname
” as follows:NSSNickname "Fortanix Token:Your Certificate Label"
NSSNickname "Fortanix Token:SDKMS_Apache_Certificate"
Red Hat - Update Apache SSL Configuration File
On Red Hat 8 mod_ssl is used. We need to update the Apache mod_ssl configuration file (/etc/httpd/conf.d/ssl.conf
) file to specify the SSL private key which needs to be accessed using PKCS#11 engine.
The highlighted Key ID after the word ‘id=
’ corresponds to the CKA_ID
of the key in Fortanix DSM when you imported or created it. As per the PKCS#11 URI format (RFC 7512), the value of ‘id
’ must be percent-encoded. You can find the CKA_ID
of the key from the WebUI, by going to the detailed view of the security object then click the “Attributes” tab as shown in the following screenshot.
Figure 2: Attributes tab of security object
The lines to be edited are shown in the following snippet:
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile pkcs11:id=%5A%59%6E;type=private
Update Apache Startup File
Update the Apache service start-up file to pass the necessary environment variables for integration with Fortanix DSM. These environment variables allow PKCS#11 engine and PKCS#11 library to work and point to your Fortanix DSM URL.
Edit the file /usr/lib/systemd/system/httpd.service
and add the environment variables under the “Service” section as follows (see highlighted text). Please update the value of FORTANIX_API_ENDPOINT
to point to your instance of Fortanix DSM.
[Unit]
Description=The Apache HTTP Server
Wants=httpd-init.service
After=network.target remote-fs.target nss-lookup.target httpd-init.service
Documentation=man:httpd.service(8)
[Service]
Type=notify
Environment=LANG=C
Environment="OPENSSL_CONF=/etc/pki/tls/openssl.cnf"
Environment="FORTANIX_API_ENDPOINT=YOUR DSM URL"
Environment="FORTANIX_PKCS11_NUM_SLOTS=1"
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
# Send SIGWINCH for graceful stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Restarting Apache
Now, to restart Apache and make it use the key stored in Fortanix DSM, do the following:
sudo systemctl daemon-reload
sudo systemctl restart httpd
Verification
To verify that the configuration is working correctly, connect to your Apache server using a browser. You should be able to connect successfully. You can also check the key usage event logs in Fortanix DSM to verify that the key is being used as you connect to your Apache server.
Troubleshooting
If you see any issues, please use the steps mentioned in the section Testing Setup to verify if each piece of integration is working correctly. If you still see issues, please look at the PKCS11 logs in /var/log/messages
and share with the Fortanix support team: (support@fortanix.com).
Comments
Please sign in to leave a comment.