mirror of https://github.com/Icinga/icinga2.git
Icinga DB: Support Redis username authentication
The Redis ACL system was introduced with Redis 6.0. It introduced users with precisely granular permissions. This change allows Icinga 2 to use the Icinga DB feature against a Redis with an ACL user. This was reflected in the documentation, next to the already implemented, but undocumented Redis database. Closes #9536.
This commit is contained in:
parent
57fab7f39e
commit
98f60fd78e
|
@ -1387,6 +1387,7 @@ Configuration Attributes:
|
|||
host | String | **Optional.** Redis host. Defaults to `127.0.0.1`.
|
||||
port | Number | **Optional.** Redis port. Defaults to `6380` since the Redis server provided by the `icingadb-redis` package listens on that port.
|
||||
path | String | **Optional.** Redis unix socket path. Can be used instead of `host` and `port` attributes.
|
||||
username | String | **Optional.** Redis auth username. Only possible if Redis ACLs are used. Requires `password` to be set as well.
|
||||
password | String | **Optional.** Redis auth password.
|
||||
db\_index | Number | **Optional.** Redis logical database by its number. Defaults to `0`.
|
||||
enable\_tls | Boolean | **Optional.** Whether to use TLS.
|
||||
|
|
|
@ -47,6 +47,11 @@ void IcingaDB::Validate(int types, const ValidationUtils& utils)
|
|||
if (!(types & FAConfig))
|
||||
return;
|
||||
|
||||
if (!GetUsername().IsEmpty() && GetPassword().IsEmpty()) {
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, std::vector<String>(),
|
||||
"Redis password must be set, if username is provided."));
|
||||
}
|
||||
|
||||
if (GetEnableTls() && GetCertPath().IsEmpty() != GetKeyPath().IsEmpty()) {
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, std::vector<String>(), "Validation failed: Either both a client certificate (cert_path) and its private key (key_path) or none of them must be given."));
|
||||
}
|
||||
|
@ -77,7 +82,7 @@ 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(), GetUsername(), GetPassword(), GetDbIndex(),
|
||||
GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(),
|
||||
GetTlsProtocolmin(), GetCipherList(), GetConnectTimeout(), GetDebugInfo());
|
||||
m_RconLocked.store(m_Rcon);
|
||||
|
@ -87,7 +92,7 @@ void IcingaDB::Start(bool runtimeCreated)
|
|||
if (!ctype)
|
||||
continue;
|
||||
|
||||
RedisConnection::Ptr con = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(),
|
||||
RedisConnection::Ptr con = new RedisConnection(GetHost(), GetPort(), GetPath(), GetUsername(), GetPassword(), GetDbIndex(),
|
||||
GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(),
|
||||
GetTlsProtocolmin(), GetCipherList(), GetConnectTimeout(), GetDebugInfo(), m_Rcon);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ class IcingaDB : ConfigObject
|
|||
default {{{ return 6380; }}}
|
||||
};
|
||||
[config, no_user_modify] String path;
|
||||
[config, no_user_modify] String username;
|
||||
[config, no_user_view, no_user_modify] String password;
|
||||
[config, no_user_modify] int db_index;
|
||||
|
||||
|
|
|
@ -30,18 +30,18 @@ namespace asio = boost::asio;
|
|||
|
||||
boost::regex RedisConnection::m_ErrAuth ("\\AERR AUTH ");
|
||||
|
||||
RedisConnection::RedisConnection(const String& host, int port, const String& path, const String& password, int db,
|
||||
RedisConnection::RedisConnection(const String& host, int port, const String& path, const String& username, 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, double connectTimeout, DebugInfo di, const RedisConnection::Ptr& parent)
|
||||
: RedisConnection(IoEngine::Get().GetIoContext(), host, port, path, password, db,
|
||||
: RedisConnection(IoEngine::Get().GetIoContext(), host, port, path, username, password, db,
|
||||
useTls, insecure, certPath, keyPath, caPath, crlPath, tlsProtocolmin, cipherList, connectTimeout, std::move(di), parent)
|
||||
{
|
||||
}
|
||||
|
||||
RedisConnection::RedisConnection(boost::asio::io_context& io, String host, int port, String path, String password,
|
||||
RedisConnection::RedisConnection(boost::asio::io_context& io, String host, int port, String path, String username, String password,
|
||||
int db, bool useTls, bool insecure, String certPath, String keyPath, String caPath, String crlPath,
|
||||
String tlsProtocolmin, String cipherList, double connectTimeout, 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_Host(std::move(host)), m_Port(port), m_Path(std::move(path)), m_Username(std::move(username)), 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_ConnectTimeout(connectTimeout), m_DebugInfo(std::move(di)), m_Connecting(false), m_Connected(false),
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace icinga
|
|||
: Config(config), State(state), History(history) { }
|
||||
};
|
||||
|
||||
RedisConnection(const String& host, int port, const String& path, const String& password, int db,
|
||||
RedisConnection(const String& host, int port, const String& path, const String& username, 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, double connectTimeout, DebugInfo di, const Ptr& parent = nullptr);
|
||||
|
||||
|
@ -196,7 +196,7 @@ namespace icinga
|
|||
|
||||
static boost::regex m_ErrAuth;
|
||||
|
||||
RedisConnection(boost::asio::io_context& io, String host, int port, String path, String password,
|
||||
RedisConnection(boost::asio::io_context& io, String host, int port, String path, String username, String password,
|
||||
int db, bool useTls, bool insecure, String certPath, String keyPath, String caPath, String crlPath,
|
||||
String tlsProtocolmin, String cipherList, double connectTimeout, DebugInfo di, const Ptr& parent);
|
||||
|
||||
|
@ -227,6 +227,7 @@ namespace icinga
|
|||
String m_Path;
|
||||
String m_Host;
|
||||
int m_Port;
|
||||
String m_Username;
|
||||
String m_Password;
|
||||
int m_DbIndex;
|
||||
|
||||
|
@ -457,7 +458,9 @@ void RedisConnection::Handshake(StreamPtr& strm, boost::asio::yield_context& yc)
|
|||
// Trigger NOAUTH
|
||||
WriteRESP(*strm, {"PING"}, yc);
|
||||
} else {
|
||||
if (!m_Password.IsEmpty()) {
|
||||
if (!m_Username.IsEmpty()) {
|
||||
WriteRESP(*strm, {"AUTH", m_Username, m_Password}, yc);
|
||||
} else if (!m_Password.IsEmpty()) {
|
||||
WriteRESP(*strm, {"AUTH", m_Password}, yc);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue