mirror of https://github.com/Icinga/icinga2.git
Merge pull request #5682 from Icinga/feature/cert-migration
Implement support for migrating certificates to /var/lib/icinga2/certs
This commit is contained in:
commit
a5b949bec2
|
@ -175,11 +175,11 @@ By default Icinga 2 uses the following files and directories:
|
|||
/usr/lib\*/icinga2 | Libraries and the Icinga 2 binary (use `find /usr -type f -name icinga2` to locate the binary path).
|
||||
/usr/share/doc/icinga2 | Documentation files that come with Icinga 2.
|
||||
/usr/share/icinga2/include | The Icinga Template Library and plugin command configuration.
|
||||
/var/lib/icinga2 | Icinga 2 state file, cluster log, master CA, node certificates and configuration files (cluster, api).
|
||||
/var/run/icinga2 | PID file.
|
||||
/var/run/icinga2/cmd | Command pipe and Livestatus socket.
|
||||
/var/cache/icinga2 | status.dat/objects.cache, icinga2.debug files
|
||||
/var/spool/icinga2 | Used for performance data spool files.
|
||||
/var/lib/icinga2 | Icinga 2 state file, cluster log, local CA and configuration files (cluster, api).
|
||||
/var/log/icinga2 | Log file location and compat/ directory for the CompatLogger feature.
|
||||
|
||||
FreeBSD uses slightly different paths:
|
||||
|
@ -194,11 +194,11 @@ By default Icinga 2 uses the following files and directories:
|
|||
/usr/local/lib/icinga2 | Libraries and the Icinga 2 binary.
|
||||
/usr/local/share/doc/icinga2 | Documentation files that come with Icinga 2.
|
||||
/usr/local/share/icinga2/include | The Icinga Template Library and plugin command configuration.
|
||||
/var/lib/icinga2 | Icinga 2 state file, cluster log, master CA, node certificates and configuration files (cluster, api).
|
||||
/var/run/icinga2 | PID file.
|
||||
/var/run/icinga2/cmd | Command pipe and Livestatus socket.
|
||||
/var/cache/icinga2 | status.dat/objects.cache, icinga2.debug files
|
||||
/var/spool/icinga2 | Used for performance data spool files.
|
||||
/var/lib/icinga2 | Icinga 2 state file, cluster log, local CA and configuration files (cluster, api).
|
||||
/var/log/icinga2 | Log file location and compat/ directory for the CompatLogger feature.
|
||||
|
||||
## Setting up Check Plugins <a id="setting-up-check-plugins"></a>
|
||||
|
@ -877,5 +877,6 @@ popular addons is available in the
|
|||
Ensure to include the following in your backups:
|
||||
|
||||
* Configuration files in `/etc/icinga2`
|
||||
* Runtime files in `/var/lib/icinga2` (the master's CA is stored here as well)
|
||||
* Certificate files in `/var/lib/icinga2/ca` (Master CA key pair) and `/var/lib/icinga2/certs` (node certificates)
|
||||
* Runtime files in `/var/lib/icinga2`
|
||||
* Optional: IDO database backup
|
||||
|
|
|
@ -553,6 +553,11 @@ The setup wizard will ensure that the following steps are taken:
|
|||
|
||||
You can verify that the certificate files are stored in the `/var/lib/icinga2/certs` directory.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The certificate location changed in v2.8 to `/var/lib/icinga2/certs`. Please read the [upgrading chapter](16-upgrading-icinga-2.md#upgrading-to-2-8-certificate-paths)
|
||||
> for more details.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> If the client is not directly connected to the certificate signing master,
|
||||
|
@ -2358,6 +2363,11 @@ Sign the CSR with the previously created CA:
|
|||
|
||||
[root@icinga2-master1.localdomain /root]# icinga2 pki sign-csr --csr icinga2-master1.localdomain.csr --cert icinga2-master1.localdomain
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The certificate location changed in v2.8 to `/var/lib/icinga2/certs`. Please read the [upgrading chapter](16-upgrading-icinga-2.md#upgrading-to-2-8-certificate-paths)
|
||||
> for more details.
|
||||
|
||||
Copy the host's certificate files and the public CA certificate to `/var/lib/icinga2/certs`:
|
||||
|
||||
[root@icinga2-master1.localdomain /root]# mkdir -p /var/lib/icinga2/certs
|
||||
|
@ -2444,7 +2454,12 @@ host/port you can specify it like this:
|
|||
|
||||
#### Node Setup with Satellites/Clients <a id="distributed-monitoring-automation-cli-node-setup-satellite-client"></a>
|
||||
|
||||
Make sure that the `/var/lib/icinga2/certs` exists and is owned by the `icinga`
|
||||
> **Note**
|
||||
>
|
||||
> The certificate location changed in v2.8 to `/var/lib/icinga2/certs`. Please read the [upgrading chapter](16-upgrading-icinga-2.md#upgrading-to-2-8-certificate-paths)
|
||||
> for more details.
|
||||
|
||||
Make sure that the `/var/lib/icinga2/certs` directory exists and is owned by the `icinga`
|
||||
user (or the user Icinga 2 is running as).
|
||||
|
||||
[root@icinga2-client1.localdomain /]# mkdir -p /var/lib/icinga2/certs
|
||||
|
@ -2499,7 +2514,7 @@ Pass the following details to the `node setup` CLI command:
|
|||
Accept config | **Optional.** Whether this node accepts configuration sync from the master node (required for [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)).
|
||||
Accept commands | **Optional.** Whether this node accepts command execution messages from the master node (required for [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint)).
|
||||
|
||||
Example:
|
||||
Example for Icinga 2 v2.8:
|
||||
|
||||
[root@icinga2-client1.localdomain /]# icinga2 node setup --ticket ead2d570e18c78abf285d6b85524970a0f69c22d \
|
||||
--cn icinga2-client1.localdomain \
|
||||
|
|
|
@ -41,9 +41,8 @@ Example:
|
|||
|
||||
```
|
||||
object ApiListener "api" {
|
||||
cert_path = LocalStateDir + "/lib/icinga2/certs/" + NodeName + ".crt"
|
||||
key_path = LocalStateDir + "/lib/icinga2/certs/" + NodeName + ".key"
|
||||
ca_path = LocalStateDir + "/lib/icinga2/certs/ca.crt"
|
||||
accept_commands = true
|
||||
accept_config = true
|
||||
|
||||
ticket_salt = TicketSalt
|
||||
}
|
||||
|
@ -53,9 +52,9 @@ Configuration Attributes:
|
|||
|
||||
Name | Type | Description
|
||||
--------------------------------------|-----------------------|----------------------------------
|
||||
cert\_path | String | **Required.** Path to the public key.
|
||||
key\_path | String | **Required.** Path to the private key.
|
||||
ca\_path | String | **Required.** Path to the CA certificate file.
|
||||
cert\_path | String | **Deprecated.** Path to the public key.
|
||||
key\_path | String | **Deprecated.** Path to the private key.
|
||||
ca\_path | String | **Deprecated.** Path to the CA certificate file.
|
||||
ticket\_salt | String | **Optional.** Private key for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing). **Required** for a signing master instance.
|
||||
crl\_path | String | **Optional.** Path to the CRL file.
|
||||
bind\_host | String | **Optional.** The IP address the api listener should be bound to. Defaults to `0.0.0.0`.
|
||||
|
@ -69,6 +68,20 @@ Configuration Attributes:
|
|||
access\_control\_allow\_headers | String | **Optional.** Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. Defaults to `Authorization`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Headers)
|
||||
access\_control\_allow\_methods | String | **Optional.** Used in response to a preflight request to indicate which HTTP methods can be used when making the actual request. Defaults to `GET, POST, PUT, DELETE`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Methods)
|
||||
|
||||
The ApiListener type expects its certificate files to be in the following locations:
|
||||
|
||||
Type | Location
|
||||
---------------------|-------------------------------------
|
||||
Private key | `LocalStateDir + "/lib/icinga2/certs/" + NodeName + ".key"`
|
||||
Certificate file | `LocalStateDir + "/lib/icinga2/certs/" + NodeName + ".crt"`
|
||||
CA certificate file | `LocalStateDir + "/lib/icinga2/certs/ca.crt"`
|
||||
|
||||
If the deprecated attributes `cert_path`, `key_path` and/or `ca_path` are specified Icinga 2
|
||||
copies those files to the new location in `LocalStateDir + "/lib/icinga2/certs"` unless the
|
||||
file(s) there are newer.
|
||||
|
||||
Please check the [upgrading chapter](16-upgrading-icinga-2.md#upgrading-to-2-8-certificate-paths) for more details.
|
||||
|
||||
## ApiUser <a id="objecttype-apiuser"></a>
|
||||
|
||||
ApiUser objects are used for authentication against the [Icinga 2 API](12-icinga2-api.md#icinga2-api-authentication).
|
||||
|
|
|
@ -10,19 +10,103 @@ are scheme updates for the IDO database.
|
|||
The default certificate path was changed from `/etc/icinga2/pki` to
|
||||
`/var/lib/icinga2/certs`.
|
||||
|
||||
Old Path | New Path
|
||||
---------------------------------------------------|---------------------------------------------------
|
||||
`/etc/icinga2/pki/icinga2-client1.localdomain.crt` | `/var/lib/icinga2/certs/icinga2-client1.localdomain.crt`
|
||||
`/etc/icinga2/pki/icinga2-client1.localdomain.key` | `/var/lib/icinga2/certs/icinga2-client1.localdomain.key`
|
||||
`/etc/icinga2/pki/ca.crt` | `/var/lib/icinga2/certs/ca.crt`
|
||||
|
||||
This applies to Windows clients in the same way: `%ProgramData%\etc\icinga2\pki`
|
||||
was moved to `%ProgramData%`\var\lib\icinga2\certs`.
|
||||
was moved to `%ProgramData%\var\lib\icinga2\certs`.
|
||||
|
||||
Old Path | New Path
|
||||
----------------------------------------------------------------|----------------------------------------------------------------
|
||||
`%ProgramData%\etc\icinga2\pki\icinga2-client1.localdomain.crt` | `%ProgramData%\var\lib\icinga2\certs\icinga2-client1.localdomain.crt`
|
||||
`%ProgramData%\etc\icinga2\pki\icinga2-client1.localdomain.key` | `%ProgramData%\var\lib\icinga2\certs\icinga2-client1.localdomain.key`
|
||||
`%ProgramData%\etc\icinga2\pki\ca.crt` | `%ProgramData%\var\lib\icinga2\certs\ca.crt`
|
||||
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The default expected path for client certificates is `/var/lib/icinga2/certs/ + NodeName + {.crt,.key}`.
|
||||
> The `NodeName` constant is usually the FQDN and certificate common name (CN). Check the [conventions](06-distributed-monitoring.md#distributed-monitoring-conventions)
|
||||
> section inside the Distributed Monitoring chapter.
|
||||
|
||||
The [setup CLI commands](06-distributed-monitoring.md#distributed-monitoring-setup-master) and the
|
||||
default [ApiListener configuration](06-distributed-monitoring.md#distributed-monitoring-apilistener)
|
||||
have been adjusted to these paths too.
|
||||
|
||||
The [ApiListener](09-object-types.md#objecttype-apilistener) object attributes `cert_path`, `key_path`
|
||||
and `ca_path` have been deprecated and removed from the example configuration.
|
||||
|
||||
#### Migration Path <a id="upgrading-to-2-8-certificate-paths-migration-path"></a>
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Icinga 2 automatically migrates the certificates to the new default location if they
|
||||
> are configured and detected in `/etc/icinga2/pki`.
|
||||
|
||||
During startup, the migration kicks in and ensures to copy the certificates to the new
|
||||
location. This will also happen if someone updates the certificate files in `/etc/icinga2/pki`
|
||||
to ensure that the new certificate location always has the latest files.
|
||||
|
||||
This has been implemented in the Icinga 2 binary to ensure it works on both Linux/Unix
|
||||
and the Windows platform.
|
||||
|
||||
If you are not using the built-in CLI commands and setup wizards to deploy the client certificates,
|
||||
please ensure to update your deployment tools/scripts. This mainly affects
|
||||
|
||||
* Puppet modules
|
||||
* Ansible playbooks
|
||||
* Chef cookbooks
|
||||
* Salt recipes
|
||||
* Custom scripts, e.g. Windows Powershell or self-made implementations
|
||||
|
||||
In order to support a smooth migration between versions older than 2.8 and future releases,
|
||||
the built-in certificate migration path is planned to exist as long as the deprecated
|
||||
`ApiListener` object attributes exist.
|
||||
|
||||
You are safe to use the existing configuration paths inside the `api` feature. If you plan your migration,
|
||||
look at the following example taken from the Director Linux deployment script for clients.
|
||||
|
||||
* Ensure that the default certificate path is changed from `/etc/icinga2/pki` to `/var/lib/icinga2/certs`.
|
||||
|
||||
```
|
||||
-ICINGA2_SSL_DIR="${ICINGA2_CONF_DIR}/pki"
|
||||
+ICINGA2_SSL_DIR="${ICINGA2_STATE_DIR}/lib/icinga2/certs"
|
||||
```
|
||||
|
||||
* Remove the ApiListener configuration attributes.
|
||||
|
||||
```
|
||||
object ApiListener "api" {
|
||||
- cert_path = SysconfDir + "/icinga2/pki/${ICINGA2_NODENAME}.crt"
|
||||
- key_path = SysconfDir + "/icinga2/pki/${ICINGA2_NODENAME}.key"
|
||||
- ca_path = SysconfDir + "/icinga2/pki/ca.crt"
|
||||
accept_commands = true
|
||||
accept_config = true
|
||||
}
|
||||
```
|
||||
|
||||
Test the script with a fresh client installation before putting it into production.
|
||||
|
||||
> **Tip**
|
||||
>
|
||||
> Please support module and script developers in their migration. If you find
|
||||
> any project which would require these changes, create an issue or a patchset in a PR
|
||||
> and help them out. Thanks in advance!
|
||||
|
||||
|
||||
### Removed Bottom Up Client Mode <a id="upgrading-to-2-8-removed-bottom-up-client-mode"></a>
|
||||
|
||||
This client mode was deprecated in 2.6 and was removed in 2.8.
|
||||
|
||||
The node CLI command does not provide `list` or `update-config` anymore.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The old migration guide can be found on [GitHub](https://github.com/Icinga/icinga2/blob/v2.7.0/doc/06-distributed-monitoring.md#bottom-up-migration-to-top-down-).
|
||||
|
||||
The clients don't need to have a local `conf.d` directory included.
|
||||
The setup wizards for Linux and Windows attempt to disable this by default.
|
||||
|
||||
|
@ -31,6 +115,7 @@ You are advised to [migrate](https://github.com/Icinga/icinga2/issues/4798)
|
|||
any existing configuration to the "top down" mode with the help of the
|
||||
Icinga Director or config management tools such as Puppet, Ansible, etc.
|
||||
|
||||
|
||||
### Removed Classic UI Config Package <a id="upgrading-to-2-8-removed-classicui-config-package"></a>
|
||||
|
||||
The config meta package `classicui-config` and the configuration files
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
*/
|
||||
|
||||
object ApiListener "api" {
|
||||
cert_path = LocalStateDir + "/lib/icinga2/certs/" + NodeName + ".crt"
|
||||
key_path = LocalStateDir + "/lib/icinga2/certs/" + NodeName + ".key"
|
||||
ca_path = LocalStateDir + "/lib/icinga2/certs/ca.crt"
|
||||
//accept_config = false
|
||||
//accept_commands = false
|
||||
|
||||
ticket_salt = TicketSalt
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ abstract class Function
|
|||
{
|
||||
[config] String "name";
|
||||
[config] bool side_effect_free;
|
||||
[config] bool deprecated;
|
||||
[config] bool "deprecated";
|
||||
[config] Array::Ptr arguments;
|
||||
};
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ enum FieldAttribute
|
|||
FARequired = 256,
|
||||
FANavigation = 512,
|
||||
FANoUserModify = 1024,
|
||||
FANoUserView = 2048
|
||||
FANoUserView = 2048,
|
||||
FADeprecated = 4096,
|
||||
};
|
||||
|
||||
class Type;
|
||||
|
|
|
@ -816,6 +816,10 @@ void Utility::CollectPaths(const String& path, std::vector<String>& paths)
|
|||
paths.push_back(path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies a source file to a target location.
|
||||
* Caller must ensure that the target's base directory exists and is writable.
|
||||
*/
|
||||
void Utility::CopyFile(const String& source, const String& target)
|
||||
{
|
||||
std::ifstream ifs(source.CStr(), std::ios::binary);
|
||||
|
|
|
@ -173,10 +173,7 @@ int NodeSetupCommand::SetupMaster(const boost::program_options::variables_map& v
|
|||
fp << "/**\n"
|
||||
<< " * The API listener is used for distributed monitoring setups.\n"
|
||||
<< " */\n"
|
||||
<< "object ApiListener \"api\" {\n"
|
||||
<< " cert_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".crt\"\n"
|
||||
<< " key_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".key\"\n"
|
||||
<< " ca_path = LocalStateDir + \"/lib/icinga2/certs/ca.crt\"\n";
|
||||
<< "object ApiListener \"api\" {\n";
|
||||
|
||||
if (vm.count("listen")) {
|
||||
std::vector<String> tokens;
|
||||
|
@ -378,10 +375,7 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,
|
|||
fp << "/**\n"
|
||||
<< " * The API listener is used for distributed monitoring setups.\n"
|
||||
<< " */\n"
|
||||
<< "object ApiListener \"api\" {\n"
|
||||
<< " cert_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".crt\"\n"
|
||||
<< " key_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".key\"\n"
|
||||
<< " ca_path = LocalStateDir + \"/lib/icinga2/certs/ca.crt\"\n";
|
||||
<< "object ApiListener \"api\" {\n";
|
||||
|
||||
if (vm.count("listen")) {
|
||||
std::vector<String> tokens;
|
||||
|
|
|
@ -472,10 +472,6 @@ wizard_ticket:
|
|||
<< " * The API listener is used for distributed monitoring setups.\n"
|
||||
<< " */\n"
|
||||
<< "object ApiListener \"api\" {\n"
|
||||
<< " cert_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".crt\"\n"
|
||||
<< " key_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".key\"\n"
|
||||
<< " ca_path = LocalStateDir + \"/lib/icinga2/certs/ca.crt\"\n"
|
||||
<< "\n"
|
||||
<< " accept_config = " << acceptConfig << "\n"
|
||||
<< " accept_commands = " << acceptCommands << "\n";
|
||||
|
||||
|
@ -629,10 +625,7 @@ int NodeWizardCommand::MasterSetup(void) const
|
|||
fp << "/**\n"
|
||||
<< " * The API listener is used for distributed monitoring setups.\n"
|
||||
<< " */\n"
|
||||
<< "object ApiListener \"api\" {\n"
|
||||
<< " cert_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".crt\"\n"
|
||||
<< " key_path = LocalStateDir + \"/lib/icinga2/certs/\" + NodeName + \".key\"\n"
|
||||
<< " ca_path = LocalStateDir + \"/lib/icinga2/certs/ca.crt\"\n";
|
||||
<< "object ApiListener \"api\" {\n";
|
||||
|
||||
if (!bindHost.IsEmpty())
|
||||
fp << " bind_host = \"" << bindHost << "\"\n";
|
||||
|
|
|
@ -75,6 +75,34 @@ String ApiListener::GetCertificateRequestsDir(void)
|
|||
return Application::GetLocalStateDir() + "/lib/icinga2/certificate-requests/";
|
||||
}
|
||||
|
||||
String ApiListener::GetDefaultCertPath(void)
|
||||
{
|
||||
return GetCertsDir() + "/" + ScriptGlobal::Get("NodeName") + ".crt";
|
||||
}
|
||||
|
||||
String ApiListener::GetDefaultKeyPath(void)
|
||||
{
|
||||
return GetCertsDir() + "/" + ScriptGlobal::Get("NodeName") + ".key";
|
||||
}
|
||||
|
||||
String ApiListener::GetDefaultCaPath(void)
|
||||
{
|
||||
return GetCertsDir() + "/ca.crt";
|
||||
}
|
||||
|
||||
void ApiListener::CopyCertificateFile(const String& oldCertPath, const String& newCertPath)
|
||||
{
|
||||
struct stat st1, st2;
|
||||
|
||||
if (!oldCertPath.IsEmpty() && stat(oldCertPath.CStr(), &st1) >= 0 && (stat(newCertPath.CStr(), &st2) < 0 || st1.st_mtime > st2.st_mtime)) {
|
||||
Log(LogWarning, "ApiListener")
|
||||
<< "Copying '" << oldCertPath << "' certificate file to '" << newCertPath << "'";
|
||||
|
||||
Utility::MkDirP(Utility::DirName(newCertPath), 0700);
|
||||
Utility::CopyFile(oldCertPath, newCertPath);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiListener::OnConfigLoaded(void)
|
||||
{
|
||||
if (m_Instance)
|
||||
|
@ -82,20 +110,37 @@ void ApiListener::OnConfigLoaded(void)
|
|||
|
||||
m_Instance = this;
|
||||
|
||||
String defaultCertPath = GetDefaultCertPath();
|
||||
String defaultKeyPath = GetDefaultKeyPath();
|
||||
String defaultCaPath = GetDefaultCaPath();
|
||||
|
||||
/* Migrate certificate location < 2.8 to the new default path. */
|
||||
String oldCertPath = GetCertPath();
|
||||
String oldKeyPath = GetKeyPath();
|
||||
String oldCaPath = GetCaPath();
|
||||
|
||||
CopyCertificateFile(oldCertPath, defaultCertPath);
|
||||
CopyCertificateFile(oldKeyPath, defaultKeyPath);
|
||||
CopyCertificateFile(oldCaPath, defaultCaPath);
|
||||
|
||||
if (!oldCertPath.IsEmpty() && !oldKeyPath.IsEmpty() && !oldCaPath.IsEmpty()) {
|
||||
Log(LogWarning, "ApiListener", "Please read the upgrading documentation for v2.8: https://www.icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/");
|
||||
}
|
||||
|
||||
/* set up SSL context */
|
||||
boost::shared_ptr<X509> cert;
|
||||
try {
|
||||
cert = GetX509Certificate(GetCertPath());
|
||||
cert = GetX509Certificate(defaultCertPath);
|
||||
} catch (const std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot get certificate from cert path: '"
|
||||
+ GetCertPath() + "'.", GetDebugInfo()));
|
||||
+ defaultCertPath + "'.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
try {
|
||||
SetIdentity(GetCertificateCN(cert));
|
||||
} catch (const std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot get certificate common name from cert path: '"
|
||||
+ GetCertPath() + "'.", GetDebugInfo()));
|
||||
+ defaultCertPath + "'.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
Log(LogInformation, "ApiListener")
|
||||
|
@ -109,10 +154,10 @@ void ApiListener::UpdateSSLContext(void)
|
|||
boost::shared_ptr<SSL_CTX> context;
|
||||
|
||||
try {
|
||||
context = MakeSSLContext(GetCertPath(), GetKeyPath(), GetCaPath());
|
||||
context = MakeSSLContext(GetDefaultCertPath(), GetDefaultKeyPath(), GetDefaultCaPath());
|
||||
} catch (const std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot make SSL context for cert path: '"
|
||||
+ GetCertPath() + "' key path: '" + GetKeyPath() + "' ca path: '" + GetCaPath() + "'.", GetDebugInfo()));
|
||||
+ GetDefaultCertPath() + "' key path: '" + GetDefaultKeyPath() + "' ca path: '" + GetDefaultCaPath() + "'.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
if (!GetCrlPath().IsEmpty()) {
|
||||
|
@ -420,7 +465,7 @@ void ApiListener::NewClientHandlerInternal(const Socket::Ptr& client, const Stri
|
|||
identity = GetCertificateCN(cert);
|
||||
} catch (const std::exception&) {
|
||||
Log(LogCritical, "ApiListener")
|
||||
<< "Cannot get certificate common name from cert path: '" << GetCertPath() << "'.";
|
||||
<< "Cannot get certificate common name from cert path: '" << GetDefaultCertPath() << "'.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,10 @@ public:
|
|||
static bool IsHACluster(void);
|
||||
static String GetFromZoneName(const Zone::Ptr& fromZone);
|
||||
|
||||
static String GetDefaultCertPath(void);
|
||||
static String GetDefaultKeyPath(void);
|
||||
static String GetDefaultCaPath(void);
|
||||
|
||||
protected:
|
||||
virtual void OnConfigLoaded(void) override;
|
||||
virtual void OnAllConfigLoaded(void) override;
|
||||
|
@ -157,6 +161,8 @@ private:
|
|||
static void LogGlobHandler(std::vector<int>& files, const String& file);
|
||||
void ReplayLog(const JsonRpcConnection::Ptr& client);
|
||||
|
||||
static void CopyCertificateFile(const String& oldCertPath, const String& newCertPath);
|
||||
|
||||
/* filesync */
|
||||
static ConfigDirInformation LoadConfigDir(const String& dir);
|
||||
static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config);
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace icinga
|
|||
|
||||
class ApiListener : ConfigObject
|
||||
{
|
||||
[config, required] String cert_path;
|
||||
[config, required] String key_path;
|
||||
[config, required] String ca_path;
|
||||
[config, deprecated] String cert_path;
|
||||
[config, deprecated] String key_path;
|
||||
[config, deprecated] String ca_path;
|
||||
[config] String crl_path;
|
||||
[config] String cipher_list {
|
||||
default {{{ return "ALL:!LOW:!WEAK:!MEDIUM:!EXP:!NULL"; }}}
|
||||
|
|
|
@ -56,7 +56,7 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
|
|||
cert = StringToCertificate(certText);
|
||||
|
||||
ApiListener::Ptr listener = ApiListener::GetInstance();
|
||||
boost::shared_ptr<X509> cacert = GetX509Certificate(listener->GetCaPath());
|
||||
boost::shared_ptr<X509> cacert = GetX509Certificate(listener->GetDefaultCaPath());
|
||||
|
||||
String cn = GetCertificateCN(cert);
|
||||
|
||||
|
@ -183,7 +183,7 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
|
|||
* a certificate it wouldn't be able to use to connect to us anyway) */
|
||||
if (!VerifyCertificate(cacert, newcert)) {
|
||||
Log(LogWarning, "JsonRpcConnection")
|
||||
<< "The CA in '" << listener->GetCaPath() << "' does not match the CA which Icinga uses "
|
||||
<< "The CA in '" << listener->GetDefaultCaPath() << "' does not match the CA which Icinga uses "
|
||||
<< "for its own cluster connections. This is most likely a configuration problem.";
|
||||
goto delayed_request;
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ Value UpdateCertificateHandler(const MessageOrigin::Ptr& origin, const Dictionar
|
|||
if (!listener)
|
||||
return Empty;
|
||||
|
||||
boost::shared_ptr<X509> oldCert = GetX509Certificate(listener->GetCertPath());
|
||||
boost::shared_ptr<X509> oldCert = GetX509Certificate(listener->GetDefaultCertPath());
|
||||
boost::shared_ptr<X509> newCert = StringToCertificate(cert);
|
||||
|
||||
String cn = GetCertificateCN(newCert);
|
||||
|
@ -328,7 +328,7 @@ Value UpdateCertificateHandler(const MessageOrigin::Ptr& origin, const Dictionar
|
|||
}
|
||||
|
||||
/* Update CA certificate. */
|
||||
String caPath = listener->GetCaPath();
|
||||
String caPath = listener->GetDefaultCaPath();
|
||||
|
||||
Log(LogInformation, "JsonRpcConnection")
|
||||
<< "Updating CA certificate in '" << caPath << "'.";
|
||||
|
@ -350,7 +350,7 @@ Value UpdateCertificateHandler(const MessageOrigin::Ptr& origin, const Dictionar
|
|||
}
|
||||
|
||||
/* Update signed certificate. */
|
||||
String certPath = listener->GetCertPath();
|
||||
String certPath = listener->GetDefaultCertPath();
|
||||
|
||||
Log(LogInformation, "JsonRpcConnection")
|
||||
<< "Updating client certificate for CN '" << cn << "' in '" << certPath << "'.";
|
||||
|
|
|
@ -149,6 +149,7 @@ bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& requ
|
|||
attributeInfo->Set("navigation", static_cast<bool>(field.Attributes & FANavigation));
|
||||
attributeInfo->Set("no_user_modify", static_cast<bool>(field.Attributes & FANoUserModify));
|
||||
attributeInfo->Set("no_user_view", static_cast<bool>(field.Attributes & FANoUserView));
|
||||
attributeInfo->Set("deprecated", static_cast<bool>(field.Attributes & FADeprecated));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ protected { yylval->num = FAGetProtected | FASetProtected; return T_FIELD_ATTR
|
|||
no_storage { yylval->num = FANoStorage; return T_FIELD_ATTRIBUTE; }
|
||||
no_user_modify { yylval->num = FANoUserModify; return T_FIELD_ATTRIBUTE; }
|
||||
no_user_view { yylval->num = FANoUserView; return T_FIELD_ATTRIBUTE; }
|
||||
deprecated { yylval->num = FADeprecated; return T_FIELD_ATTRIBUTE; }
|
||||
navigation { return T_NAVIGATION; }
|
||||
validator { return T_VALIDATOR; }
|
||||
required { return T_REQUIRED; }
|
||||
|
|
|
@ -510,6 +510,15 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
|||
m_Impl << "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), boost::assign::list_of(\"" << field.Name << "\"), \"Attribute must not be empty.\"));" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
if (field.Attributes & FADeprecated) {
|
||||
if (field.Type.GetRealType().find("::Ptr") != std::string::npos)
|
||||
m_Impl << "\t" << "if (" << argName << ")" << std::endl;
|
||||
else
|
||||
m_Impl << "\t" << "if (!" << argName << ".IsEmpty())" << std::endl;
|
||||
|
||||
m_Impl << "\t\t" << "Log(LogWarning, \"" << klass.Name << "\") << \"Attribute '" << field.Name << "' for object '\" << dynamic_cast<ConfigObject *>(this)->GetName() << \"' of type '\" << dynamic_cast<ConfigObject *>(this)->GetReflectionType()->GetName() << \"' is deprecated and should not be used.\";" << std::endl;
|
||||
}
|
||||
|
||||
if (field.Type.ArrayRank > 0) {
|
||||
m_Impl << "\t" << "if (avalue) {" << std::endl
|
||||
<< "\t\t" << "ObjectLock olock(avalue);" << std::endl
|
||||
|
|
|
@ -72,7 +72,8 @@ enum FieldAttribute
|
|||
FARequired = 256,
|
||||
FANavigation = 512,
|
||||
FANoUserModify = 1024,
|
||||
FANoUserView = 2048
|
||||
FANoUserView = 2048,
|
||||
FADeprecated = 4096
|
||||
};
|
||||
|
||||
struct FieldType
|
||||
|
|
Loading…
Reference in New Issue