mirror of https://github.com/Icinga/icinga2.git
Merge pull request #6813 from Icinga/feature/gelfwriter-tls-support
Implement TLS support for the GelfWriter feature
This commit is contained in:
commit
5d0af5c879
|
@ -1344,7 +1344,10 @@ Configuration Attributes:
|
|||
source | String | **Optional.** Source name for this instance. Defaults to `icinga2`.
|
||||
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\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`.
|
||||
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`.
|
||||
key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`.
|
||||
|
||||
### GraphiteWriter <a id="objecttype-graphitewriter"></a>
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#include "base/statsfunction.hpp"
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <utility>
|
||||
#include "base/io-engine.hpp"
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/asio/error.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -126,11 +131,7 @@ void GelfWriter::ExceptionHandler(boost::exception_ptr exp)
|
|||
Log(LogDebug, "GelfWriter")
|
||||
<< "Exception during Graylog Gelf operation: " << DiagnosticInformation(std::move(exp));
|
||||
|
||||
if (GetConnected()) {
|
||||
m_Stream->Close();
|
||||
|
||||
SetConnected(false);
|
||||
}
|
||||
DisconnectInternal();
|
||||
}
|
||||
|
||||
void GelfWriter::Reconnect()
|
||||
|
@ -156,20 +157,46 @@ void GelfWriter::ReconnectInternal()
|
|||
if (GetConnected())
|
||||
return;
|
||||
|
||||
TcpSocket::Ptr socket = new TcpSocket();
|
||||
|
||||
Log(LogNotice, "GelfWriter")
|
||||
<< "Reconnecting to Graylog Gelf on host '" << GetHost() << "' port '" << GetPort() << "'.";
|
||||
|
||||
try {
|
||||
socket->Connect(GetHost(), GetPort());
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "GelfWriter")
|
||||
<< "Can't connect to Graylog Gelf on host '" << GetHost() << "' port '" << GetPort() << "'.";
|
||||
throw ex;
|
||||
bool ssl = GetEnableTls();
|
||||
|
||||
if (ssl) {
|
||||
std::shared_ptr<boost::asio::ssl::context> sslContext;
|
||||
|
||||
try {
|
||||
sslContext = MakeAsioSslContext(GetCertPath(), GetKeyPath(), GetCaPath());
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogWarning, "GelfWriter")
|
||||
<< "Unable to create SSL context.";
|
||||
throw;
|
||||
}
|
||||
|
||||
m_Stream.first = std::make_shared<AsioTlsStream>(IoEngine::Get().GetIoService(), *sslContext, GetHost());
|
||||
} else {
|
||||
m_Stream.second = std::make_shared<AsioTcpStream>(IoEngine::Get().GetIoService());
|
||||
}
|
||||
|
||||
m_Stream = new NetworkStream(socket);
|
||||
try {
|
||||
icinga::Connect(ssl ? m_Stream.first->lowest_layer() : m_Stream.second->lowest_layer(), GetHost(), GetPort());
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogWarning, "GelfWriter")
|
||||
<< "Can't connect to Graylog Gelf on host '" << GetHost() << "' port '" << GetPort() << ".'";
|
||||
throw;
|
||||
}
|
||||
|
||||
if (ssl) {
|
||||
auto& tlsStream (m_Stream.first->next_layer());
|
||||
|
||||
try {
|
||||
tlsStream.handshake(tlsStream.client);
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogWarning, "GelfWriter")
|
||||
<< "TLS handshake with host '" << GetHost() << " failed.'";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
SetConnected(true);
|
||||
|
||||
|
@ -194,9 +221,22 @@ void GelfWriter::DisconnectInternal()
|
|||
if (!GetConnected())
|
||||
return;
|
||||
|
||||
m_Stream->Close();
|
||||
if (m_Stream.first) {
|
||||
boost::system::error_code ec;
|
||||
m_Stream.first->next_layer().shutdown(ec);
|
||||
|
||||
// https://stackoverflow.com/a/25703699
|
||||
// As long as the error code's category is not an SSL category, then the protocol was securely shutdown
|
||||
if (ec.category() == boost::asio::error::get_ssl_category()) {
|
||||
Log(LogCritical, "GelfWriter")
|
||||
<< "TLS shutdown with host '" << GetHost() << "' could not be done securely.";
|
||||
}
|
||||
} else if (m_Stream.second) {
|
||||
m_Stream.second->close();
|
||||
}
|
||||
|
||||
SetConnected(false);
|
||||
|
||||
}
|
||||
|
||||
void GelfWriter::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr)
|
||||
|
@ -456,7 +496,13 @@ void GelfWriter::SendLogMessage(const Checkable::Ptr& checkable, const String& g
|
|||
Log(LogDebug, "GelfWriter")
|
||||
<< "Checkable '" << checkable->GetName() << "' sending message '" << log << "'.";
|
||||
|
||||
m_Stream->Write(log.CStr(), log.GetLength());
|
||||
if (m_Stream.first) {
|
||||
boost::asio::write(*m_Stream.first, boost::asio::buffer(msgbuf.str()));
|
||||
m_Stream.first->flush();
|
||||
} else {
|
||||
boost::asio::write(*m_Stream.second, boost::asio::buffer(msgbuf.str()));
|
||||
m_Stream.second->flush();
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "GelfWriter")
|
||||
<< "Cannot write to TCP socket on host '" << GetHost() << "' port '" << GetPort() << "'.";
|
||||
|
|
|
@ -33,7 +33,7 @@ protected:
|
|||
void Pause() override;
|
||||
|
||||
private:
|
||||
Stream::Ptr m_Stream;
|
||||
OptionalTlsStream m_Stream;
|
||||
WorkQueue m_WorkQueue{10000000, 1};
|
||||
|
||||
Timer::Ptr m_ReconnectTimer;
|
||||
|
|
|
@ -31,6 +31,12 @@ class GelfWriter : ConfigObject
|
|||
[config] bool enable_ha {
|
||||
default {{{ return false; }}}
|
||||
};
|
||||
[config] bool enable_tls {
|
||||
default {{{ return false; }}}
|
||||
};
|
||||
[config] String ca_path;
|
||||
[config] String cert_path;
|
||||
[config] String key_path;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue