Certificate request stuck on satellite

Hi there, I am trying to use the ansible-collection-icinga to deploy master, satellites and agents. We have scenarios where the agent cannot connect the master, therefore the satellite needs to be able to sign/provide the certificates. The ca from the master is copied to the satellite and it is up and running.

Today I tried to setup an agent. I see an incoming certificate request from the agent, but it is just stuck on “Waiting for approval.”. I can see the pending request via icinga2 ca list.

Fingerprint | Timestamp                | Signed | Subject
------------|--------------------------|--------|--------
xxxx        | Apr 25 07:38:58 2025 GMT |        | CN = agent.example.net

Log from satellite:

[2025-04-25 09:38:58 +0200] information/ApiListener: New client connection from [::ffff:10.10.10.10]:53856 (no client certificate)
[2025-04-25 09:38:58 +0200] information/ApiListener: No data received on new API connection from [::ffff:10.10.10.10]:53856. Ensure that the remote endpoints are properly configured in a cluster setup.
[2025-04-25 09:39:00 +0200] information/ApiListener: New client connection for identity 'agent.example.net' from [::ffff:10.10.10.10]:53868 (certificate validation failed: code 18: self-signed certificate)
[2025-04-25 09:39:00 +0200] information/JsonRpcConnection: Received certificate request for CN agent.example.net' which couldn't be verified: self-signed certificate (code 18)
[2025-04-25 09:39:00 +0200] information/JsonRpcConnection: Certificate request for CN 'agent.example.net' is pending. Waiting for approval.
[2025-04-25 09:39:00 +0200] warning/JsonRpcConnection: API client disconnected for identity 'agent.example.net'

What step am I missing? I think I am overlooking something in the collection or the general setup.


Vars on agent

  - name: api           # Enable Feature API
    accept_config: true
    accept_commands: true
    ca_host: "{{ groups['icinga_satellites_int'][0] }}"
    cert_name: "{{ inventory_hostname }}"
    ticket_salt: "{{ icinga2_global_ticketsalt }}"
    force_newcert: yes # set to `yes` in case you need to re-setup a client
    # Trusted Cert and Ticket will be gathered from this host.
    # Ticket will be "delegated" if the FQDN is not in your Ansible environment
    # use the variable icinga2_delegate_host in addition.
    endpoints:
      - name: NodeName
      - name: "{{ groups['icinga_satellites_int'][0] }}"
    zones:
      - name: NodeName
        parent: "{{ icinga2_global_zonename_satellite }}"
        endpoints:
          - NodeName
      - name: "{{ icinga2_global_zonename_satellite }}"
        endpoints:
          - "{{ groups['icinga_satellites_int'][0] }}"
      - name: global-templates
        global: true
      - name: director-global
        global: true
  • Version used (icinga2 --version)
    • r2.14.5-1
  • Operating System and version
    • 20.04.6 LTS (Focal Fossa)
    • 22.04.5 LTS (Jammy Jellyfish)
  • Enabled features (icinga2 feature list)
    • master: api checker icingadb mainlog notification
    • satellite: api checker mainlog
    • agent: api checker mainlog
  • Icinga Web 2 version and modules (System - About)
    • 2.12.4
  • Config validation (icinga2 daemon -C)
    • no errors
  • ansible-collection-icinga version
    • 0.3.4

zones.conf
Master

object Endpoint NodeName {
}

object Endpoint "satellite.example.net" {
  host = "10.10.10.10"
}

object Endpoint "master2.example.com" {
}

object Zone ZoneName {
  endpoints = [ NodeName, "master2.example.com", ]
}

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

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

object Zone "satellite-zoner" {
  endpoints = [ "icinga-satellite.example.com", ]
  parent = ZoneName
}

Satellite

object Endpoint NodeName {
}

object Endpoint "master1.example.net" {
}

object Endpoint "master2.example.net" {
}

object Zone ZoneName {
  parent = "main"
  endpoints = [ NodeName, ]
}

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

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

object Zone "main" {
  endpoints = [ "master1.example.net", "master2.example.net", ]
}

Agent

object Endpoint NodeName {
}

object Endpoint "satellite.example.com" {
}

object Zone NodeName {
  parent = "satellite-zone"
  endpoints = [ NodeName, ]
}

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

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

object Zone "satellite-zone" {
  endpoints = [ "satellite.example.net", ]
}

Certificates can be signed by the master only. An agent can send its request to a satellite and this would forward it to the master. However, using ansible offers a better approach called auto-signing. You need an additional task to create a ticket first and generate agent’s certificates.

I didn’t change anything but suddenly the auto-signing works properly on a new attempt. I am a bit confused but accept my fate.

The ticket and agent cert generation is handled by the ansible-collection-icinga. With this agent/satellite I am not in the situation that the satellite cannot reach the master (FW out forbidden).

Nevermind. As soon as I added the host in the director I am back to “Waiting for Approval.”. I was under the impression auto-signing is being used already. Using the collection.

I am always referring to the official GitHub - Icinga/ansible-collection-icinga: Collection to setup and manage components of the Icinga software stack

Master

[2025-04-25 12:29:00 +0200] information/JsonRpcConnection: Certificate request for CN 'agent2.example.net' is pending. Waiting for approval.

Satellite

[2025-04-25 12:32:13 +0200] information/ApiListener: Reconnecting to endpoint 'agent2.example.com' via host '10.10.10.20' and port '5665'
[2025-04-25 12:32:13 +0200] warning/ApiListener: Certificate validation failed for endpoint 'agent2.example.com': code 7: certificate signature failure
[2025-04-25 12:32:13 +0200] information/ApiListener: New client connection for identity 'agent2.example.com' to [10.10.10.20]:5665 (certificate validation failed: code 7: certificate signature failure)
[2025-04-25 12:32:13 +0200] information/ApiListener: Finished reconnecting to endpoint 'agent2.example.com' via host '10.10.10.20' and port '5665'
[2025-04-25 12:32:13 +0200] information/JsonRpcConnection: Received certificate request for CN 'agent2.example.com' which couldn't be verified: certificate signature failure (code 7)
[2025-04-25 12:32:13 +0200] information/JsonRpcConnection: Certificate request for CN 'agent2.example.com' is pending. Waiting for approval.

EDIT: Even if I sign it manually on the satellite I get a new request immediately with a new fingerprint.