Icinga/icinga-powershell-framework

Install-Icinga uses wrong port to get parent certificate

Donien opened this issue · 2 comments

Install-Icinga uses the local node's port instead of the parent's port.

When running Install-Icinga the local node's port (IfW-Port) is used to connect to the defined parent.

E.g.

  • IfW port: 5777
  • Parent Icinga port: 5665

This results in the following command when running Install-Icinga:

C:\Program Files\ICINGA2\sbin\icinga2.exe pki request \
    --host icinga.localdomain \
    --port 5777 \
    --key C:\ProgramData\icinga2\var\lib\icinga2\certs\windows.key \
    --cert C:\ProgramData\icinga2\var\lib\icinga2\certs\windows.crt \
    --trustedcert C:\ProgramData\icinga2\var\lib\icinga2\certs\trusted-parent.crt \
    --ca C:\ProgramData\icinga2\var\lib\icinga2\certs\ca.crt

This command however fails because the parent's port is not 5777 but 5665.


Actual (full) command run:

Expand
Install-Icinga -InstallCommand "
{
  'IfW-CustomZones': {
    'Values': [
      'director-global',
      'global-templates'
    ]
  },
  'IfW-GlobalZones': {
    'Selection': '3'
  },
  'IfW-InstallAgent': {
    'Selection': '1'
  },
  'IfW-Port': {
    'Values': [
      '5777'
    ]
  },
  'IfW-ParentNodes': {
    'Values': [
      'main'
    ]
  },
  'IfW-ParentZone': {
    'Values': [
      'main'
    ]
  },
  'IfW-ParentAddress': {
    'Values': {
      'main': [
        '[icinga.localdomain]:5665'
      ]
    }
  },
  'IfW-InstallPlugins': {
    'Selection': '1'
  },
  'IfW-Connection': {
    'Selection': '2'
  },
  'IfW-InstallService': {
    'Selection': '1'
  },
  'IfW-Certificate': {
    'Selection': '1'
  },
  'IfW-CAServer': {
    'Values': [
      'icinga.localdomain'
    ]
  },
  'IfW-InstallJEAProfile': {
    'Selection': '2'
  },
  'IfW-Hostname': {
    'Selection': '0'
  }
}
"

Command run (with relevant parts):

Install-Icinga -InstallCommand "
{
  ...
  'IfW-Port': {
    'Values': [
      '5777'
    ]
  },
  'IfW-ParentNodes': {
    'Values': [
      'main'
    ]
  },
  'IfW-ParentZone': {
    'Values': [
      'main'
    ]
  },
  'IfW-ParentAddress': {
    'Values': {
      'main': [
        '[icinga.localdomain]:5665'
      ]
    }
  },
  ...
}
"

I think setting 5665 as the default to connect to the parent should be the way to go unless another port is specified for the parent endpoint itself ([icinga.localdomain]:5665).

The local port on which the Windows host should listen should not affect the port used to connect to the parent.

Thank you for your issue. Can you please explain why the local Windows port should be different to the parent nodes Icinga port?

This is in general not best practice, as the Icinga environment should listen on the same port. However, forcing 5665 to be used every time is not a suitable option, as there are environments where this is not the default port and therefore all those installations would fail.

I need to have a deeper look into this, as a simple change could break current environments in case the behavior changes. In addition, I'm not sure if the described behavior is wrong or correct 🤔

I've tested the PR but without success.

Also, typo ("$Hostnamef", line 225):

Write-IcingaAgentZonesConfig -Endpoints $IcingaEndpoints -EndpointConnections $IcingaParentAddresses -ParentZone $IcingaZone -GlobalZones $GlobalZones -Hostname $Hostnamef;

When intially opening the issue I had used the variable IfW-CAServer. This in turn led to some confusion.
Within IfW-CAServer I didn't specify any port, just the hostname.

Icinga For Windows then using IfW-Port is to be expected and actually the most logical approach.


However, if leaving IfW-CAServer empty / not setting it, the value IfW-ParentAddress': {'Values': {'main': ['[icinga.localdomain]:5665']}} is used instead (actual parent).
This value will be used to get the "trusted-parent.crt" certificate.

So
IfW-ParentAddress': {'Values': {'main': ['[icinga.localdomain]:5665']}} in combination with IfW-Port': {'Values': ['5777']}
will result in

[Error]: Failed to create certificate.
Arguments: pki save-cert --trustedcert C:\ProgramData\icinga2\var\lib\icinga2\certs\trusted-parent.crt --host [icinga.localdomain]:5665 --port 5777
Error:information/cli: Retrieving TLS certificate for '[icinga.localdomain]:5665:5777'.
critical/pki: Cannot connect to host '[icinga.localdomain]:5665' on port '5777'

When it comes to the certificate retrieval specifiying an endpoint as [HOSTNAME]:PORT simply isn't supported yet.

But that exact pattern ([HOSTNAME]:PORT) is successfully used to write zones.conf, while IfW-Port is used as the local bind port and set properly in features-enabled/api.conf.
Both seem to be the expected behaviour.

IfW-ParentAddress': {'Values': {'main': ['[icinga.localdomain]:1234']}} in combination with IfW-Port': {'Values': ['5777']} results in the following.

Result of the install command:

...
[Error]: Failed to create certificate.
Arguments: pki save-cert --trustedcert C:\ProgramData\icinga2\var\lib\icinga2\certs\trusted-parent.crt --host [icinga.localdomain]:1234 --port 5777
Error:information/cli: Retrieving TLS certificate for '[icinga.localdomain]:1234:5777'.
critical/pki: Cannot connect to host '[icinga.localdomain]:1234' on port '5777'
critical/cli: Failed to fetch certificate from host.
...

zones.conf:

object Endpoint "windows" {
}

object Endpoint "main" {
    host = "icinga.localdomain";
    port = "1234";
}

object Zone "main" {
    endpoints = [ "main" ];
}

object Zone "windows" {
    parent = "main";
    endpoints = [ "windows" ];
}

object Zone "director-global" {
    global = true;
}

object Zone "global-templates" {
    global = true;
}

The same parsing used to write zones.conf would need to be implemented for the retrieval of the parent certificate.

So if the parent is written in the form of "[HOSTNAME]:PORT"

  • take the first part (HOSTNAME) as the value for --host
  • take the second part (PORT) as the value for --port

If the parent is written like "HOSTNAME"

  • take HOSTNAME as the value for --host
  • take IfW-Port as the value for --port