Obtaining service variables as JSON

I want to query my Icinga services and collect certain custom variable values in machine-readable form. Since the Icinga API doesn’t allow filtering out sensitive service variables from the responses I’ve been hoping to use Icinga Web for this. I’ve already set up variable filtering so the HTML pages look fine and doesn’t contain anything sensitive. However, I haven’t been able to get JSON output for any pages that include service variables.

For example, I get JSON output from /icingaweb2/monitoring/list/services?<filter_expression> when including Accept: application/json but the response doesn’t include any service variables at all. I’ve made a couple of attempts to fetch service details:

  • /icingaweb2/monitoring/service/show?host=<hostname>&service=<servicename> yields JSON but not what I expected: {"status":"success","data":{"message":"Scheduling check.."}}
  • /icingaweb2/monitoring/host/services?host=<hostname>&service=<servicename>#!/icingaweb2/monitoring/service/show?host=<hostname>&service=<servicename> just yields HTML.

Am I using the wrong URL or is this something that isn’t supposed to work in my ancient combo of Icinga 2.10.5 and Icinga Web 2.6.3? (I’ve been using the no longer maintained jordan/icinga2 Docker image so upgrading requires some work.)

If you want JSON, it’s maybe better to query the Icinga2 API directly?

AFAICT that API doesn’t support filtering out variables containing sensitive data like passwords.

I think you can by specifically requesting attrs: Icinga2 Api - Icinga 2

Also you could filter after getting the result but before passing it on, inside of your own script.

My concern is malicious actors that gain access to API credentials so the variable filtering would have to take place on the server side.

Not sure, what you goal is but maybe you can filter on the server side to only allow the API access to the state endpoint and thus the sensitive variables are protected.

Also if you run the API queries on the Icinga server itself the credentials wouldn’t leave the host and if somebody breaches the hosts access would a given with or without the API credentials.

The “state endpoint”?

I guess the “state endpoint” isn’t good enough for you as you want to read the variables but not the sensitive ones. So probably, your only option is to use on the API Icinga2 master and filter before you extract it from the host.

Okay, thanks. I think it’s a problem that it’s so hard to avoid exposing sensitive data.

I think I’ll store the secrets in global dictionary variables instead, and let the service variables for secrets contain the dictionary key instead of the actual secret value. Resolving the key to the secret value would take place in the CheckCommand object definition, out of sight for the services.

Good approach and also fits well with my requests to send the secrets to the check commands via environment variables to not have them show up in the process table and logs.

https://github.com/Icinga/icingaweb2-module-director/issues/2751

You could put the variables XORed into the constants file and pass the string used
for the XOR into the environment of Icinga2 itself and use the DSL to encrypt them.

https://icinga.com/docs/icinga-2/latest/doc/18-library-reference/#getenv

Maybe you could help and also push for this as it looks like you care about this topic:

  • no secrets in clear text on disk
  • no secrets in process lists

Use the host or server list instead. Then export this to json using the format parameter or by use of the Accept header.

Good idea, why didn’t I think about this…