diff --git a/doc/09-object-types.md b/doc/09-object-types.md
index 19e796aff..4ee242019 100644
--- a/doc/09-object-types.md
+++ b/doc/09-object-types.md
@@ -1410,6 +1410,14 @@ Configuration Attributes:
port | Number | **Optional.** Redis port for IcingaDB. Defaults to `6380`.
path | String | **Optional.** Redix unix socket path. Can be used instead of `host` and `port` attributes.
password | String | **Optional.** Redis auth password for IcingaDB.
+ enable\_tls | Boolean | **Optional.** Whether to use TLS.
+ cert\_path | String | **Optional.** Path to the certificate.
+ key\_path | String | **Optional.** Path to the private key.
+ ca\_path | String | **Optional.** Path to the CA certificate to use instead of the system's root CAs.
+ crl\_path | String | **Optional.** Path to the CRL file.
+ cipher\_list | String | **Optional.** Cipher list that is allowed. For a list of available ciphers run `openssl ciphers`. Defaults to `ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384:AES128-GCM-SHA256`.
+ tls\_protocolmin | String | **Optional.** Minimum TLS protocol version. Defaults to `TLSv1.2`.
+ insecure\_noverify | Boolean | **Optional.** Whether not to verify the peer.
### IdoMySqlConnection
diff --git a/lib/base/tlsutility.cpp b/lib/base/tlsutility.cpp
index 40e2d1767..02d677ee0 100644
--- a/lib/base/tlsutility.cpp
+++ b/lib/base/tlsutility.cpp
@@ -70,7 +70,7 @@ void InitializeOpenSSL()
l_SSLInitialized = true;
}
-static void SetupSslContext(const Shared::Ptr& context, const String& pubkey, const String& privkey, const String& cakey)
+static void InitSslContext(const Shared::Ptr& context, const String& pubkey, const String& privkey, const String& cakey)
{
char errbuf[256];
@@ -137,7 +137,16 @@ static void SetupSslContext(const Shared::Ptr& contex
}
}
- if (!cakey.IsEmpty()) {
+ if (cakey.IsEmpty()) {
+ if (!SSL_CTX_set_default_verify_paths(sslContext)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
+ Log(LogCritical, "SSL")
+ << "Error loading system's root CAs: " << ERR_peek_error() << ", \"" << errbuf << "\"";
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << boost::errinfo_api_function("SSL_CTX_set_default_verify_paths")
+ << errinfo_openssl_error(ERR_peek_error()));
+ }
+ } else {
if (!SSL_CTX_load_verify_locations(sslContext, cakey.CStr(), nullptr)) {
ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
@@ -181,7 +190,7 @@ Shared::Ptr MakeAsioSslContext(const String& pubkey,
auto context (Shared::Make(ssl::context::tls));
- SetupSslContext(context, pubkey, privkey, cakey);
+ InitSslContext(context, pubkey, privkey, cakey);
return context;
}
@@ -249,6 +258,49 @@ int ResolveTlsProtocolVersion(const std::string& version) {
}
}
+Shared::Ptr SetupSslContext(String certPath, String keyPath,
+ String caPath, String crlPath, String cipherList, String protocolmin, DebugInfo di)
+{
+ namespace ssl = boost::asio::ssl;
+
+ Shared::Ptr context;
+
+ try {
+ context = MakeAsioSslContext(certPath, keyPath, caPath);
+ } catch (const std::exception&) {
+ BOOST_THROW_EXCEPTION(ScriptError("Cannot make SSL context for cert path: '"
+ + certPath + "' key path: '" + keyPath + "' ca path: '" + caPath + "'.", di));
+ }
+
+ if (!crlPath.IsEmpty()) {
+ try {
+ AddCRLToSSLContext(context, crlPath);
+ } catch (const std::exception&) {
+ BOOST_THROW_EXCEPTION(ScriptError("Cannot add certificate revocation list to SSL context for crl path: '"
+ + crlPath + "'.", di));
+ }
+ }
+
+ if (!cipherList.IsEmpty()) {
+ try {
+ SetCipherListToSSLContext(context, cipherList);
+ } catch (const std::exception&) {
+ BOOST_THROW_EXCEPTION(ScriptError("Cannot set cipher list to SSL context for cipher list: '"
+ + cipherList + "'.", di));
+ }
+ }
+
+ if (!protocolmin.IsEmpty()){
+ try {
+ SetTlsProtocolminToSSLContext(context, protocolmin);
+ } catch (const std::exception&) {
+ BOOST_THROW_EXCEPTION(ScriptError("Cannot set minimum TLS protocol version to SSL context with tls_protocolmin: '" + protocolmin + "'.", di));
+ }
+ }
+
+ return std::move(context);
+}
+
/**
* Set the minimum TLS protocol version to the specified SSL context.
*
diff --git a/lib/base/tlsutility.hpp b/lib/base/tlsutility.hpp
index 2493ff279..0bc1a8332 100644
--- a/lib/base/tlsutility.hpp
+++ b/lib/base/tlsutility.hpp
@@ -4,6 +4,7 @@
#define TLSUTILITY_H
#include "base/i2-base.hpp"
+#include "base/debuginfo.hpp"
#include "base/object.hpp"
#include "base/shared.hpp"
#include "base/array.hpp"
@@ -24,6 +25,10 @@
namespace icinga
{
+const char * const DEFAULT_TLS_CIPHERS = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384:AES128-GCM-SHA256";
+
+const char * const DEFAULT_TLS_PROTOCOLMIN = "TLSv1.2";
+
void InitializeOpenSSL();
String GetOpenSSLVersion();
@@ -35,6 +40,9 @@ void SetCipherListToSSLContext(const Shared::Ptr& con
void SetTlsProtocolminToSSLContext(const Shared::Ptr& context, const String& tlsProtocolmin);
int ResolveTlsProtocolVersion(const std::string& version);
+Shared::Ptr SetupSslContext(String certPath, String keyPath,
+ String caPath, String crlPath, String cipherList, String protocolmin, DebugInfo di);
+
String GetCertificateCN(const std::shared_ptr& certificate);
std::shared_ptr GetX509Certificate(const String& pemfile);
int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), bool ca = false);
diff --git a/lib/icingadb/icingadb.cpp b/lib/icingadb/icingadb.cpp
index 7b05364d1..0fac021fc 100644
--- a/lib/icingadb/icingadb.cpp
+++ b/lib/icingadb/icingadb.cpp
@@ -33,6 +33,18 @@ IcingaDB::IcingaDB()
m_PrefixConfigCheckSum = "icinga:checksum:";
}
+void IcingaDB::Validate(int types, const ValidationUtils& utils)
+{
+ ObjectImpl::Validate(types, utils);
+
+ if (!(types & FAConfig))
+ return;
+
+ if (GetEnableTls() && GetCertPath().IsEmpty() != GetKeyPath().IsEmpty()) {
+ BOOST_THROW_EXCEPTION(ValidationError(this, std::vector(), "Validation failed: Either both a client certificate (cert_path) and its private key (key_path) or none of them must be given."));
+ }
+}
+
/**
* Starts the component.
*/
@@ -52,7 +64,9 @@ void IcingaDB::Start(bool runtimeCreated)
m_WorkQueue.SetExceptionCallback([this](boost::exception_ptr exp) { ExceptionHandler(std::move(exp)); });
- m_Rcon = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex());
+ m_Rcon = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(),
+ GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(),
+ GetTlsProtocolmin(), GetCipherList(), GetDebugInfo());
m_Rcon->SetConnectedCallback([this](boost::asio::yield_context& yc) {
m_WorkQueue.Enqueue([this]() { OnConnectedHandler(); });
});
@@ -63,7 +77,9 @@ void IcingaDB::Start(bool runtimeCreated)
if (!ctype)
continue;
- RedisConnection::Ptr rCon (new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(), m_Rcon));
+ RedisConnection::Ptr rCon (new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(),
+ GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(),
+ GetTlsProtocolmin(), GetCipherList(), GetDebugInfo(), m_Rcon));
rCon->Start();
m_Rcons[ctype] = std::move(rCon);
}
@@ -140,6 +156,17 @@ void IcingaDB::Stop(bool runtimeRemoved)
ObjectImpl::Stop(runtimeRemoved);
}
+void IcingaDB::ValidateTlsProtocolmin(const Lazy& lvalue, const ValidationUtils& utils)
+{
+ ObjectImpl::ValidateTlsProtocolmin(lvalue, utils);
+
+ try {
+ ResolveTlsProtocolVersion(lvalue());
+ } catch (const std::exception& ex) {
+ BOOST_THROW_EXCEPTION(ValidationError(this, { "tls_protocolmin" }, ex.what()));
+ }
+}
+
void IcingaDB::AssertOnWorkQueue()
{
ASSERT(m_WorkQueue.IsWorkerThread());
diff --git a/lib/icingadb/icingadb.hpp b/lib/icingadb/icingadb.hpp
index 964b837b9..07ed75904 100644
--- a/lib/icingadb/icingadb.hpp
+++ b/lib/icingadb/icingadb.hpp
@@ -35,9 +35,13 @@ public:
static void ConfigStaticInitialize();
+ void Validate(int types, const ValidationUtils& utils) override;
virtual void Start(bool runtimeCreated) override;
virtual void Stop(bool runtimeRemoved) override;
+protected:
+ void ValidateTlsProtocolmin(const Lazy& lvalue, const ValidationUtils& utils) override;
+
private:
class DumpedGlobals
{
diff --git a/lib/icingadb/icingadb.ti b/lib/icingadb/icingadb.ti
index ebc69e8a6..35299573b 100644
--- a/lib/icingadb/icingadb.ti
+++ b/lib/icingadb/icingadb.ti
@@ -1,6 +1,7 @@
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
#include "base/configobject.hpp"
+#include "base/tlsutility.hpp"
library icingadb;
@@ -20,6 +21,25 @@ class IcingaDB : ConfigObject
[config] String path;
[config, no_user_view, no_user_modify] String password;
[config] int db_index;
+
+ [config] bool enable_tls {
+ default {{{ return false; }}}
+ };
+
+ [config] bool insecure_noverify {
+ default {{{ return false; }}}
+ };
+
+ [config] String cert_path;
+ [config] String key_path;
+ [config] String ca_path;
+ [config] String crl_path;
+ [config] String cipher_list {
+ default {{{ return DEFAULT_TLS_CIPHERS; }}}
+ };
+ [config] String tls_protocolmin {
+ default {{{ return DEFAULT_TLS_PROTOCOLMIN; }}}
+ };
};
}
diff --git a/lib/icingadb/redisconnection.cpp b/lib/icingadb/redisconnection.cpp
index ee1ede89d..9ccdf5d7f 100644
--- a/lib/icingadb/redisconnection.cpp
+++ b/lib/icingadb/redisconnection.cpp
@@ -4,11 +4,13 @@
#include "base/array.hpp"
#include "base/convert.hpp"
#include "base/defer.hpp"
+#include "base/exception.hpp"
#include "base/io-engine.hpp"
#include "base/logger.hpp"
#include "base/objectlock.hpp"
#include "base/string.hpp"
#include "base/tcpsocket.hpp"
+#include "base/tlsutility.hpp"
#include "base/utility.hpp"
#include
#include
@@ -19,23 +21,39 @@
#include
#include
#include
+#include
+#include
#include
using namespace icinga;
namespace asio = boost::asio;
-RedisConnection::RedisConnection(const String& host, const int port, const String& path,
- const String& password, const int db, const RedisConnection::Ptr& parent) :
- RedisConnection(IoEngine::Get().GetIoContext(), host, port, path, password, db, parent)
+RedisConnection::RedisConnection(const String& host, int port, const String& path, const String& password, int db,
+ bool useTls, bool insecure, const String& certPath, const String& keyPath, const String& caPath, const String& crlPath,
+ const String& tlsProtocolmin, const String& cipherList, DebugInfo di, const RedisConnection::Ptr& parent)
+ : RedisConnection(IoEngine::Get().GetIoContext(), host, port, path, password, db,
+ useTls, insecure, certPath, keyPath, caPath, crlPath, tlsProtocolmin, cipherList, std::move(di), parent)
{
}
-RedisConnection::RedisConnection(boost::asio::io_context& io, String host, int port, String path,
- String password, int db, const RedisConnection::Ptr& parent)
- : m_Host(std::move(host)), m_Port(port), m_Path(std::move(path)), m_Password(std::move(password)), m_DbIndex(db),
- m_Connecting(false), m_Connected(false), m_Started(false), m_Strand(io),
- m_QueuedWrites(io), m_QueuedReads(io), m_LogStatsTimer(io), m_Parent(parent)
+RedisConnection::RedisConnection(boost::asio::io_context& io, String host, int port, String path, String password,
+ int db, bool useTls, bool insecure, String certPath, String keyPath, String caPath, String crlPath,
+ String tlsProtocolmin, String cipherList, DebugInfo di, const RedisConnection::Ptr& parent)
+ : m_Host(std::move(host)), m_Port(port), m_Path(std::move(path)), m_Password(std::move(password)),
+ m_DbIndex(db), m_CertPath(std::move(certPath)), m_KeyPath(std::move(keyPath)), m_Insecure(insecure),
+ m_CaPath(std::move(caPath)), m_CrlPath(std::move(crlPath)), m_TlsProtocolmin(std::move(tlsProtocolmin)),
+ m_CipherList(std::move(cipherList)), m_DebugInfo(std::move(di)), m_Connecting(false), m_Connected(false),
+ m_Started(false), m_Strand(io), m_QueuedWrites(io), m_QueuedReads(io), m_LogStatsTimer(io), m_Parent(parent)
{
+ if (useTls && m_Path.IsEmpty()) {
+ UpdateTLSContext();
+ }
+}
+
+void RedisConnection::UpdateTLSContext()
+{
+ m_TLSContext = SetupSslContext(m_CertPath, m_KeyPath, m_CaPath,
+ m_CrlPath, m_CipherList, m_TlsProtocolmin, m_DebugInfo);
}
void RedisConnection::Start()
@@ -245,12 +263,48 @@ void RedisConnection::Connect(asio::yield_context& yc)
for (;;) {
try {
if (m_Path.IsEmpty()) {
- Log(m_Parent ? LogNotice : LogInformation, "IcingaDB")
- << "Trying to connect to Redis server (async) on host '" << m_Host << ":" << m_Port << "'";
+ if (m_TLSContext) {
+ Log(m_Parent ? LogNotice : LogInformation, "IcingaDB")
+ << "Trying to connect to Redis server (async, TLS) on host '" << m_Host << ":" << m_Port << "'";
- auto conn (Shared::Make(m_Strand.context()));
- icinga::Connect(conn->next_layer(), m_Host, Convert::ToString(m_Port), yc);
- m_TcpConn = std::move(conn);
+ auto conn (Shared::Make(m_Strand.context(), *m_TLSContext, m_Host));
+ auto& tlsConn (conn->next_layer());
+
+ if (!m_Insecure) {
+ auto native (tlsConn.native_handle());
+
+ X509_VERIFY_PARAM_set1_host(SSL_get0_param(native), m_Host.CStr(), 0);
+ SSL_set_verify(native, SSL_VERIFY_PEER, NULL);
+ }
+
+ icinga::Connect(conn->lowest_layer(), m_Host, Convert::ToString(m_Port), yc);
+ tlsConn.async_handshake(tlsConn.client, yc);
+
+ if (!m_Insecure) {
+ std::shared_ptr cert (tlsConn.GetPeerCertificate());
+
+ if (!cert) {
+ BOOST_THROW_EXCEPTION(std::runtime_error(
+ "Redis didn't present any TLS certificate."
+ ));
+ }
+
+ if (!tlsConn.IsVerifyOK()) {
+ BOOST_THROW_EXCEPTION(std::runtime_error(
+ "TLS certificate validation failed: " + std::string(tlsConn.GetVerifyError())
+ ));
+ }
+ }
+
+ m_TlsConn = std::move(conn);
+ } else {
+ Log(m_Parent ? LogNotice : LogInformation, "IcingaDB")
+ << "Trying to connect to Redis server (async) on host '" << m_Host << ":" << m_Port << "'";
+
+ auto conn (Shared::Make(m_Strand.context()));
+ icinga::Connect(conn->next_layer(), m_Host, Convert::ToString(m_Port), yc);
+ m_TcpConn = std::move(conn);
+ }
} else {
Log(LogInformation, "IcingaDB")
<< "Trying to connect to Redis server (async) on unix socket path '" << m_Path << "'";
@@ -560,7 +614,11 @@ void RedisConnection::WriteItem(boost::asio::yield_context& yc, RedisConnection:
RedisConnection::Reply RedisConnection::ReadOne(boost::asio::yield_context& yc)
{
if (m_Path.IsEmpty()) {
- return ReadOne(m_TcpConn, yc);
+ if (m_TLSContext) {
+ return ReadOne(m_TlsConn, yc);
+ } else {
+ return ReadOne(m_TcpConn, yc);
+ }
} else {
return ReadOne(m_UnixConn, yc);
}
@@ -574,7 +632,11 @@ RedisConnection::Reply RedisConnection::ReadOne(boost::asio::yield_context& yc)
void RedisConnection::WriteOne(RedisConnection::Query& query, asio::yield_context& yc)
{
if (m_Path.IsEmpty()) {
- WriteOne(m_TcpConn, query, yc);
+ if (m_TLSContext) {
+ WriteOne(m_TlsConn, query, yc);
+ } else {
+ WriteOne(m_TcpConn, query, yc);
+ }
} else {
WriteOne(m_UnixConn, query, yc);
}
diff --git a/lib/icingadb/redisconnection.hpp b/lib/icingadb/redisconnection.hpp
index 9c7aaa880..57d6b63c3 100644
--- a/lib/icingadb/redisconnection.hpp
+++ b/lib/icingadb/redisconnection.hpp
@@ -10,6 +10,7 @@
#include "base/ringbuffer.hpp"
#include "base/shared.hpp"
#include "base/string.hpp"
+#include "base/tlsstream.hpp"
#include "base/value.hpp"
#include
#include
@@ -20,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -69,8 +71,11 @@ namespace icinga
SyncConnection = 255
};
- RedisConnection(const String& host, const int port, const String& path,
- const String& password = "", const int db = 0, const Ptr& parent = nullptr);
+ RedisConnection(const String& host, int port, const String& path, const String& password, int db,
+ bool useTls, bool insecure, const String& certPath, const String& keyPath, const String& caPath, const String& crlPath,
+ const String& tlsProtocolmin, const String& cipherList, DebugInfo di, const Ptr& parent = nullptr);
+
+ void UpdateTLSContext();
void Start();
@@ -134,6 +139,8 @@ namespace icinga
typedef boost::asio::buffered_stream TcpConn;
typedef boost::asio::buffered_stream UnixConn;
+ Shared::Ptr m_TLSContext;
+
template
static Value ReadRESP(AsyncReadStream& stream, boost::asio::yield_context& yc);
@@ -143,8 +150,9 @@ namespace icinga
template
static void WriteRESP(AsyncWriteStream& stream, const Query& query, boost::asio::yield_context& yc);
- RedisConnection(boost::asio::io_context& io, String host, int port, String path,
- String password, int db, const Ptr& parent);
+ RedisConnection(boost::asio::io_context& io, String host, int port, String path, String password,
+ int db, bool useTls, bool insecure, String certPath, String keyPath, String caPath, String crlPath,
+ String tlsProtocolmin, String cipherList, DebugInfo di, const Ptr& parent);
void Connect(boost::asio::yield_context& yc);
void ReadLoop(boost::asio::yield_context& yc);
@@ -169,9 +177,19 @@ namespace icinga
String m_Password;
int m_DbIndex;
+ String m_CertPath;
+ String m_KeyPath;
+ bool m_Insecure;
+ String m_CaPath;
+ String m_CrlPath;
+ String m_TlsProtocolmin;
+ String m_CipherList;
+ DebugInfo m_DebugInfo;
+
boost::asio::io_context::strand m_Strand;
Shared::Ptr m_TcpConn;
Shared::Ptr m_UnixConn;
+ Shared::Ptr m_TlsConn;
Atomic m_Connecting, m_Connected, m_Started;
struct {
diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp
index fcf902cfa..45dc69131 100644
--- a/lib/remote/apilistener.cpp
+++ b/lib/remote/apilistener.cpp
@@ -181,44 +181,7 @@ void ApiListener::OnConfigLoaded()
void ApiListener::UpdateSSLContext()
{
- namespace ssl = boost::asio::ssl;
-
- Shared::Ptr context;
-
- try {
- context = MakeAsioSslContext(GetDefaultCertPath(), GetDefaultKeyPath(), GetDefaultCaPath());
- } catch (const std::exception&) {
- BOOST_THROW_EXCEPTION(ScriptError("Cannot make SSL context for cert path: '"
- + GetDefaultCertPath() + "' key path: '" + GetDefaultKeyPath() + "' ca path: '" + GetDefaultCaPath() + "'.", GetDebugInfo()));
- }
-
- if (!GetCrlPath().IsEmpty()) {
- try {
- AddCRLToSSLContext(context, GetCrlPath());
- } catch (const std::exception&) {
- BOOST_THROW_EXCEPTION(ScriptError("Cannot add certificate revocation list to SSL context for crl path: '"
- + GetCrlPath() + "'.", GetDebugInfo()));
- }
- }
-
- if (!GetCipherList().IsEmpty()) {
- try {
- SetCipherListToSSLContext(context, GetCipherList());
- } catch (const std::exception&) {
- BOOST_THROW_EXCEPTION(ScriptError("Cannot set cipher list to SSL context for cipher list: '"
- + GetCipherList() + "'.", GetDebugInfo()));
- }
- }
-
- if (!GetTlsProtocolmin().IsEmpty()){
- try {
- SetTlsProtocolminToSSLContext(context, GetTlsProtocolmin());
- } catch (const std::exception&) {
- BOOST_THROW_EXCEPTION(ScriptError("Cannot set minimum TLS protocol version to SSL context with tls_protocolmin: '" + GetTlsProtocolmin() + "'.", GetDebugInfo()));
- }
- }
-
- m_SSLContext = context;
+ m_SSLContext = SetupSslContext(GetDefaultCertPath(), GetDefaultKeyPath(), GetDefaultCaPath(), GetCrlPath(), GetCipherList(), GetTlsProtocolmin(), GetDebugInfo());
for (const Endpoint::Ptr& endpoint : ConfigType::GetObjectsByType()) {
for (const JsonRpcConnection::Ptr& client : endpoint->GetClients()) {
diff --git a/lib/remote/apilistener.ti b/lib/remote/apilistener.ti
index fa0ad395b..d62402b6e 100644
--- a/lib/remote/apilistener.ti
+++ b/lib/remote/apilistener.ti
@@ -3,6 +3,7 @@
#include "remote/i2-remote.hpp"
#include "base/configobject.hpp"
#include "base/application.hpp"
+#include "base/tlsutility.hpp"
library remote;
@@ -18,10 +19,10 @@ class ApiListener : ConfigObject
[config, deprecated] String ca_path;
[config] String crl_path;
[config] String cipher_list {
- default {{{ return "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384:AES128-GCM-SHA256"; }}}
+ default {{{ return DEFAULT_TLS_CIPHERS; }}}
};
[config] String tls_protocolmin {
- default {{{ return "TLSv1.2"; }}}
+ default {{{ return DEFAULT_TLS_PROTOCOLMIN; }}}
};
[config] String bind_host {