How to set up a general HTTPS certificate check rule which checks the explicit hostname and not the primary IP?

Hello everyone,

I would like to set up a HTTPS certificate check, which does not check the primary IP of the attached host, but the explicit hostname the rule is assigned to.

Our websites are implemented as vhosts (Apache or NGINX) running on servers which have names differing from the site/vhost name. The site/vhost names are DNS aliases of the server name. So far we had set up an individual rule for each site/vhost and specified the vhost name in the “Host settings” section:
image

However it doesn’t really make sense to have 20 rules which are 99% identical with the exception of this single setting. Therefore I have set up a single general rule, which is valid for all webservers, and we assign this rule to all 20 sites (“Explicit hosts” setting, the sitenames have been added as hostnames to Checkmk):
(image see next post, as I am not allowed to post more than one image :frowning: )

The “Host settings” setting is left empty. Unfortunately Checkmk now resolves the IP of the site and gets the IP of the server, which in many cases makes the check fail, either because there are several different sites running on the same server or because there is no site running under the server name.

How can I specify, that Checkmk checks the explicit host names configured in the “Explicit hosts” settings and not the primary IP of that host? I.e uses the host names verbatim and skips the DNS lookup to get the primary IP.

Cheers, Frank

This is the illustration missing in the original post:

After some experimenting I found a way by editing the function _get_host() in /opt/omd/versions/2.0.0p22.cee/share/check_mk/checks/check_http:

def _get_host(params):
    # Use the address family of the monitored host by default
    host = params.get("host", {})

    family = host.get("address_family")
    if family is None:
        family = "ipv6" if is_ipv6_primary(host_name()) else "ipv4"

    address = host_name()  # this is CHANGED from address = host.get("address")
    if address is None:
        address = "$_HOSTADDRESS_%s$" % family[-1]

    HostSettings = collections.namedtuple("HostSettings", ("address", "port", "family", "virtual"))
    return HostSettings(address, host.get("port"), family, host.get("virthost"))

(address = host.get("address") has been replaced by address = host_name()) and then restarting the site.

However I wonder, if there is not a way w/o manually patching the code…

Not sure if I fully understand your scenario, but you can use the macro $HOSTNAME$ in the service name, hostname and/or virtual host fields.

Checkmk has its OWN dns cache so it will resolve the CNAME to an IP and it will always connect using IP to not hammer your DNS relays (think of when having 100.000 hosts…)

As arealdy mentioned you should be able to use $HOSTNAME$ as your Virtual Host

The scenario is e.g.: Host H hosts the two websites S1 and S2. Checking the certificates for S1 and S2 does not work by checking the certificate of H (if there is any). But that is what Checkmk by default does: It resolves the IP of S1, which is the IP of H and then does a certificate check on H.

I could circumvent this by creating an individual rule for each site and then specifying S1 and S2 respectively as virtual hosts in the rule’s settings, but the goal is to do the checks using a single rule which applies to all sites.

Thanks a lot for the $HOSTNAME$ hint. I was not able to find the documentation for the Python interface to Checkmk. Is there any?

It seems I misunderstood. Apparently these macros should be used directly in the configuration forms, and not in the Python code :-). I’ve adapted my rule by using $HOSTNAME$ as “Hosts name / IP address” in the rule configuration and this seems to work fine with the original code of check_http.

Thanks a lot @martin.schwarz and @Anders

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact an admin if you think this should be re-opened.