Add pkcs#11 support with tls-auth option
This merge request is based on heyLu/NetworkManager-openvpn!2. It allows using PKCS#11 tokens and adds two new connection types.
The issues with original MR were:
- TLS Authentication tab is missing in Advanced Setting
- Authentication Type names don't match settings behind it
I haven't found any style guides or linters. Thus, provide MR as is.
Motivation
Secure storage of credentials can be archived in different ways with different security levels. One way is to store certificates and private keys for VPN on a hardware token.
Usually, tokens support a PKCS#11 interface. This MR adds ability to use it, additionally specifying a module with particular a PKCS#11 implementation.
MR changes
The MR adds two new connection types:
- Certificates (TLS), PKCS#11
- Password with Certificates (TLS), PKCS#11
These connection types support new fields:
- PKCS#11 providers (rename to PKCS#11 provider?)
- PKCS#11 id
- PKCS#11 pin
If the field PKCS#11 providers is empty, p11-kit can be used.
How to test
The following is required:
- OpenVPN server
- PKCS#11 token
- Compiled and installed NetworkManager-openvpn plugin
To deploy an OpenVPN server you can use this article. As a token emulator use SoftHSM2.
Assuming you have client's certificate (cert.pem
) and key (key.pem
) add them to the token this way:
LABEL=nm-openvpn-plugin-test
softhsm2-util --init-token --slot 0 --label ${LABEL}
TOKEN_URL=$(p11tool --list-tokens | grep ${LABEL} | grep URL | awk '{print $2}')
p11tool --login --write ${TOKEN_URL} --load-certificate cert.pem --label ovpn-test
p11tool --login --write ${TOKEN_URL} --load-privkey key.pem --label ovpn-test
To get PKCS#11 providers and id run the following commands:
PKCS11_MODULE=$(p11tool --list-tokens | grep libsofthsm2.so | awk '{print $2}')
echo "Provider: ${PKCS11_MODULE}"
echo -E "ID: $(openvpn --show-pkcs11-ids ${PKCS11_MODULE} | grep "Serialized id:" | awk '{print $3}')"
You must know PIN yourself.
Then create a new connection of type Certificates (TLS), PKCS#11 and specify parameters. You're all set.
Security considerations
As mentioned in the comments to the MR, a user can elevate their privileges specifying arbitrary so-file. It works because an so-file is run with root privileges when the connection is activated.
To protect from this issue NM_OPENVPN_PKCS11_PROVIDERS_PREFIX
was introduced effectively limiting available so-files. Thus, only root user can add new modules under NM_OPENVPN_PKCS11_PROVIDERS_PREFIX
. It was considered a good enough solution until CVE-2023-38408. Now I see several possible solutions:
- limit
NM_OPENVPN_PKCS11_PROVIDERS_PREFIX
even more (a bad one) - create symlinks to allowed modules/providers somewhere under
/etc/NetworkManager/
and use them - completely rely on p11-kit
The third solution seems to be the most robust. NetworkManager itself behaves in a similar way.