Use OpenSSL provider with BIND for Fedora 42+ and RHEL10+

OpenSSL Engine API is deprecated and ability to compile against it is
removed in RHEL10. OpenSSL provider API is the future.

Fedora 42+ also defaults to OpenSSL provider. With pkcs11-provider, the
same PKCS#11 modules can be loaded transparently like with OpenSSL
engines. Thus, we can update configuration to use the provider API.

While Fedora 41 also defaults to OpenSSL provider, we need BIND version
that supports using OpenSSL provider API. This backport was only done in
Fedora 42.

Fixes: https://pagure.io/freeipa/issue/9696

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
Alexander Bokovoy authored and Florence Blanc-Renaud committed 2025-05-06 13:48:35 +02:00
1 parent 6cdabdacc9
commit 1311df2e0e
10 files changed
+140 -29

No files matched your search

+10 -2
View File
@@ -162,12 +162,20 @@
# BIND employs 'pkcs11' OpenSSL engine instead of native PKCS11
# Fedora 31+ uses OpenSSL engine, as well as Fedora ELN (RHEL9)
%if 0%{?fedora} || 0%{?rhel} >= 9
# Howevever, Fedora 40+ and RHEL10+ use OpenSSL provider
%if 0%{?fedora} < 40 || 0%{?rhel} == 9
%global openssl_pkcs11_version 0.4.10-6
%global openssl_pkcs11_name openssl-pkcs11
%global softhsm_version 2.5.0-4
%else
%if 0%{?fedora} >= 40 || 0%{?rhel} >= 10
%global openssl_pkcs11_version 0.3
%global openssl_pkcs11_name pkcs11-provider
%global softhsm_version 2.6.1
%else
%global with_bind_pkcs11 1
%endif
%endif
%if 0%{?rhel} == 8
# Make sure to use PKI versions that work with 389-ds fix for https://github.com/389ds/389-ds-base/issues/4609
@@ -627,7 +635,7 @@ Requires: bind-dnssec-utils >= %{bind_version}
Requires: bind-pkcs11 >= %{bind_version}
%else
Requires: softhsm >= %{softhsm_version}
Requires: openssl-pkcs11 >= %{openssl_pkcs11_version}
Requires: %{openssl_pkcs11_name} >= %{openssl_pkcs11_version}
%endif
# See https://bugzilla.redhat.com/show_bug.cgi?id=1825812
# RHEL 8.3+ and Fedora 32+ have 2.1
+2
View File
@@ -50,6 +50,8 @@ dist_app_DATA = \
bind.named.conf.template \
bind.openssl.cnf.template \
bind.openssl.cryptopolicy.cnf.template \
bind.openssl.provider.cnf.template \
bind.openssl.provider.crp.cnf.template \
certmap.conf.template \
kdc.conf.template \
kdc_extensions.template \
@@ -0,0 +1,19 @@
# OpenSSL configuration file
# File generated by IPA instalation
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
pkcs11 = pkcs11_bind_sect
[default_sect]
activate = 1
[pkcs11_bind_sect]
pkcs11-module-path = $SOFTHSM_MODULE
pkcs11-module-token-pin = file:$SOFTHSM_PIN
activate = 1
@@ -0,0 +1,25 @@
# OpenSSL configuration file
# File generated by IPA instalation
openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_configuration
providers = provider_sect
[ssl_configuration]
system_default = crypto_policy
[crypto_policy]
.include $CRYPTO_POLICY_FILE
[provider_sect]
default = default_sect
pkcs11 = pkcs11_bind_sect
[default_sect]
activate = 1
[pkcs11_bind_sect]
pkcs11-module-path = $SOFTHSM_MODULE
pkcs11-module-token-pin = file:$SOFTHSM_PIN
activate = 1
+1
View File
@@ -123,6 +123,7 @@ class BaseConstantsNamespace:
NAMED_DATA_DIR = "data/"
NAMED_OPTIONS_VAR = "OPTIONS"
NAMED_OPENSSL_ENGINE = None
NAMED_OPENSSL_PROVIDER = None
NAMED_ZONE_COMMENT = ""
NOBODY_GROUP = Group("nobody")
PKI_USER = User("pkiuser")
+8 -1
View File
@@ -19,6 +19,10 @@ from ipaplatform.osinfo import osinfo
# Fedora 29 has both
HAS_NFS_CONF = osinfo.version_number >= (30,)
# Fedora 40 and later deprecated OpenSSL engine and recommend using OpenSSL
# provider API. However, only bind 9.18 in F42+ was built with OpenSSL provider.
HAS_OPENSSL_PROVIDER = osinfo.version_number >= (42,)
__all__ = ("constants", "User", "Group")
@@ -32,6 +36,9 @@ class FedoraConstantsNamespace(RedHatConstantsNamespace):
if HAS_NFS_CONF:
SECURE_NFS_VAR = None
NAMED_OPENSSL_ENGINE = "pkcs11"
if HAS_OPENSSL_PROVIDER:
NAMED_OPENSSL_PROVIDER = True
else:
NAMED_OPENSSL_ENGINE = "pkcs11"
constants = FedoraConstantsNamespace()
+6 -1
View File
@@ -18,8 +18,11 @@ from ipaplatform.osinfo import osinfo
# RHEL 8 uses /etc/nfs.conf
HAS_NFS_CONF = osinfo.version_number >= (8,)
# RHEL 9 uses pkcs11 as openssl engine
HAS_PKCS11_OPENSSL_ENGINE = osinfo.version_number >= (9,)
HAS_PKCS11_OPENSSL_ENGINE = osinfo.version_number == (9,)
# RHEL 10 and later deprecated OpenSSL engine and recommend using OpenSSL
# provider API.
HAS_OPENSSL_PROVIDER = osinfo.version_number >= (10,)
__all__ = ("constants", "User", "Group")
@@ -31,5 +34,7 @@ class RHELConstantsNamespace(RedHatConstantsNamespace):
SECURE_NFS_VAR = None
if HAS_PKCS11_OPENSSL_ENGINE:
NAMED_OPENSSL_ENGINE = "pkcs11"
if HAS_OPENSSL_PROVIDER:
NAMED_OPENSSL_PROVIDER = True
constants = RHELConstantsNamespace()
+18 -9
View File
@@ -68,7 +68,7 @@ class BINDMgr:
str_val,
ipalib.constants.LDAP_GENERALIZED_TIME_FORMAT
)
return dt.strftime(time_bindfmt).encode('utf-8')
return dt.strftime(time_bindfmt)
def dates2params(self, ldap_attrs):
"""Convert LDAP timestamps to list of parameters suitable
@@ -117,21 +117,30 @@ class BINDMgr:
"""Run dnssec-keyfromlabel on given LDAP object.
:returns: base file name of output files, e.g. Kaaa.test.+008+19719
"""
logger.info('attrs: %s', attrs)
assert attrs.get('idnsseckeyzone', [b'FALSE'])[0] == b'TRUE', \
b'object %s is not a DNS zone key' % attrs['dn']
uri = b"%s;pin-source=%s" % (
attrs['idnsSecKeyRef'][0],
paths.DNSSEC_SOFTHSM_PIN.encode('utf-8')
)
uri = None
# LDAP object entries are all in binary encoding
keyref = attrs['idnsSecKeyRef'][0].decode('utf-8')
if platformconstants.NAMED_OPENSSL_ENGINE is not None:
uri = "%s;pin-source=%s" % (
keyref,
paths.DNSSEC_SOFTHSM_PIN
)
elif platformconstants.NAMED_OPENSSL_PROVIDER is not None:
uri = "%s;token=%s" % (
keyref,
ipalib.constants.SOFTHSM_DNSSEC_TOKEN_LABEL
)
assert uri is not None
cmd = [
paths.DNSSEC_KEYFROMLABEL,
'-E', 'pkcs11',
'-K', workdir,
'-a', attrs['idnsSecAlgorithm'][0],
'-l', uri
'-a', attrs['idnsSecAlgorithm'][0].decode('utf-8'),
]
cmd.extend(['-l', uri])
cmd.extend(self.dates2params(attrs))
if attrs.get('idnsSecKeySep', [b'FALSE'])[0].upper() == b'TRUE':
cmd.extend(['-f', 'KSK'])
+43 -12
View File
@@ -155,21 +155,36 @@ class DNSKeySyncInstance(service.Service):
return False
def setup_named_openssl_conf(self):
opensslcnf_tmpl = None
conf_file_dict = {
'CRYPTO_POLICY_FILE': paths.CRYPTO_POLICY_OPENSSLCNF_FILE,
'SOFTHSM_MODULE': paths.LIBSOFTHSM2_SO,
'SOFTHSM_PIN': paths.DNSSEC_SOFTHSM_PIN,
}
if constants.NAMED_OPENSSL_ENGINE is not None:
logger.debug("Setup OpenSSL config for BIND")
# setup OpenSSL config for BIND,
# this one is needed because FreeIPA installation
# disables p11-kit-proxy PKCS11 module
conf_file_dict = {
'OPENSSL_ENGINE': constants.NAMED_OPENSSL_ENGINE,
'SOFTHSM_MODULE': paths.LIBSOFTHSM2_SO,
'CRYPTO_POLICY_FILE': paths.CRYPTO_POLICY_OPENSSLCNF_FILE,
}
# Traditional configuration using OpenSSL engine API
# requires openssl-pkcs11 engine to load PKCS#11 token
# provided by SoftHSMv2
conf_file_dict['OPENSSL_ENGINE'] = constants.NAMED_OPENSSL_ENGINE
if paths.CRYPTO_POLICY_OPENSSLCNF_FILE is None:
opensslcnf_tmpl = "bind.openssl.cnf.template"
else:
opensslcnf_tmpl = "bind.openssl.cryptopolicy.cnf.template"
elif constants.NAMED_OPENSSL_PROVIDER is not None:
# OpenSSL provider API is preferred and requires
# pkcs11-provider to load PKCS#11 token provided by SoftHSMv2
if paths.CRYPTO_POLICY_OPENSSLCNF_FILE is None:
opensslcnf_tmpl = "bind.openssl.provider.cnf.template"
else:
opensslcnf_tmpl = "bind.openssl.provider.crp.cnf.template"
else:
conf_file_dict = None
if opensslcnf_tmpl is not None and conf_file_dict is not None:
logger.debug("Setup OpenSSL config for BIND")
# setup OpenSSL config for BIND,
# this one is needed because FreeIPA installation
# disables p11-kit-proxy PKCS11 module
named_openssl_txt = ipautil.template_file(
os.path.join(paths.USR_SHARE_IPA_DIR, opensslcnf_tmpl),
conf_file_dict
@@ -189,7 +204,8 @@ class DNSKeySyncInstance(service.Service):
'SOFTHSM2_CONF', paths.DNSSEC_SOFTHSM2_CONF,
quotes=False, separator='=')
if constants.NAMED_OPENSSL_ENGINE is not None:
if any([constants.NAMED_OPENSSL_ENGINE is not None,
constants.NAMED_OPENSSL_PROVIDER is not None]):
directivesetter.set_directive(
sysconfig,
'OPENSSL_CONF', paths.DNSSEC_OPENSSL_CONF,
@@ -200,9 +216,23 @@ class DNSKeySyncInstance(service.Service):
constants.NAMED_OPTIONS_VAR,
separator="="
) or ''
if not self._are_named_options_configured(options):
new_options = None
if all([constants.NAMED_OPENSSL_ENGINE is not None,
not self._are_named_options_configured(options)]):
engine_cmd = "-E {}".format(constants.NAMED_OPENSSL_ENGINE)
new_options = ' '.join([options, engine_cmd])
# Remove '-E pkcs11' from the options in the OpenSSL provider case
if all([constants.NAMED_OPENSSL_ENGINE is None,
self._are_named_options_configured(options)]):
lst_options = options.split()
try:
idx = lst_options.index('-E')
lst_options.pop(idx)
lst_options.pop(idx)
new_options = ' '.join(lst_options)
except ValueError:
pass
if new_options is not None:
directivesetter.set_directive(
sysconfig,
constants.NAMED_OPTIONS_VAR, new_options,
@@ -216,7 +246,8 @@ class DNSKeySyncInstance(service.Service):
'SOFTHSM2_CONF', paths.DNSSEC_SOFTHSM2_CONF,
quotes=False, separator='=')
if constants.NAMED_OPENSSL_ENGINE is not None:
if any([constants.NAMED_OPENSSL_ENGINE is not None,
constants.NAMED_OPENSSL_PROVIDER is not None]):
directivesetter.set_directive(
sysconfig,
'OPENSSL_CONF', paths.DNSSEC_OPENSSL_CONF,
+8 -4
View File
@@ -549,15 +549,19 @@ def ca_initialize_hsm_state(ca):
def dnssec_set_openssl_engine(dnskeysyncd):
"""
Setup OpenSSL engine for BIND
Setup OpenSSL engine or provider for BIND
"""
if constants.NAMED_OPENSSL_ENGINE is None:
if all([constants.NAMED_OPENSSL_ENGINE is None,
constants.NAMED_OPENSSL_PROVIDER is None]):
return False
if sysupgrade.get_upgrade_state('dns', 'openssl_engine'):
# Nothing to do if we are using OpenSSL engine already and not on the OS
# that requires OpenSSL provider instead.
if all([sysupgrade.get_upgrade_state('dns', 'openssl_engine'),
constants.NAMED_OPENSSL_PROVIDER is None]):
return False
logger.info('[Set OpenSSL engine for BIND]')
logger.info('[Set OpenSSL engine or provider for BIND]')
dnskeysyncd.setup_named_openssl_conf()
dnskeysyncd.setup_named_sysconfig()
dnskeysyncd.setup_ipa_dnskeysyncd_sysconfig()