Nachdem ich mich zuletzt in den Sänften Apples ausgeruht habe, geht es heute zurück ans eingemachte – oder besser gesagt: Back to the Roots! Selbst als alter Icinga Web 2– und Modulentwickler habe ich noch längst nicht alle Vorzüge dieses Feldes beansprucht.

Einer davon ist die Möglichkeit, alles Mögliche für die Authentifizierung herzunehmen. Einzige Voraussetzung: der Webserver muss mitspielen. Manche Authentifizierungsverfahren gelten als sicher, andere nur wenn das Passwort weise gewählt ist… aber zumindest eines ist todsicher: TLS (aka “SSL”) Client-Zertifikate. Die Vorteile liegen auf der Hand:

  • mit der folgenden Anleitung relativ einfach umzusetzen
  • Erstellung unsicherer Zertifikate (analog zu den Passwörtern) nicht möglich
  • keine geheimen/privaten Schlüssel werden während der Authentifizierung übertragen (kann man von Passwörtern nicht behaupten)
  • Unbefugte werden schon vom Webserver “abgefangen” und kommen gar nicht erst an Icinga Web 2 heran

Na dann riegeln wir mal ab…

Zertifikate erstellen

Sowohl der Webserver als auch jeder Client brauchen je ein TLS-Zertifikat, das von einer der Gegenseite vertrauenswürdigen Zertifizierungsstelle (CA) unterschrieben ist. Diese Unterschriften könnte ich einkaufen oder kostenlos beziehen, aber der Einfachheit halber erstelle ich mir für beide Seiten je eine CA und unterschreibe je ein Zertifikat.

Die Sänfte Apples bieten in der Schlüsselbundverwaltung einen Zertifikatsassistenten, aber auch der eingefleischte Linux-Sysadmin hat mit Openssl ein Umfangreiches Bordmittel zur Verfügung.

Server

Im Gegensatz zum Client müssen Nutzer beider Betriebssysteme darauf achten, dass das Server-Zertifikat über einen sog. “subjectAltName” verfügt. Sonst staunt man beim Aufbau der Umgebung nicht schlecht: Trotz Vertrauen in die CA und passendem commonName erkennt zumind. Google Chrome das Zertifikat nicht an.

Die hervorgehobenen Stellen müssen höchst wahrscheinlich an die eigene Umgebung angepasst werden – z.B. eine Domäne statt einer IP Adresse und damit auch CN_KIND=DNS.

openssl req -x509 -newkey rsa:4096 -subj '/CN=example com CA - server' -md5 -keyout ca-server.key -out ca-server.crt -nodes

CN_KIND=IP ; CN=172.28.128.3

openssl req -newkey rsa:4096 -subj "/CN=$CN" -keyout server.key -out server.csr -nodes

openssl x509 -req -in server.csr -sha512 -out server.crt -CA ca-server.crt -CAkey ca-server.key -CAcreateserial -extensions SAN -extfile <(printf '[SAN]\nsubjectAltName=%s:%s' "$CN_KIND" "$CN")

Client

Bis auf den hier nicht nötigen “subjectAltName” – das gleiche in grün.

openssl req -x509 -newkey rsa:4096 -subj '/CN=example com CA - client' -md5 -keyout ca-client.key -out ca-client.crt -nodes

openssl req -newkey rsa:4096 -subj '/CN=Alexander Klimov' -keyout client.key -out client.csr -nodes

openssl x509 -req -in client.csr -sha512 -out client.crt -CA ca-client.crt -CAkey ca-client.key -CAcreateserial

Kleines Easter-Egg am Rande: Es spielt keine Rolle, ob ein Root-CA-Zertifikat mit SHA512, MD5 oder handschriftlich signiert wurde, da es nur auf dessen Vorhandensein im eigenen Schlüsselbund ankommt.

Zertifikate importieren

Ein nicht offizielles Server-CA-Zertifikat und das eigene Client-Zertifikat muss natürlich in den Browser importiert werden. Dafür ist ein kleiner Zwischenschritt nötig:

alexanders-mbp:debian aklimov$ openssl pkcs12 -in client.crt -inkey client.key -export -out client.p12
Enter Export Password:
Verifying - Enter Export Password:
alexanders-mbp:debian aklimov$

“client.p12” (und evtl. “ca-server.crt”) kann anschließend in den Browser importiert werden. Leider ist ein temporäres Passwort unumgänglich, aber “123456” o.ä. geht auch.

Wer diesen Schritt verschleppt, fällt bei der Einrichtung von Icinga Web 2 auf die Nase: Entweder beschwert sich der Browser über eine “nicht sichere” Verbindung oder der Webserver weist die Verbindung ab.

Icinga Web 2 installieren

DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \
echo "deb http://packages.icinga.com/debian icinga-${DIST} main" >  /etc/apt/sources.list.d/${DIST}-icinga.list; \
echo "deb-src http://packages.icinga.com/debian icinga-${DIST} main" >>  /etc/apt/sources.list.d/${DIST}-icinga.list

wget -qO - https://packages.icinga.com/icinga.key | apt-key add -
apt update
apt install icingaweb2 -y

cp /vagrant/server.crt /etc/ssl/certs/todsicher.pem
cp /vagrant/server.key /etc/ssl/private/todsicher.pem
cp /vagrant/ca-client.crt /etc/ssl/certs/todsicher-ca.pem

a2dissite 000-default.conf
a2enmod ssl
a2enmod headers
vim /etc/apache2/sites-available/todsicher.conf
a2ensite todsicher.conf
service apache2 restart

Nachdem das Icinga-Repository hinzugefügt wurde, kann auch schon das Paket “icingaweb2” installiert werden. Dieses bringt den Apache-Webserver mit und integriert sich entsprechend. Darauf hin müssen die Zertifikate installiert und deren Verwendung konfiguriert werden.

/etc/apache2/sites-available/todsicher.conf

<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	RewriteEngine On
	RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

<VirtualHost *:443>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	SSLEngine on
	SSLCertificateFile /etc/ssl/certs/todsicher.pem
	SSLCertificateKeyFile /etc/ssl/private/todsicher.pem
	Header always set Strict-Transport-Security "max-age=2678400"

	SSLCACertificateFile /etc/ssl/certs/todsicher-ca.pem
	SSLVerifyClient require
	SSLVerifyDepth 1
	SSLUserName SSL_CLIENT_S_DN_CN
</VirtualHost>

Sollte jemand auf die Idee kommen, den Server mit HTTP anzusprechen, wird er bedingungslos auf HTTPS umgeleitet – und diese Tat auch nicht wiederholen.

Außerdem wird ein TLS-Client-Zertifikat verlangt, das von entsprechender CA unterschrieben sein muss. Dessen commonName wird im Erfolgsfall als Nutzername behandelt – und genau auf diesen Zug springt Icinga Web 2 auf…

Icinga Web 2 einrichten

Nun greift man via Browser auf Icinga Web 2 zu und richtet es wie gewohnt ein… naja, fast wie gewohnt…

Nachdem der Browser nach dem zu verwendenden Client-Zertifikat gefragt hat, grüßt die Anmeldemaske, die auf den Einrichtungsassistenten verweist. Dieser fordert wie zu erwarten den Einrichtungstoken. Nach dessen Eingabe habe ich ausnahmsweise sämtliche Module deaktiviert, da… dieser Blogpost eh schon viel zu lang ist. (Aber nur die Ruhe, wir haben’s schon fast.)

Nach einer kleinen Anpassung der PHP-Konfiguration und einem darauf folgenden Neustart des Webservers…

root@contrib-stretch:~# perl -pi -e 's~^;date\.timezone =.*?$~date.timezone = Europe/Berlin~' /etc/php/7.0/apache2/php.ini
root@contrib-stretch:~# service apache2 restart

… bestätigt auch schon die erste Ausnahme die Regel: Der Typ des Authentifizierungs-Backends ist auf “Extern” zu setzen, da dies der Webserver übernimmt. Die folgenden Einstellungen des Backends können bei dem voreingetragenen belassen werden. Wenn alles richtig konfiguriert wurde, schlägt der Assistent den bedienenden Benutzer als Administrator vor. Ab da bleiben nur noch die Formalitäten…

Fazit

Wer auf das Monitoring-System Zugriff hat, hat viel Macht.

Bernd Erk, NETWAYS CEO

Tja Bernd, auf mein Monitoring-System hat kein Unbefugter mehr Zugriff – todsicher.

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.