In diesem Beitrag stelle ich zwei kleine Puppet-Module vor, die ich geschrieben habe, um ohne großen Aufwand Apache-VHosts mit einem SSL-Zertifikat, signiert durch die Certificate Authority aus meiner FreeIPA-Instanz, und Authentifizierung gegen Kerberos sowie Authorisierung aus FreeIPA abzusichern.

Das Ziel ist Single Sign On, so dass im ganzen Netzwerk alle Dienste die gleichen Accounts verwenden.

Weitere Beiträge in der Reihe:

Puppet-Module

Um den Aufwand gering, wiederholbar und verbesserbar zu halten, habe ich zwei kleine Puppet-Module geschrieben, die man in die eigene Umgebung einzubauen hat:

  • ipa um einen privaten Schlüssel zu erstellen, einen CSR einzureichen und das von der zentralen CA aus FreeIPA signierte Zertifikat abzuholen und automatisch verlängern zu lassen.
  • webserver um den Apache-Server für Authentifizierung und Autorisation über Kerberos vorzubereiten. Dazu wird Apache::Vhost aus dem puppetlabs/apache-Paket aufgerufen.

Verwendung

In die Node-Definition eines einzelnen Hosts oder in ein geeignetes Profil kann man jetzt ein einfaches Setup einbauen:

include ::apache
include ::webserver

file { 'ssl_directory':
  ensure => 'directory',
  path   => '/etc/apache2/ssl',
  owner  => 'root',
  group  => 'root',
  mode   => '0770'
}

$vhosts = lookup('webserver::vhost')
$vhosts.each do |$vhost| {
  if $vhost['vhost_name'] == $facts['fqdn'] {
    create_resources(::webserver::vhost, {$facts['fqdn'] => $vhost})
    ipa::sslcert { "${vhost['krb_servicename']}/${facts['fqdn']}":
      fname   => "/etc/apache2/ssl/${facts['fqdn']}",
      domain  => $facts['fqdn']
      service => $vhost['krb_servicename'],
    }
  }
}

So wird das Zertifikat für den FQDN des jeweiligen Hosts angefordert. Die notwendige Konfiguration eines VHosts muss noch im Hiera-Eintrag der Node oder für das Profil hinterlegt werden:

webserver::vhost:
  - vhost_name: vhost.domain.tld
    ssl: true
    kerberos: true
    web_user: 'sampleuser'
    krb_auth_realm: 'IPA.DOMAIN.TLD'
    krb_5keytab: '/etc/apache2/krb5_keytab'
    krb_servicename: 'http'
    docroot: '/var/www/vhost.domain.tld/html'

Jeder Host, der diese Funktionalität verwenden soll, muss bereits Mitglied in FreeIPA sein, außerdem muss der oben angegebene servicename als Prinzipal angelegt und für Apache lesbar hinterlegt werden:

$ kinit admin
$ ipa service-add http/vhost.domain.tld@IPA.DOMAIN.TLD
$ ipa-getkeytab -s ipaserver.domain.tld -p http/vhost.domain.tld -k /etc/apache2/krb5_keytab

Die feineren Konfigurationseinstellungen können in der README.md des Puppet-Modules nachgelesen werden.

Autorisierung

Die Authentifizierung ist jetzt mit Hilfe von Username und Kennwort möglich. Dadurch hat sich ein User jedoch lediglich als User ausgewiesen – ob User auf den so abgesicherten vHost zugreifen dürfen, ist jedoch eine andere Frage: Die der Autorisierung. Die Antwort darauf ist relativ einfach: nachdem das hier vorgestellte Setup FreeIPA über PAM anspricht, werden auch die HBAC-Regeln von FreeIPA berücksichtigt und durchgesetzt. Um den Zugang zu VHosts zu gewähren oder zu versagen muss also eine entsprechende Regel für das Service-Prinzipal in den HBAC-Einstellungen eingetragen werden.

Verwendung

Hat Puppet die beiden Module auf die jeweiligen Nodes verteilt, sollten HTTPS und Kerberos-Absicherung sofort funktionieren. Erfolgt der Zugriff von einem Gerät ohne Integration in Kerberos, wird (wie gewohnt) nach Username und Kennwort gefragt. Unterstützt der verwendete Webbrowser die Authentifizierung über Kerberos und verfügen lokal angemeldete User über Kerberos-Tickets, muss nicht mal ein Kennwort eingegeben werden.