mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-08 17:05:25 +02:00
Merge pull request from GHSA-cxfm-8j5v-5qr2
Add TLS server certificate validation to ElasticsearchWriter, GelfWriter, InfluxdbWriter and Influxdb2Writer (v2)
This commit is contained in:
commit
9cafabcc9c
13
CHANGELOG.md
13
CHANGELOG.md
@ -9,7 +9,18 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
|
|||||||
|
|
||||||
## 2.13.1 (2021-08-19)
|
## 2.13.1 (2021-08-19)
|
||||||
|
|
||||||
Version 2.13.1 fixes two issues indroduced with the 2.13.0 release.
|
The main focus of this version is a security vulnerability in the TLS certificate verification of our metrics writers ElasticsearchWriter, GelfWriter, InfluxdbWriter and Influxdb2Writer.
|
||||||
|
|
||||||
|
Version 2.13.1 also fixes two issues indroduced with the 2.13.0 release.
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
* Add TLS server certificate validation to ElasticsearchWriter, GelfWriter, InfluxdbWriter and Influxdb2Writer ([GHSA-cxfm-8j5v-5qr2](https://github.com/Icinga/icinga2/security/advisories/GHSA-cxfm-8j5v-5qr2))
|
||||||
|
|
||||||
|
Depending on your setup, manual intervention beyond installing the new versions
|
||||||
|
may be required, so please read the more detailed information in the
|
||||||
|
[release blog post](https://icinga.com/blog/2021/08/19/icinga-2-13-1-security-release//)
|
||||||
|
carefully
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
|
@ -1238,6 +1238,7 @@ Configuration Attributes:
|
|||||||
username | String | **Optional.** Basic auth username if Elasticsearch is hidden behind an HTTP proxy.
|
username | String | **Optional.** Basic auth username if Elasticsearch is hidden behind an HTTP proxy.
|
||||||
password | String | **Optional.** Basic auth password if Elasticsearch is hidden behind an HTTP proxy.
|
password | String | **Optional.** Basic auth password if Elasticsearch is hidden behind an HTTP proxy.
|
||||||
enable\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`. Requires an HTTP proxy.
|
enable\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`. Requires an HTTP proxy.
|
||||||
|
insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification.
|
||||||
ca\_path | String | **Optional.** Path to CA certificate to validate the remote host. Requires `enable_tls` set to `true`.
|
ca\_path | String | **Optional.** Path to CA certificate to validate the remote host. Requires `enable_tls` set to `true`.
|
||||||
cert\_path | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. Requires `enable_tls` set to `true`.
|
cert\_path | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. Requires `enable_tls` set to `true`.
|
||||||
key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`.
|
key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`.
|
||||||
@ -1325,6 +1326,7 @@ Configuration Attributes:
|
|||||||
enable\_send\_perfdata | Boolean | **Optional.** Enable performance data for 'CHECK RESULT' events.
|
enable\_send\_perfdata | Boolean | **Optional.** Enable performance data for 'CHECK RESULT' events.
|
||||||
enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`.
|
enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`.
|
||||||
enable\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
enable\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
||||||
|
insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification.
|
||||||
ca\_path | String | **Optional.** Path to CA certificate to validate the remote host. Requires `enable_tls` set to `true`.
|
ca\_path | String | **Optional.** Path to CA certificate to validate the remote host. Requires `enable_tls` set to `true`.
|
||||||
cert\_path | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. Requires `enable_tls` set to `true`.
|
cert\_path | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. Requires `enable_tls` set to `true`.
|
||||||
key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`.
|
key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`.
|
||||||
@ -1662,6 +1664,7 @@ Configuration Attributes:
|
|||||||
password | String | **Optional.** InfluxDB user password. Defaults to `none`.
|
password | String | **Optional.** InfluxDB user password. Defaults to `none`.
|
||||||
basic\_auth | Dictionary | **Optional.** Username and password for HTTP basic authentication.
|
basic\_auth | Dictionary | **Optional.** Username and password for HTTP basic authentication.
|
||||||
ssl\_enable | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
ssl\_enable | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
||||||
|
ssl\_insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification.
|
||||||
ssl\_ca\_cert | String | **Optional.** Path to CA certificate to validate the remote host.
|
ssl\_ca\_cert | String | **Optional.** Path to CA certificate to validate the remote host.
|
||||||
ssl\_cert | String | **Optional.** Path to host certificate to present to the remote host for mutual verification.
|
ssl\_cert | String | **Optional.** Path to host certificate to present to the remote host for mutual verification.
|
||||||
ssl\_key | String | **Optional.** Path to host key to accompany the ssl\_cert.
|
ssl\_key | String | **Optional.** Path to host key to accompany the ssl\_cert.
|
||||||
@ -1724,6 +1727,7 @@ Configuration Attributes:
|
|||||||
bucket | String | **Required.** InfluxDB bucket name.
|
bucket | String | **Required.** InfluxDB bucket name.
|
||||||
auth\_token | String | **Required.** InfluxDB authentication token.
|
auth\_token | String | **Required.** InfluxDB authentication token.
|
||||||
ssl\_enable | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
ssl\_enable | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
||||||
|
ssl\_insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification.
|
||||||
ssl\_ca\_cert | String | **Optional.** Path to CA certificate to validate the remote host.
|
ssl\_ca\_cert | String | **Optional.** Path to CA certificate to validate the remote host.
|
||||||
ssl\_cert | String | **Optional.** Path to host certificate to present to the remote host for mutual verification.
|
ssl\_cert | String | **Optional.** Path to host certificate to present to the remote host for mutual verification.
|
||||||
ssl\_key | String | **Optional.** Path to host key to accompany the ssl\_cert.
|
ssl\_key | String | **Optional.** Path to host key to accompany the ssl\_cert.
|
||||||
|
@ -37,6 +37,10 @@ void UnbufferedAsioTlsStream::BeforeHandshake(handshake_type type)
|
|||||||
{
|
{
|
||||||
namespace ssl = boost::asio::ssl;
|
namespace ssl = boost::asio::ssl;
|
||||||
|
|
||||||
|
if (!m_Hostname.IsEmpty()) {
|
||||||
|
X509_VERIFY_PARAM_set1_host(SSL_get0_param(native_handle()), m_Hostname.CStr(), m_Hostname.GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
set_verify_mode(ssl::verify_peer | ssl::verify_client_once);
|
set_verify_mode(ssl::verify_peer | ssl::verify_client_once);
|
||||||
|
|
||||||
set_verify_callback([this](bool preverified, ssl::verify_context& ctx) {
|
set_verify_callback([this](bool preverified, ssl::verify_context& ctx) {
|
||||||
|
@ -274,13 +274,6 @@ void RedisConnection::Connect(asio::yield_context& yc)
|
|||||||
auto connectTimeout (MakeTimeout(conn));
|
auto connectTimeout (MakeTimeout(conn));
|
||||||
Defer cancelTimeout ([&connectTimeout]() { connectTimeout->Cancel(); });
|
Defer cancelTimeout ([&connectTimeout]() { connectTimeout->Cancel(); });
|
||||||
|
|
||||||
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);
|
icinga::Connect(conn->lowest_layer(), m_Host, Convert::ToString(m_Port), yc);
|
||||||
tlsConn.async_handshake(tlsConn.client, yc);
|
tlsConn.async_handshake(tlsConn.client, yc);
|
||||||
|
|
||||||
|
@ -632,6 +632,18 @@ OptionalTlsStream ElasticsearchWriter::Connect()
|
|||||||
<< "TLS handshake with host '" << GetHost() << "' on port " << GetPort() << " failed.";
|
<< "TLS handshake with host '" << GetHost() << "' on port " << GetPort() << " failed.";
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GetInsecureNoverify()) {
|
||||||
|
if (!tlsStream.GetPeerCertificate()) {
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error("Elasticsearch didn't present any TLS certificate."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tlsStream.IsVerifyOK()) {
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error(
|
||||||
|
"TLS certificate validation failed: " + std::string(tlsStream.GetVerifyError())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(stream);
|
return std::move(stream);
|
||||||
|
@ -29,6 +29,9 @@ class ElasticsearchWriter : ConfigObject
|
|||||||
[config] bool enable_tls {
|
[config] bool enable_tls {
|
||||||
default {{{ return false; }}}
|
default {{{ return false; }}}
|
||||||
};
|
};
|
||||||
|
[config] bool insecure_noverify {
|
||||||
|
default {{{ return false; }}}
|
||||||
|
};
|
||||||
[config] String ca_path;
|
[config] String ca_path;
|
||||||
[config] String cert_path;
|
[config] String cert_path;
|
||||||
[config] String key_path;
|
[config] String key_path;
|
||||||
|
@ -135,10 +135,8 @@ void GelfWriter::AssertOnWorkQueue()
|
|||||||
|
|
||||||
void GelfWriter::ExceptionHandler(boost::exception_ptr exp)
|
void GelfWriter::ExceptionHandler(boost::exception_ptr exp)
|
||||||
{
|
{
|
||||||
Log(LogCritical, "GelfWriter", "Exception during Graylog Gelf operation: Verify that your backend is operational!");
|
Log(LogCritical, "GelfWriter") << "Exception during Graylog Gelf operation: " << DiagnosticInformation(exp, false);
|
||||||
|
Log(LogDebug, "GelfWriter") << "Exception during Graylog Gelf operation: " << DiagnosticInformation(exp, true);
|
||||||
Log(LogDebug, "GelfWriter")
|
|
||||||
<< "Exception during Graylog Gelf operation: " << DiagnosticInformation(std::move(exp));
|
|
||||||
|
|
||||||
DisconnectInternal();
|
DisconnectInternal();
|
||||||
}
|
}
|
||||||
@ -206,6 +204,18 @@ void GelfWriter::ReconnectInternal()
|
|||||||
<< "TLS handshake with host '" << GetHost() << " failed.'";
|
<< "TLS handshake with host '" << GetHost() << " failed.'";
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GetInsecureNoverify()) {
|
||||||
|
if (!tlsStream.GetPeerCertificate()) {
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error("Graylog Gelf didn't present any TLS certificate."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tlsStream.IsVerifyOK()) {
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error(
|
||||||
|
"TLS certificate validation failed: " + std::string(tlsStream.GetVerifyError())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConnected(true);
|
SetConnected(true);
|
||||||
|
@ -34,6 +34,9 @@ class GelfWriter : ConfigObject
|
|||||||
[config] bool enable_tls {
|
[config] bool enable_tls {
|
||||||
default {{{ return false; }}}
|
default {{{ return false; }}}
|
||||||
};
|
};
|
||||||
|
[config] bool insecure_noverify {
|
||||||
|
default {{{ return false; }}}
|
||||||
|
};
|
||||||
[config] String ca_path;
|
[config] String ca_path;
|
||||||
[config] String cert_path;
|
[config] String cert_path;
|
||||||
[config] String key_path;
|
[config] String key_path;
|
||||||
|
@ -187,6 +187,18 @@ OptionalTlsStream InfluxdbCommonWriter::Connect()
|
|||||||
<< "TLS handshake with host '" << GetHost() << "' failed.";
|
<< "TLS handshake with host '" << GetHost() << "' failed.";
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GetSslInsecureNoverify()) {
|
||||||
|
if (!tlsStream.GetPeerCertificate()) {
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error("InfluxDB didn't present any TLS certificate."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tlsStream.IsVerifyOK()) {
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error(
|
||||||
|
"TLS certificate validation failed: " + std::string(tlsStream.GetVerifyError())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(stream);
|
return std::move(stream);
|
||||||
|
@ -18,6 +18,9 @@ abstract class InfluxdbCommonWriter : ConfigObject
|
|||||||
[config] bool ssl_enable {
|
[config] bool ssl_enable {
|
||||||
default {{{ return false; }}}
|
default {{{ return false; }}}
|
||||||
};
|
};
|
||||||
|
[config] bool ssl_insecure_noverify {
|
||||||
|
default {{{ return false; }}}
|
||||||
|
};
|
||||||
[config] String ssl_ca_cert {
|
[config] String ssl_ca_cert {
|
||||||
default {{{ return ""; }}}
|
default {{{ return ""; }}}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user