Menu

Icinga Web 2 Single Sign On

Nachdem ich für den SSH Zugriff auf einigen Server bereits Singel Sign On (SSO) eingerichtet hatte, sind jetzt die ersten Webdienste dran. Da ich als Webserver eigentlich nginx bevorzuge, war der erste Plan natürlich den SSO Zugriff über nginx zu lösen. Allerdings ist die Umsetzung nicht ganz so trivial wie vermutet.

Für Kerberos SSO mittels nginx wird ein 3rd-Party-Modul benötigt. Das Modul ist aber weder im Standardpaket noch im Paket nginx-extras enhalten. Prinzipiell bleiben jetzt zwei Möglichkeiten ein Modul zu laden, entweder dynamisch oder durch eincompilieren.

Debian 8 liefert mit den offiziellen Paketquellen nginx in der Version 1.6.2 aus, dynamische Module werden aber erst ab der Version 1.9 unterstützt. Möchte man das Modul nutzen bleibt einem nichts anderes über als nginx selbst zu compilieren und das Modul direkt zu integrieren. Ich verzichte wenn möglich auf selbst compilierte Programme, da es den Updateprozess verkompliziert und ein manuelles eingreifen erfordert. Aus diesem Grund habe ich mich entscheiden SSO über apache2 zu realisieren. Zusätzlich zum Kerberos SSO wird apache mittels LDAP prüfen, ob der Benutzer sich in einer Gruppe befindet bevor es die Verbindung zulässt. An dieser Stelle möchte ich mich bei NETWAYS für die schöne Doku bedanken.

Ich gehe für diesen Beitrag davon aus, dass ihr Icinga Web 2 und apache bereits installiert und vollständig eingerichtet habt.

Im ersten Schritt müssen einige benötigte apache-Module aktiviert werden.

  1. a2enmod auth_kerb
  2. a2enmod ldap
  3. a2enmod authnz_ldap

Außerdem muss die Datei /etc/apache2/conf-available/icingaweb2.conf angepasst werden. Es werden folgende zusätzliche Zeilen benötigt:

  1. <Location / >
  2.         AuthType Kerberos
  3.         AuthName "Kerberos Login"
  4.         KrbMethodK5Passwd Off
  5.         KrbServiceName http/fqdn.example.com
  6.         KrbAuthRealms EXAMPLE.COM
  7.         Krb5KeyTab /etc/apache2/krb5.keytab
  8.         KrbLocalUserMapping On
  9.         Require valid-user
  10. </Location>

Damit der Kerberos Dienst sich gegenüber dem Client identifizieren kann, benötigen wir wieder einen Dienst-Principal. Diesen schreiben wir auf dem UCS (Univention Corporate Server) DC in ein keytab File und übertragen dieses auf den Webserver.

  1. ssh dc.rknet.org
  2. samba-tool domain exportkeytab /tmp/krb5.keytab --principal "http/fqdn@REALM"

Achtet darauf, dass ihr dem Benutzer mit dem der Webserver läuft (www-data) Leserechte auf die keytab gebt. Um die Änderungen wirksam zu machen, muss apache neugestartet werden.

  1. systemctl restart apache2

Jetzt müssen wir Icinga Web noch mitteilen, dass für die Authentifizierung eine externe Anwendung verantwortlich ist. Dazu muss in der Datei /etc/icingaweb2/authentication.ini folgendes ergänzt werden.

  1. [autologin]
  2. backend = external

An dieser Stelle könnten wir eigentlich aufhören, SSO sollte jetzt bereits funktionieren.

Wir gehen aber noch einen Schritt weiter, und kontrollieren vor der Anmeldung die Gruppenmitgliedschaft des Benutzers. Dazu müssen wir erneut die Datei /etc/apache2/conf-available/icingaweb2.conf anpassen:

  1. <Location / >
  2.         AuthType Kerberos
  3.         AuthName "Kerberos Login"
  4.         KrbMethodK5Passwd Off
  5.         KrbServiceName http/fqdn.example.com
  6.         KrbAuthRealms EXAMPLE.COM
  7.         Krb5KeyTab /etc/apache2/krb5.keytab
  8.         KrbLocalUserMapping On
  9.  
  10.         KrbMethodNegotiate On
  11.         AuthLDAPUrl "ldap://dc.example.com:7389/dc=example,dc=com?uid"
  12.         AuthLDAPBindDN "uid=[user],cn=users,dc=example,dc=com"
  13.         AuthLDAPBindPassword "[password]"
  14.         Require ldap-group cn=monitoring-admin,cn=groups,dc=rknet,dc=org
  15. </Location>

Nach dem Neustart von apache wird jetzt zusätzlich geprüft ob sich der Benutzer in der Gruppe monitoring-admin befindet.

Jetzt bleibt eigentlich nur noch ein Problem. Was passiert mit Clients die kein Kerberos Ticket haben (z. B. Smartphones)? Richtig, diese bekommen beim Aufruf die Fehlermeldung Unautorized (401) und haben auch keine Chance sich anzumelden.

Das Problem lässt sich aber durch zwei verschiedene Aliase (/sso und /manual) lösen. Der Ablauf stellt sich dann folgendermaßen dar: Jeder Request wird als erstes zu /sso umgeleitet und ein Kerberos Login versucht, schlegt das fehl (Error 401) wird die Anfrage an /manual umgeleitet und die die Anmeldemaske von Icinga Web aufgerufen.

Hier die komplette Konfiguration:

  1. # LDAP Verbindung über StartTLS aktivieren
  2. LDAPTrustedMode TLS
  3. LDAPTrustedGlobalCert CA_BASE64 /etc/apache2/CAcert.pem
  4.  
  5. <VirtualHost *:80>
  6.     ServerName icinga.example.com
  7.  
  8.     RewriteEngine On
  9.     RewriteCond %{HTTPS} !=on
  10.     RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
  11. </VirtualHost>
  12.  
  13. <VirtualHost *:443>
  14.     SSLEngine on
  15.     ServerName icinga.example.com
  16.     DocumentRoot /usr/share/icingaweb2/public
  17.  
  18.     Alias /sso "/usr/share/icingaweb2/public"
  19.     Alias /manual "/usr/share/icingaweb2/public"
  20.  
  21.    # Alle Requests umleiten
  22.     RedirectMatch ^/$ /sso
  23.  
  24.     <Location /sso >
  25.         AuthType Kerberos
  26.         AuthName "Kerberos Login"
  27.         KrbMethodK5Passwd Off
  28.         KrbServiceName http/fqdn.example.com
  29.         KrbAuthRealms EXAMPLE.COM
  30.         Krb5KeyTab /etc/apache2/krb5.keytab
  31.         KrbLocalUserMapping On
  32.  
  33.         KrbMethodNegotiate On
  34.         AuthLDAPUrl "ldap://dc.example.com:7389/dc=example,dc=com?uid"
  35.         AuthLDAPBindDN "uid=[USER],cn=users,dc=example,dc=com"
  36.         AuthLDAPBindPassword "[PASSWORD]"
  37.         Require ldap-group cn=monitoring-admin,cn=groups,dc=rknet,dc=org
  38.         ErrorDocument 401 '<html> \
  39.         <meta http-equiv="refresh" content="0; URL=/manual"> \
  40.         <body>Kerberos authentication did not pass.</body></html>'
  41.     </Location>
  42.  
  43.     <Directory "/usr/share/icingaweb2/public">
  44.         Options SymLinksIfOwnerMatch
  45.         AllowOverride None
  46.  
  47.         SetEnv ICINGAWEB_CONFIGDIR "/etc/icingaweb2"
  48.  
  49.         EnableSendfile Off
  50.  
  51.         <IfModule mod_rewrite.c>
  52.                 RewriteEngine on
  53.                 # mehrere RewriteBases werden nicht unterstützt
  54.                 # wir  benötigen aber sowohl /sso als auch /manual als RewriteBase
  55.                 RewriteBase /
  56.                 # das wird mit dieser Rewrite Regel realisiert
  57.                 # nicht schön aber funktional
  58.                 RewriteCond %{REQUEST_FILENAME} !-f
  59.                 RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
  60.                 RewriteRule ^.*$ %2index.php [QSA,L]
  61.         </IfModule>
  62.  
  63.         <IfModule !mod_rewrite.c>
  64.                 DirectoryIndex error_norewrite.html
  65.                 ErrorDocument 404 /error_norewrite.html
  66.         </IfModule>
  67.     </Directory>
  68.  
  69.     ErrorLog /var/log/apache2/icingaweb2_error.log
  70.     LogLevel error
  71.  
  72. </VirtualHost>

Euch hat der Beitrag gefallen, ihr habt Fragen oder Anregungen? Hinterlasst mir einen Kommentar oder diskutiert im OSBN-Chat.

Kommentare

Linear Verschachtelt

Noch keine Kommentare

Kommentar schreiben

Die angegebene E-Mail-Adresse wird nicht veröffentlicht, sondern nur für eventuelle Benachrichtigungen verwendet.
Die Formatierung der Kommentare ist über Markdown möglich.
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.
Gravatar Autoren-Bilder werden unterstützt.
Markdown-Formatierung erlaubt