Checkmk
to checkmk.com

1. Einleitung

In diesem Artikel erfahren Sie, wie Sie eine Anmeldung via Secure Assertion Markup Language (SAML) einrichten. Die Implementierung in Checkmk läuft auf Apache-Level über mod_auth_mellon, das im SAML-Design die Rolle des Service Providers (SP) übernimmt.

Diese Anleitung zeigt ausführlich den Weg mit Active Directory Federation Services (AD FS) als Identity Provider (IDP). In weiteren Abschnitten bekommen Sie Hinweise zur Konfiguration weiterer IDPs, etwa Azure AD und Micro Focus NetIQ Access Manager.

Hinweis: Dieses Feature wird von den SUSE Linux Enterprise Server (SLES) Versionen 12 SP3, 12 SP4 und 15 aufgrund fehlender Abhängigkeiten nicht unterstützt (ab SLES 15 SP1 ist die Anbindung möglich).

Achtung: Die ganze Thematik Transportverschlüsselung (TLS/SSL) wird in den Beispielen nur in einer simplen, beispielhaften Umsetzung aufgenommen. In Produktivumgebungen mit eigener CA und sorgfältiger Zertifikatsbehandlung werden sich entsprechende Abweichungen ergeben, die von Ihrer eigenen Infrastruktur abhängen.

2. Anmeldung mit Active Directory Federation Services

2.1. Voraussetzungen

Die Anmeldung an Checkmk mittels Active Directory ist im Grunde relativ simpel: AD Federation Service (FS) dient als Identity Provider (IDP), das Apache-Modul mod_auth_mellon sorgt als Service Provider via Security Assertion Markup Language (SAML) für die Authentifizierung. Voraussetzungen für diese Anleitung sind entsprechend:

  • Funktionierende LDAP-AD-Integration

  • Funktionierendes AD FS als IDP

  • Checkmk-Server mit SSL

Die Einrichtung erfolgt in drei Schritten:

  1. Konfiguration von Apache (ein Ergebnis: XML-Datei mit Metadaten)

  2. Konfiguration von AD FS: Relying Party Trust mit Mellon-Metadaten einrichten

  3. Aktivierung des Logins in Checkmk selbst

2.2. Apache konfigurieren

Unter Umständen müssen noch zusätzliche Abhängigkeiten installiert werden, unter Debian/Ubuntu z.B.:

root@linux# apt-get update
root@linux# apt-get install wget libxmlsec1-openssl

Es geht hier natürlich um die Konfiguration des Instanz-eigenen Apache-Servers, loggen Sie sich also zunächst dort ein:

root@linux# omd su mysite

Erstellen Sie nun ein Verzeichnis für mod_auth_mellon und wechseln Sie in das Verzeichnis:

OMD[mysite]:~$ mkdir etc/apache/mellon
OMD[mysite]:~$ cd etc/apache/mellon

Machen Sie nun mellon_create_metadata ausführbar und starten Sie es unter Angabe Ihres Servers sowie Ihrer Instanz mit dem Zusatz mellon:

OMD[mysite]:~/etc/apache/mellon$ chmod +x ~/bin/mellon_create_metadata
OMD[mysite]:~/etc/apache/mellon$ mellon_create_metadata https://myserver "https://myserver/mysite/mellon"

Das Modul erzeugt dabei drei Dateien: Zertifikat (.cert), Schlüssel (.key) und statische Metadaten (.xml) — letztere werden nicht benötigt und können gelöscht werden:

OMD[mysite]:~/etc/apache/mellon$ rm *.xml

Benennen Sie und Schlüssel- und Zertifikatsdateien der Einfachheit halber um:

OMD[mysite]:~/etc/apache/mellon$ mv *.key mellon.key
OMD[mysite]:~/etc/apache/mellon$ mv *.cert mellon.cert

Nun besorgen Sie die benötigten Metadaten direkt von Ihrem AD-FS-Server (hier myadfs) und speichern sie als idp-metadata.xml:

OMD[mysite]:~/etc/apache/mellon$ wget --no-check-certificate -O ./idp-metadata.xml https://myadfs/FederationMetadata/2007-06/FederationMetadata.xml

Nun benötigen Sie das öffentliche Zertifikat des AD-FS-Servers, das in der Datei idp-public-key.pem gespeichert wird:

OMD[mysite]:~/etc/apache/mellon$ echo -n | openssl s_client -connect myadfs:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | openssl x509 -pubkey -noout > idp-public-key.pem

Nur für den Fall, dass Sie sich über das echo -n wundern: Darüber wird die folgende SSL-Session terminiert.

Hinweis: Das Zertifikat sollte oder muss gar in den Trust Store hochgeladen werden, für den Fall, dass zum Beispiel der IDP-Service die Zertifikatskette prüft. Weiter Informationen zum Thema finden Sie im HTTPS-Artikel.

Als letzten Schritt ersetzen Sie die Authenfizierungskonfigurationsdatei ~/etc/apache/conf.d/auth.conf mit der folgenden Variante — natürlich unter Angabe Ihres Checkmk-Servers (hier myserver) und Ihrer Instanz (hier mysite):

~/etc/apache/conf.d/auth.conf
# Set this to the Name of your Checkmk site, e.g.
#Define SITE
Define SITE mysite

# ServerName from listen-ports.conf needs to be overwritten here
# and being set to the URL of the real server. auth_mellon uses this
# to generate the needed URLs in the metadata
ServerName https://myserver

# Load the module.
<IfModule !mod_auth_mellon.c>

	LoadModule auth_mellon_module /omd/sites/${SITE}/lib/apache/modules/mod_auth_mellon.so

</IfModule>

# Only enable this for debugging purposes
#MellonDiagnosticsFile /opt/omd/sites/${SITE}/tmp/mellon_diagnostics.txt
#MellonDiagnosticsEnable On

<Location /${SITE}>

	# Use SAML auth only in case there is no Check_MK authentication
	# cookie provided by the user and whitelist also some other required URLs
	<If "! %{HTTP_COOKIE} =~ /^auth_/ && \
		! %{REQUEST_URI} = '/${SITE}/check_mk/register_agent.py' && \
		! %{REQUEST_URI} = '/${SITE}/check_mk/deploy_agent.py' && \
		! %{REQUEST_URI} = '/${SITE}/check_mk/run_cron.py' && \
		! %{REQUEST_URI} = '/${SITE}/check_mk/webapi.py' && \
		! %{REQUEST_URI} = '/${SITE}/check_mk/automation.py' && \
		! %{REQUEST_URI} -strmatch '/${SITE}/check_mk/api/*' && \
		! %{QUERY_STRING} =~ /(_secret=|auth_|register_agent)/ && \
		! %{REQUEST_URI} =~ m#^/${SITE}/(omd/|check_mk/((images|themes)/.*\.(png|svg)|login\.py|.*\.(css|js)))# ">

		MellonIdPMetadataFile /opt/omd/sites/${SITE}/etc/apache/mellon/idp-metadata.xml
		MellonIdPPublicKeyFile /opt/omd/sites/${SITE}/etc/apache/mellon/idp-public-key.pem
		MellonSPCertFile /opt/omd/sites/${SITE}/etc/apache/mellon/mellon.cert
		MellonSPPrivateKeyFile /opt/omd/sites/${SITE}/etc/apache/mellon/mellon.key
		MellonEndpointPath "/${SITE}/mellon"
		MellonDefaultLoginPath "/${SITE}/check_mk/"

		Order allow,deny
		Allow from all

		MellonSecureCookie On
		MellonCookieSameSite None

		AuthType Mellon
		AuthName "Check_MK SAML Login"
		MellonEnable auth
		Require valid-user

		# Get Username
		# ADFS sends username as DOMAIN\username pair.
		# Checkmk just wants the username.
		RewriteEngine on
		RequestHeader set X-Remote-User "expr=%{REMOTE_USER}"
		RequestHeader edit X-Remote-User "^.*\\\(.*)$" "$1"

		# When SAML auth fails, show the login page to the user. This should only happen,
		# if e.g. the mellon cookie is lost/rejected or if the IDP is misconfigured.
		# A failed login at the IDP will not return you here at all.

    ErrorDocument 401 '<html> \
      <head> \
        <meta http-equiv="refresh" content="1; URL=/${SITE}/check_mk/login.py"> \
      </head> \
      <body> \
        SAML authentication failed, redirecting to login page. \
        <a href="/${SITE}/check_mk/login.py">Click here</a>. \
      </body> \
    </html>'

	</If>

	# This header is also needed after authentication (outside of the If clause)
	RequestHeader set X-Remote-User "expr=%{REMOTE_USER}"
	RequestHeader edit X-Remote-User "^.*\\\(.*)$" "$1"

</Location>

Anschließend starten Sie Apache neu:

OMD[mysite]:~/etc/apache/mellon$ omd restart apache

Zu guter Letzt laden Sie nun die dynamisch erstellten Mellon-Metadaten als XML-Datei herunter, um sie gleich im AD-Management importieren zu können:

OMD[mysite]:~/etc/apache/mellon$ wget https://myserver/mysite/mellon/metadata -o metadata.xml

3. Active Directory konfigurieren

Um einen Relying Party Trust in AD FS anzulegen, gehen Sie wie folgt vor:

Starten Sie die AD-FS-Oberfläche:

saml adfs 01

Klicken Sie auf Add Relying Party Trust:

saml adfs 02

Belassen Sie die Option auf Claims aware und fahren Sie mit dem Start-Knopf fort:

saml adfs 03

Wählen Sie nun Import data about the relying party from a file und geben Sie die eben heruntergeladene XML-Datei an:

saml adfs 04

Die AD FS Management-Warnung können Sie getrost ignorieren:

saml adfs 05

Unter Specify Display Name geben Sie nun Checkmk als Namen ein:

saml adfs 06

Bei der Rechtevergabe können Sie zum Testen zunächst für Choose Access Control Policy den Wert Permit everyone wählen; später sollten Sie nach Permit specific group ändern.

saml adfs 07

Bestätigen Sie die Zusammenfassung unter Ready to Add Trust:

saml adfs 08

Bestätigen Sie abschließend den Finish-Dialog und behalten Sie das Häkchen bei Configure claims issuance policy for this application:

saml adfs 09

Wählen Sie den eben erstellten Relying Party Trust aus und starten Sie dann den Editor mit Edit Claim Issuance Policy…​ :

saml adfs 10

Fügen Sie im folgenden Dialog über Add Rule…​ eine neue Regel hinzu:

saml adfs 11

Im ersten Schritt Select Rule Template wählen Sie Transform an Incoming Claim und bestätigen:

saml adfs 12

Im zweiten Schritt Configure Rule setzen Sie folgende Werte:

  • Incoming claim type: Windows account name

  • Outgoing claim type: Name ID

  • Outgoing name ID format: Transient Identifier

saml adfs 13

Damit ist auch die AD-FS-Konfiguration abgeschlossen. FS kann nun aus der Windows-Authentifizierung die Authentifizierung für Checkmk ableiten, das Sie im nächsten Schritt anweisen, Nutzer über HTTP-Anfragen zu authentifizieren.

4. Checkmk konfigurieren

In Checkmk müssen Sie nun nur noch unter Setup > General > Global Settings > User Interface > Authenticate users by incoming HTTP requests bei Current settings die Option Activate HTTP header authentication aktivieren:

saml adfs cmk

5. Weitere IDPs

Die folgenden Abschnitte beschreiben lediglich die Konfiguration von Mellon/Apache für unterschiedliche, bereits laufende IDPs. Die Anbindung in Checkmk selbst beschränkt sich jeweils auf den letzten Schritt aus der ausführlichen AD-FS-Anleitung.

5.1. Azure AD

Wenn Azure AD als IDP fungiert, ergeben sich einige Änderungen, beispielsweise kann der Nutzername direkt gesetzt werden, ohne umgeschrieben zu werden.

Voraussetzungen für die folgende Beispielkonfiguration:

  • UserPrincialName in LDAP-Verbindung als Identifier setzen (weitere Informationen bei LDAPwiki.com).

  • Custom Enterprise App in Azure AD mit UserPrincialName als 'name'-Attribut - mehr in der Microsoft-Dokumentation).

Hier eine Beispielkonfiguration:

~/etc/apache/conf.d/auth.conf
#Set this to the Name of your Checkmk site, e.g.
# Define SITE mysite
Define SITE mysite

# ServerName from listen-ports.conf needs to be overwritten here
# and being set to the URL of the real server.
# auth_mellon uses this to generate the needed URLs in the metadata.
ServerName https://myserver

# Load the module.
<IfModule !mod_auth_mellon.c>

	LoadModule auth_mellon_module /omd/sites/${SITE}/lib/apache/modules/mod_auth_mellon.so

</IfModule>

# Only enable this for debugging purposes
# MellonDiagnosticsFile /opt/omd/sites/${SITE}/tmp/mellon_diagnostics.log
# MellonDiagnosticsEnable On

<Location /${SITE}>

	# Use SAML auth only in case there is no Check_MK authentication
	# cookie provided by the user and whitelist also some other required URLs.
   <If "! %{HTTP_COOKIE} =~ /^auth_/ && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/register_agent.py' && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/webapi.py' && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/run_cron.py' && \
	! %{REQUEST_URI} = '/${SITE}/check_mk/automation.py' && \
        ! %{REQUEST_URI} -strmatch '/${SITE}/check_mk/api/*' && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/deploy_agent.py' && \
        ! %{QUERY_STRING} =~ /(_secret=|auth_|register_agent)/ && \
		! %{REQUEST_URI} =~ m#^/${SITE}/(omd/|check_mk/((images|themes)/.*\.(png|svg)|login\.py|.*\.(css|js)))# ">

        RequestHeader unset X-Remote-User
        MellonIdPMetadataFile /opt/omd/sites/${SITE}/etc/apache/mellon/idp-metadata.xml
        # Azure-AD-specific: Not needed because in metadata:
        #MellonIdPPublicKeyFile /opt/omd/sites/${SITE}/etc/apache/mellon/idp-public-key.pem
        MellonSPCertFile /opt/omd/sites/${SITE}/etc/apache/mellon/mellon.cert
        MellonSPPrivateKeyFile /opt/omd/sites/${SITE}/etc/apache/mellon/mellon.key
        MellonEndpointPath "/${SITE}/mellon"
        MellonDefaultLoginPath "/${SITE}/check_mk/"

		Order allow,deny
		Allow from all

		MellonSecureCookie On
		MellonCookieSameSite None

		AuthType Mellon
		MellonEnable auth
		require valid-user

        # Azure-AD-specific:
        # Get Username
        # If your assertion offers the username for Check_MK in an attribute you can set it directly as the remote user (REMOTE_USER):
        MellonUser "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
        RequestHeader set X-Remote-User "%{MELLON_http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name}e" env=MELLON_http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name

        # When SAML auth fails, show the login page to the user. This should only happen, if e.g. the mellon cookie is lost/rejected or if the IDP is misconfigured.
        # A failed login at the IDP will not return you here at all.
        ErrorDocument 401 '<html> \
          <head> \
            <meta http-equiv="refresh" content="1; URL=/${SITE}/check_mk/login.py"> \
          </head> \
          <body> \
            SAML authentication failed, redirecting to login page. \
            <a href="/${SITE}/check_mk/login.py">Click here</a>. \
          </body> \
        </html>'

	</If>

	# Azure-AD-specific:
	# This header is also needed after authentication (outside of the If clause)
	RequestHeader set X-Remote-User "%{MELLON_http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name}e" env=MELLON_http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name

</Location>

5.2. NetIQ Access Manager

Wenn NetIQ Access Manager als IDP fungiert, ergeben sich einige Änderungen, beispielsweise kann der Nutzername direkt gesetzt werden, ohne umgeschrieben zu werden.

Hier eine Beispielkonfiguration:

~/etc/apache/conf.d/auth.conf

# Set this to the Name of your Checkmk site, e.g.# Define SITE mysite
# Define SITE mysite
Define SITE mysite

# ServerName from listen-ports.conf needs to be overwritten here
# and being set to the URL of the real server. auth_mellon uses this to generate the needed URLs in the metadata.

ServerName https://myserver.mydomain.tld

# Load the module.
<IfModule !mod_auth_mellon.c>

	LoadModule auth_mellon_module /omd/sites/mysite/lib/apache/modules/mod_auth_mellon.so

</IfModule>

# Only enable this for debugging purposes
#MellonDiagnosticsFile /opt/omd/sites/${SITE}/tmp/mellon_diagnostics.log
#MellonDiagnosticsEnable On

<Location /${SITE}>

	# Use SAML auth only in case there is no Check_MK authentication
	# Cookie provided by the user and whitelist also some other required URLs.

    <If "! %{HTTP_COOKIE} =~ /^auth_/ && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/register_agent.py' && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/run_cron.py' && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/deploy_agent.py' && \
        ! %{REQUEST_URI} = '/${SITE}/check_mk/webapi.py' && \
        ! %{REQUEST_URI} -strmatch '/${SITE}/check_mk/api/*' && \
        ! %{QUERY_STRING} =~ /(_secret=|auth_|register_agent)/ && \
		! %{REQUEST_URI} =~ m#^/${SITE}/(omd/|check_mk/((images|themes)/.*\.(png|svg)|login\.py|.*\.(css|js)))# ">

        MellonIdPMetadataFile /opt/omd/sites/${SITE}/etc/apache/mellon/idp-metadata.xml
        # NetIQ-specific: Not needed because in metadata:
        #MellonIdPPublicKeyFile /opt/omd/sites/${SITE}/etc/apache/mellon/idp-public-key.pem
        MellonSPCertFile /opt/omd/sites/${SITE}/etc/apache/mellon/mellon.cert
        MellonSPPrivateKeyFile /opt/omd/sites/${SITE}/etc/apache/mellon/mellon.key
        MellonEndpointPath "/${SITE}/mellon"
        MellonDefaultLoginPath "/${SITE}/check_mk/"

		Order allow,deny
		Allow from all

		MellonSecureCookie On
		MellonCookieSameSite None

		AuthType Mellon
		MellonEnable auth
		require valid-user


        # NetIQ-specific:
        # Even though it is set as 'optional' in https://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf
        # a NetIQ Access Manager requires it to be set.
        # Specified in oasis link above - line 396
        MellonOrganizationName "<countrycode>" "<your organisation name>"
        # Specified in oasis link above - line 443 / 452
        MellonOrganizationURL  "<countrycode>" "<your organisation url>"
        # Specified in oasis link above - line 454
        MellonOrganizationDisplayName "<countrycode>" "<your organisation display name>"

        # NetIQ-specific:
        # If your assertion offers the username for Check_MK in an attribute you can set it directly as the remote user (REMOTE_USER)
        MellonUser "myusername"

        # NetIQ-specific:
        # If the assertion does contain the username (and was set to MellonUser) then you can set the header directly.
        RequestHeader set X-Remote-User "expr=%{REMOTE_USER}"

    # When SAML auth fails, show the login page to the user. This should only happen,
    # if e.g. the mellon cookie is lost/rejected or if the IDP is misconfigured.
    # A failed login at the IDP will not return you here at all.
        ErrorDocument 401 '<html> \
          <head> \
            <meta http-equiv="refresh" content="1; URL=/${SITE}/check_mk/login.py"> \
          </head> \
          <body> \
            SAML authentication failed, redirecting to login page. \
            <a href="/${SITE}/check_mk/login.py">Click here</a>. \
          </body> \
        </html>'

# This header is also needed after authentication (outside of the If clause)
RequestHeader set X-Remote-User "expr=%{REMOTE_USER}"

</Location>
Auf dieser Seite