Die Aufgabe
Gefordert war eine BizTalk Umgebung in der Cloud, die eingehende Daten aufbereitet und an ein Backend System weiterreicht. Damit die dafür genutzte VM nicht offen erreichbar ist, sollte die Architektur wie folgt aussehen:
Die BizTalk VM ist Teil eines virtuellen Netzwerks und stellt seine Web Services zum Empfangen der Daten über ein als WAF (Web Application Firewall) genutztes Application Gateway zur Verfügung. Dieses gibt, mit entsprechenden Policies, nur den Weg über die wirklich genutzten Ports frei und schützt die VM damit vor Zugriffen auf andere Dienste. Die WAF untersucht die Requests zudem auf diverse Angriffsszenarien nach OWASP Richtlinien. Zur Transportsicherung sollte die Kommunikation natürlich über HTTPS stattfinden.
Damit HTTPS funktioniert, benötigen wir ein von einer vertrauenswürdigen Stelle signiertes Zertifikat. Solch ein Zertifikat kann man bei diversen Anbietern fü̈r zum Teil dreistellige Beträge kaufen oder man nutzt das Angebot des Let's Encrypt Projekts. Let's Encrypt ist ein Dienst der Internet Security Research Group, die es sich zur Aufgabe gemacht hat, Zertifikate über einen automatisierten Vorgang kostenfrei zur Verfügung zu stellen. Dieser Prozess lässt sich dann in andere Dienste und Tools einbinden, um es Endnutzern zu ermöglichen, mit wenigen Klicks ein Zertifikat für ihre Web-Dienste zu deployen.
Perspektivisch soll damit ein vollverschlüsseltes Web geschaffen werden. Let's Encrypt agiert dabei als CA (Certificate Authority) und stellt Zertifikate selbst aus. Um die Chain-of-Trust zu wahren, sind diese von bereits als vertrauenswürdig eingestuften CAs cross-signed. Stand August 2018 wird dem Let's Encrypt Root Zertifikat aber auch von allen namhaften Systemen direkt vertraut, sodass es im Grunde keine Probleme mit den Zertifikaten geben sollte.
Können wir Let's Encrypt für Azure benutzen?
Wir wollten nun also evaluieren, ob wir statt einem Kauf-Zertifikat auch ein Let's Encrypt Zertifikat einsetzen können. Neben der kostenlosen Natur haben diese nämlich zusätzlich den Vorteil, dass man – einmal eingerichtet – das Zertifikatsmanagement einfach vergessen kann, da der Renewal-Prozess automatisch abläuft. Damit dieser auch wirklich umgesetzt wird, stellt Let's Encrypt nur Zertifikate mit einer Lebensdauer von drei Monaten aus.
Der erste Blick fiel so auf Azure selbst und die Möglichkeiten, die wir von Microsoft in dieser Hinsicht geboten bekommen. Leider gab es jedoch auch Ende 2018 noch keinen First-Level-Support für Let's Encrypt.
Zudem bindet Azure den Let's Encrypt Dienst nicht direkt ein, wie das so mancher Hoster bereits tut, und wie es aussieht, bleibt das wohl auch so. Es gibt einige Drittlösungen, die sich aber vornehmlich auf Azure Web Apps konzentrieren.
Aus dem Linux Umfeld kennt man das Certbot genannte Tool, welches als Cronjob läuft und – wenn nötig – über das ACME Protokoll ein neues Zertifikat abruft und automatisch den Webserver der Wahl konfiguriert. Aber gibt es etwas Vergleichbares für Windows? Eine kurze Recherche förderte das großartige win-acme Projekt auf GitHub zu Tage: Es kann über einen einfachen Wizard auf der Konsole bedient werden, sich für den Renewal-Prozess im Task Scheduler registrieren und ist auch in der Lage, dafür IIS entsprechend zu konfigurieren.
So weit so gut. Nun haben wir aber noch das Application Gateway, welches die VM absichert. Und dieses muss sowohl in seiner eigentlichen Funktion als Load Balancer als auch als WAF in der Lage sein, HTTPS Verbindungen zu terminieren, um Anfragen an verschiedene Backends weiterreichen bzw. die Requests auf Angriffsvektoren untersuchen zu können. Das bedeutet, dass wir nicht einfach den IIS in der VM mit dem Zertifikat versehen können, sondern das Zertifikat im Application Gateway selbst platzieren müssen.
win-acme + PowerShell = Profit!
Das win-acme Tool erlaubt aber verschiedenste Konfigurationen, sodass wir den IIS lediglich als Vehikel für den Challenge-Response Mechanismus des ACME Verfahrens nutzen können, um die Eigentümerschaft an dem abzusichernden Hostnamen nachzuweisen. Dem anschließenden Zertifikatabruf können wir dann ein eigenes Script folgen lassen, welches das Zertifikat in unserer Application Gateway Instanz installiert. Azure bietet mehrere umfangreiche Schnittstellen zum Administrieren von Resourcen an, für unsere Zwecke bot sich die Azure PowerShell Integration an, die mittels Install-Module -Name AzureRM -AllowClobber installiert wird.
Das fertige Script, welches seit Version v1.9.12.2 Bestandteil des win-acme Projekts ist, kann über die Wizard Konfiguration eingebunden werden, damit es nach einem Renewal-Vorgang automatisch auch das Application Gateway aktualisiert. Der Aufruf geschieht über den mitgelieferten PowerShell Scripthelper.
./Scripts/PSScript.bat
der den Pfad zum PowerShell Script als ersten Parameter erhält. Alle weiteren Parameter werden an das Script weitergereicht. Der minimale Aufruf sieht wie folgt aus:
./Scripts/ImportAzureApplicationGateway.ps1 "BeispielResourceGroupName" "BeispielApplicationGatewayName" "{0}" "{1}" "{2}"
Die Platzhalter in geschweiften Klammern werden von win-acme mit folgenden Werten ersetzt:
{0} - Name of the renewal
{1} - The .pfx password as specified in the settings.config file
{2} - Full path of the .pfx file
Weitere Parameter können der Dokumentation in der Scriptdatei entnommen werden.
Das Passwort ist in der Standardkonfiguration von win-acme leer. Es kann aber auch ein Passwort gesetzt werden, mit dem das Zertifikat verschlüsselt wird. Dies ist notwendig, um das Zertifikat über das Azure Portal hochzuladen. Über das Script funktioniert beides.
Beim ersten Durchlauf werden die benötigten Einstellungen im Application Gateway für Frontend Port, HTTP Einstellungen, Listener und Rules automatisch gesetzt. Mit den optionalen Parametern des Scripts können die Namen der erstellenden Einträge gesteuert werden. Alle weiteren Aufrufe aktualisieren nur noch das vorhandene Zertifikat.
Damit das Update in Azure gelingt, muss zuerst eine Verbindung aufgebaut und gespeichert werden:
# Verbinden um Context zu erstellen - zeigt Login-DialogConnect-AzureRmAccount# oder verbinden auf Mandanten bzw. andere SubscriptionConnect-AzureRmAccount -TenantId "00000000-0000-0000-0000-000000000000"Connect-AzureRmAccount -Subscription "MeineSubscription"# [!] Context über Sessions hinweg speichern, damit der Renewal Task das Application Gateway updaten kannEnable-AzureRmContextAutosave# KontrolleGet-AzureRmContext
Zu beachten ist, dass der Kontext für den aktuellen Windows-Nutzer gesetzt wird und daher der win-acme Task im Scheduler mit dem gleichen Nutzer ausgeführt werden muss.
Konfiguration mit mehreren VMs im Backend
In unserem Use Case haben wir nur eine einzige VM im Application Gateway Backend Pool. Was aber, wenn wir mehrere VMs oder ein VM Scaleset als Backend verwenden und nicht vorhersehen können, an welche Instanz der Challenge-Request des Let's Encrypt Services gehen wird?
Wir können uns dazu einen gemeinsamen File Share zunutze machen, beispielsweise ein über Samba eingebundener Azure Files Storage. Wir müssen sicherstellen, dass folgende Punkte erfüllt sind:
- Der win-acme Agent ist auf jeder Maschine im Backend installiert.
- Der ConfigurationPath in der win-acme settings.config ist auf allen Maschinen auf den gemeinsamen Share gelegt worden. Das Tool kann dann auf einer Maschine konfiguriert werden.
- Der Renewal-Prozess nutzt eines der nicht-lokalen Validierungsplugins:
- Mit dem File system Plugin kann die Validierungsdatei auf dem gemeinsamen Share abgelegt werden. Das Plugin legt ebenfalls eine web.config an, sodass der Ausgabeorder als IIS Applikation zum Bereitstellen der Datei genutzt werden kann.
- Wenn Azure DNS genutzt wird, kann das Azure Plugin genutzt werden, um eine Validierung über einen TXT Record zu erreichen.
- Der Task im Task Scheduler ist auf allen Maschinen eingerichtet. Diese sollten am besten zu unterschiedlichen Zeiten laufen. Im Falle eines Clusters kann auch ein Clustered Task im Any Node Modus genutzt werden.
Die genaue Implementierung kann je nach Use Case anders aussehen. Mit den verschiedenen Konfigurationsmöglichkeiten des Tools sollten aber auch komplexe Szenarien abbildbar sein. Der oben geschilderte Weg ist daher als Beispiel zu verstehen.
Dies ist ein quiTeq-Tipp von QUIBIQ Hamburg.