From 2a3c27aadee91cd7b179e762ef0fe99128345bd1 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 15 May 2020 16:28:32 +0200 Subject: Reload certificates daily --- debian/changelog | 1 + https.cpp | 62 ++++++++++++++++++++++++++++++++++++++++---------------- https.h | 7 ++++++- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/debian/changelog b/debian/changelog index 4e4f55c..100dda2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ webserver (1.6) UNRELEASED; urgency=medium * Webbox: Improved UI * config: Serve_sites bugfix + * Reload certificates daily -- Roland Reichwein Fri, 15 May 2020 10:29:06 +0200 diff --git a/https.cpp b/https.cpp index 6ca27f0..508ece9 100644 --- a/https.cpp +++ b/https.cpp @@ -43,6 +43,8 @@ using tcp = boost::asio::ip::tcp; // from namespace { + // reload certs once a day: may be updated by certbot + const int32_t certificates_timer_seconds { 24 * 60*60 }; //------------------------------------------------------------------------------ // Report a failure @@ -459,12 +461,6 @@ private: /* Load a signed certificate into the ssl context, and configure the context for use with a server. - - For this to work with the browser or operating system, it is - necessary to import the "Beast Test CA" certificate into - the local certificate store, browser, or operating system - depending on your environment Please see the documentation - accompanying the Beast certificate for more details. */ void load_server_certificate(boost::asio::ssl::context& ctx, fs::path cert_path, fs::path key_path) { @@ -485,13 +481,6 @@ void load_server_certificate(boost::asio::ssl::context& ctx, fs::path cert_path, "QMUk26jPTIVTLfXmmwU0u8vUkpR7LQKkwwIBAg==\n" "-----END DH PARAMETERS-----\n"; - ctx.set_password_callback( - [](std::size_t, - boost::asio::ssl::context_base::password_purpose) - { - return "test"; - }); - ctx.set_options( boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | @@ -642,6 +631,25 @@ namespace HTTPS { Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socket, plugins_container_type& plugins, Statistics& statistics) : ::Server(config, ioc, socket, plugins, statistics) + , m_certificates_timer(ioc, boost::asio::chrono::seconds(certificates_timer_seconds)) + , m_certificates_timer_callback { + [&](const boost::system::error_code& error){ + reload_certificates(); + m_certificates_timer.expires_at(m_certificates_timer.expires_at() + boost::asio::chrono::seconds(certificates_timer_seconds)); + m_certificates_timer.async_wait(m_certificates_timer_callback); + }} +{ + load_certificates(); // load initially + + // Reload certs once a day, maybe updated by certbot + m_certificates_timer.async_wait(m_certificates_timer_callback); +} + +Server::~Server() +{ +} + +void Server::load_certificates() { // initial dummy, before we can add specific ctx w/ certificate std::shared_ptr ctx_dummy{std::make_shared(tls_method)}; @@ -650,12 +658,12 @@ Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socke m_ctx.emplace("", ctx_dummy); // import the real certificates - for (const auto& serve_site: socket.serve_sites) { - for (const auto& site: config.Sites()) { + for (const auto& serve_site: m_socket.serve_sites) { + for (const auto& site: m_config.Sites()) { if (site.name == serve_site) { std::shared_ptr ctx {std::make_shared(tls_method)}; - std::cout << "Creating SSL context/cert for site " << serve_site << " on port " << socket.port << std::endl; + std::cout << "Creating SSL context/cert for site " << serve_site << " on port " << m_socket.port << std::endl; load_server_certificate(*ctx, site.cert_path, site.key_path); SSL_CTX_set_client_hello_cb(ctx->native_handle(), servername_callback, &m_ctx); @@ -669,8 +677,28 @@ Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socke } } -Server::~Server() +void Server::reload_certificates() { + for (const auto& serve_site: m_socket.serve_sites) { + for (const auto& site: m_config.Sites()) { + if (site.name == serve_site) { + + std::cout << "Updating SSL context/cert for site " << serve_site << " on port " << m_socket.port << std::endl; + + auto it_host {site.hosts.begin()}; + if (it_host == site.hosts.end()) { + std::cout << " Warning: No configured host found." << std::endl; + } else { + auto it_ctx {m_ctx.find(*it_host)}; + if (it_ctx == m_ctx.end()) { + std::cout << " Warning: No context found for configured host." << std::endl; + } else { + load_server_certificate(*it_ctx->second, site.cert_path, site.key_path); + } + } + } + } + } } int Server::start() diff --git a/https.h b/https.h index 738e122..e87fc6d 100644 --- a/https.h +++ b/https.h @@ -38,11 +38,16 @@ public: private: ctx_type m_ctx; - + boost::asio::steady_timer m_certificates_timer; + std::function m_certificates_timer_callback; + public: Server(Config& config, boost::asio::io_context& ioc, const Socket& socket, plugins_container_type& plugins, Statistics& statistics); virtual ~Server(); + void load_certificates(); + void reload_certificates(); + int start() override; }; -- cgit v1.2.3