Generate TLS certificates with validity time in the past
Otherwise a slight clock skew may prevent them from working, see e.g. https://bugzilla.redhat.com/show_bug.cgi?id=1906448. Change-Id: Icea103af06edef16c0dc4578877dc04cd6ec3b0c
This commit is contained in:
parent
1a9491e651
commit
557293ca6a
@ -72,6 +72,11 @@ cli_opts = [
|
|||||||
'is False and ironic API version indicates support for '
|
'is False and ironic API version indicates support for '
|
||||||
'automatic agent TLS.'),
|
'automatic agent TLS.'),
|
||||||
|
|
||||||
|
cfg.IntOpt('auto_tls_allowed_clock_skew',
|
||||||
|
default=3600, min=0,
|
||||||
|
help='Clock skew (in seconds) allowed in the generated TLS '
|
||||||
|
'certificate.'),
|
||||||
|
|
||||||
cfg.StrOpt('advertise_host',
|
cfg.StrOpt('advertise_host',
|
||||||
default=APARAMS.get('ipa-advertise-host', None),
|
default=APARAMS.get('ipa-advertise-host', None),
|
||||||
help='The host to tell Ironic to reply and send '
|
help='The host to tell Ironic to reply and send '
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import datetime
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -36,6 +37,7 @@ class GenerateTestCase(ironic_agent_base.IronicAgentTest):
|
|||||||
result = tls_utils._generate_tls_certificate(self.crt_file,
|
result = tls_utils._generate_tls_certificate(self.crt_file,
|
||||||
self.key_file,
|
self.key_file,
|
||||||
'localhost', '127.0.0.1')
|
'localhost', '127.0.0.1')
|
||||||
|
now = datetime.datetime.utcnow()
|
||||||
self.assertTrue(result.startswith("-----BEGIN CERTIFICATE-----\n"),
|
self.assertTrue(result.startswith("-----BEGIN CERTIFICATE-----\n"),
|
||||||
result)
|
result)
|
||||||
self.assertTrue(result.endswith("\n-----END CERTIFICATE-----\n"),
|
self.assertTrue(result.endswith("\n-----END CERTIFICATE-----\n"),
|
||||||
@ -48,6 +50,11 @@ class GenerateTestCase(ironic_agent_base.IronicAgentTest):
|
|||||||
backends.default_backend())
|
backends.default_backend())
|
||||||
self.assertEqual([(x509.NameOID.COMMON_NAME, 'localhost')],
|
self.assertEqual([(x509.NameOID.COMMON_NAME, 'localhost')],
|
||||||
[(item.oid, item.value) for item in cert.subject])
|
[(item.oid, item.value) for item in cert.subject])
|
||||||
|
# Sanity check for validity range
|
||||||
|
self.assertLess(cert.not_valid_before,
|
||||||
|
now - datetime.timedelta(seconds=1800))
|
||||||
|
self.assertGreater(cert.not_valid_after,
|
||||||
|
now + datetime.timedelta(seconds=1800))
|
||||||
subject_alt_name = cert.extensions.get_extension_for_oid(
|
subject_alt_name = cert.extensions.get_extension_for_oid(
|
||||||
x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
|
x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
|
||||||
self.assertTrue(subject_alt_name.critical)
|
self.assertTrue(subject_alt_name.critical)
|
||||||
|
@ -22,10 +22,16 @@ from cryptography.hazmat.primitives.asymmetric import ec
|
|||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
from cryptography import x509
|
from cryptography import x509
|
||||||
|
from oslo_log import log
|
||||||
|
|
||||||
|
from ironic_python_agent import config
|
||||||
from ironic_python_agent import netutils
|
from ironic_python_agent import netutils
|
||||||
|
|
||||||
|
|
||||||
|
LOG = log.getLogger()
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
def _create_private_key(output):
|
def _create_private_key(output):
|
||||||
"""Create a new private key and write it to a file.
|
"""Create a new private key and write it to a file.
|
||||||
|
|
||||||
@ -70,19 +76,25 @@ def _generate_tls_certificate(output, private_key_output,
|
|||||||
x509.NameAttribute(x509.NameOID.COMMON_NAME, common_name),
|
x509.NameAttribute(x509.NameOID.COMMON_NAME, common_name),
|
||||||
])
|
])
|
||||||
alt_name = x509.SubjectAlternativeName([x509.IPAddress(ip_address)])
|
alt_name = x509.SubjectAlternativeName([x509.IPAddress(ip_address)])
|
||||||
|
allowed_clock_skew = CONF.auto_tls_allowed_clock_skew
|
||||||
|
not_valid_before = (datetime.datetime.utcnow()
|
||||||
|
- datetime.timedelta(seconds=allowed_clock_skew))
|
||||||
|
not_valid_after = (datetime.datetime.utcnow()
|
||||||
|
+ datetime.timedelta(days=valid_for_days))
|
||||||
cert = (x509.CertificateBuilder()
|
cert = (x509.CertificateBuilder()
|
||||||
.subject_name(subject)
|
.subject_name(subject)
|
||||||
.issuer_name(subject)
|
.issuer_name(subject)
|
||||||
.public_key(private_key.public_key())
|
.public_key(private_key.public_key())
|
||||||
.serial_number(x509.random_serial_number())
|
.serial_number(x509.random_serial_number())
|
||||||
.not_valid_before(datetime.datetime.utcnow())
|
.not_valid_before(not_valid_before)
|
||||||
.not_valid_after(datetime.datetime.utcnow()
|
.not_valid_after(not_valid_after)
|
||||||
+ datetime.timedelta(days=valid_for_days))
|
|
||||||
.add_extension(alt_name, critical=True)
|
.add_extension(alt_name, critical=True)
|
||||||
.sign(private_key, hashes.SHA256(), backends.default_backend()))
|
.sign(private_key, hashes.SHA256(), backends.default_backend()))
|
||||||
pub_bytes = cert.public_bytes(serialization.Encoding.PEM)
|
pub_bytes = cert.public_bytes(serialization.Encoding.PEM)
|
||||||
with open(output, "wb") as f:
|
with open(output, "wb") as f:
|
||||||
f.write(pub_bytes)
|
f.write(pub_bytes)
|
||||||
|
LOG.info('Generated TLS certificate for IP address %s valid from %s '
|
||||||
|
'to %s', ip_address, not_valid_before, not_valid_after)
|
||||||
return pub_bytes.decode('utf-8')
|
return pub_bytes.decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
5
releasenotes/notes/clock-skew-1fbf542b193cec17.yaml
Normal file
5
releasenotes/notes/clock-skew-1fbf542b193cec17.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Automatically generated TLS certificates now have their validity starting
|
||||||
|
in the past (1 hour by default) to allow for clock skew.
|
Loading…
Reference in New Issue
Block a user