From f63b364d91e7f784cf33f653d80861bc1ca7d6b9 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 30 Mar 2022 18:38:57 +0200 Subject: [PATCH] Renew certificates also periodically --- lib/base/tlsutility.cpp | 4 ++-- lib/base/tlsutility.hpp | 5 +++++ lib/remote/apilistener.cpp | 22 ++++++++++++++-------- lib/remote/apilistener.hpp | 1 + lib/remote/jsonrpcconnection-pki.cpp | 11 +++++++++++ 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/base/tlsutility.cpp b/lib/base/tlsutility.cpp index df0f872b4..e022621e4 100644 --- a/lib/base/tlsutility.cpp +++ b/lib/base/tlsutility.cpp @@ -623,7 +623,7 @@ std::shared_ptr CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME X509 *cert = X509_new(); X509_set_version(cert, 2); X509_gmtime_adj(X509_get_notBefore(cert), 0); - X509_gmtime_adj(X509_get_notAfter(cert), (ca ? 15 * 365 : 397) * 24 * 60 * 60); + X509_gmtime_adj(X509_get_notAfter(cert), ca ? ROOT_VALID_FOR : LEAF_VALID_FOR); X509_set_pubkey(cert, pubkey); X509_set_subject_name(cert, subject); @@ -761,7 +761,7 @@ bool IsCertUptodate(const std::shared_ptr& cert) * because Icinga versions older than 2.4 sometimes create certificates with an invalid * serial number. */ time_t forceRenewalEnd = 1483228800; /* January 1st, 2017 */ - time_t renewalStart = now + 30 * 24 * 60 * 60; + time_t renewalStart = now + RENEW_THRESHOLD; return X509_cmp_time(X509_get_notBefore(cert.get()), &forceRenewalEnd) != -1 && X509_cmp_time(X509_get_notAfter(cert.get()), &renewalStart) != -1; } diff --git a/lib/base/tlsutility.hpp b/lib/base/tlsutility.hpp index 6ed84add5..3b8a89c5e 100644 --- a/lib/base/tlsutility.hpp +++ b/lib/base/tlsutility.hpp @@ -30,6 +30,11 @@ const char * const DEFAULT_TLS_CIPHERS = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RS const char * const DEFAULT_TLS_PROTOCOLMIN = "TLSv1.2"; const unsigned int DEFAULT_CONNECT_TIMEOUT = 15; +const auto ROOT_VALID_FOR = 60 * 60 * 24 * 365 * 15; +const auto LEAF_VALID_FOR = 60 * 60 * 24 * 397; +const auto RENEW_THRESHOLD = 60 * 60 * 24 * 30; +const auto RENEW_INTERVAL = 60 * 60 * 24; + void InitializeOpenSSL(); String GetOpenSSLVersion(); diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index aad862c6f..7234bd12c 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -235,7 +235,20 @@ void ApiListener::Start(bool runtimeCreated) << "'" << GetName() << "' started."; SyncLocalZoneDirs(); - RenewOwnCert(); + + m_RenewOwnCertTimer = new Timer(); + + if (Utility::PathExists(GetIcingaCADir() + "/ca.key")) { + RenewOwnCert(); + m_RenewOwnCertTimer->OnTimerExpired.connect([this](const Timer * const&) { RenewOwnCert(); }); + } else { + m_RenewOwnCertTimer->OnTimerExpired.connect([this](const Timer * const&) { + JsonRpcConnection::SendCertificateRequest(nullptr, nullptr, String()); + }); + } + + m_RenewOwnCertTimer->SetInterval(RENEW_INTERVAL); + m_RenewOwnCertTimer->Start(); ObjectImpl::Start(runtimeCreated); @@ -288,10 +301,6 @@ void ApiListener::Start(bool runtimeCreated) void ApiListener::RenewOwnCert() { - if (!Utility::PathExists(GetIcingaCADir() + "/ca.key")) { - return; - } - auto certPath (GetDefaultCertPath()); auto cert (GetX509Certificate(certPath)); @@ -832,9 +841,6 @@ void ApiListener::SyncClient(const JsonRpcConnection::Ptr& aclient, const Endpoi auto parent (myZone->GetParent()); if (parent == eZone || !parent && eZone == myZone) { - Log(LogInformation, "ApiListener") - << "Requesting new certificate for this Icinga instance from endpoint '" << endpoint->GetName() << "'."; - JsonRpcConnection::SendCertificateRequest(aclient, nullptr, String()); if (Utility::PathExists(ApiListener::GetCertificateRequestsDir())) { diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 960f75431..d5e6ffe8c 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -171,6 +171,7 @@ private: Timer::Ptr m_AuthorityTimer; Timer::Ptr m_CleanupCertificateRequestsTimer; Timer::Ptr m_ApiPackageIntegrityTimer; + Timer::Ptr m_RenewOwnCertTimer; Endpoint::Ptr m_LocalEndpoint; diff --git a/lib/remote/jsonrpcconnection-pki.cpp b/lib/remote/jsonrpcconnection-pki.cpp index 7b7c63f3b..8ab58f416 100644 --- a/lib/remote/jsonrpcconnection-pki.cpp +++ b/lib/remote/jsonrpcconnection-pki.cpp @@ -265,6 +265,17 @@ void JsonRpcConnection::SendCertificateRequest(const JsonRpcConnection::Ptr& acl /* Path is empty if this is our own request. */ if (path.IsEmpty()) { + { + Log msg (LogInformation, "JsonRpcConnection"); + msg << "Requesting new certificate for this Icinga instance"; + + if (aclient) { + msg << " from endpoint '" << aclient->GetIdentity() << "'"; + } + + msg << "."; + } + String ticketPath = ApiListener::GetCertsDir() + "/ticket"; std::ifstream fp(ticketPath.CStr());