Konfiguration eines bestehenden AWS ECS Clusters von HTTP zu HTTPS
Unsere Kunden setzen zunehmend auf die Cloud. Um unser Wissen in diesem Bereich zu vertiefen, entschieden wir uns eine eigens entwickelte Anwendung in der Cloud, exemplarisch auf Amazon Web Services, zu hosten. Ziel war es entsprechendes Know-how aufzubauen und zu vertiefen, um unsere Kunden zukünftig auch in diesem Themenbereich angemessen unterstützen zu können.
Im Zuge der Einarbeitung zum Thema AWS
kamen wir nach kurzer Zeit an einem Punkt, wo wir zwar unsere Anwendung erfolgreich in ein Cluster einbinden konnten, aber dieses nicht gesichert war. Außerdem war der Zugriff über eine bereits bestehende Domain nicht möglich.
Also schnell gegoogelt, irgendjemand wird ja schon mal das gleiche Problem gehabt haben.
Und in der Tat, es kamen schnell ein paar Tutorials zu Vorschein, die auf dem ersten Blick vielversprechend waren.
Aber wie es bei so vielen Tutorials ist, sind diese halt wirklich auf einen schnellen Einstieg begrenzt. im Normalfall deployed man halt nicht einen Container, sondern einen ganzen Stack, der auch noch miteinander kommuniziert.
Nach einiger Recherche und vielen Versuchen haben wir einen Lösungsansatz gefunden, der zumindest für uns für das Erste zufriedenstellend ist und den wir an dieser Stelle mit euch teilen möchten.
Vielleicht hilft es ja dem einen oder anderen, oder vielleicht bringt es zumindest jemanden zum Schmunzeln, da er vielleicht schon mit Tools wie Terraform
oder Ansible
gearbeitet hat.
Ausgangssituation
Mit Hilfe eines Skriptes unter Benutzung der AWS ECS-CLI wurde bereits ein Cluster erzeugt, das im Wesentlichen aus einer EC2 Instanz, einem Service und einer Aufgabendefinition besteht.
Diese Aufgabendefinition wurde mit Hilfe einer docker-compose.yml erzeugt.
-
nginx : dient als Reverse Proxy
-
frontend : Create React App
-
service-a : Spring Boot App
-
service-b : Spring Boot App
Konfiguration von Nginx
Nginx dient uns als Reverse Proxy und soll den eingehenden Datenverkehr an die entsprechenden Container weiterleiten. Dazu wurde die default.conf
von nginx
wie folgt angepasst (wobei wir uns hier nur auf das erforderliche Mapping beziehen):
Das Dockerfile
für das Nginx Image sieht somit wie folgt aus:
Ziele
-
Weiterleitung über eine bestehende Domain auf den angegebenen Stack per
https
-
die Kommunikation erfolgt ausschließlich gesichert über
https
- zumindest von außen→ dazu später mehr -
http
wird also aufhttps
umgeleitet
AUF GEHTS
Um ans Ziel zu gelangen, müssen wir die folgenden Schritte ausführen:
- in der Sicherheitsgruppe unserer EC2 - Instanz die eingehenden Regeln dahin gehend anpassen, dass die Ports
80
und443
für jeden erreichbar sind - Erstellen bzw. importieren eines Zertifikats mit Hilfe des Amazon Certificate Mangers
- Erstellen einer Zielgruppe (Target Group) → was nichts anderes als unser bereits bestehendes Cluster ist
- Erstellen eines Loadbalancers, der den eingehenden Datenverkehr an unsere Zielgruppe weiterleitet
- Erstellen einer gehosteten Zone mit Hilfe von Amazons DNS-Web-Service Route 53
- Anpassen des Namens Servers bei unserer bestehenden Domain (in diesem Fall von Strato)
- Konfigurieren der Listener des Loadbalancers
Sicherheitsgruppe anpassen
- In EC2 unter Dashboard → Instances (ausgeführt) die zum zu konfigurierenden Cluster gehörende Instanz über Instance-ID die selektierten → Man gelangt zur Instance-Zusammenfassung
- Dort das Tab Sicherheit und dann die Sicherheitsgruppe auswählen
- Über Regeln für eingehenden Datenverkehr bearbeiten die Ports für 80 und 443 freigeben
Erstellen des Zertifikats
- In AWS zum Amazon Certificate Manger kurz ACM wechseln und Ein öffentliches Zertifikat anfordern auswählen
-
Öffentliches Zertifikat auswählen
-
Domäne eingeben mit und ohne
www
- Präfix
-
Bei der Validierungsmethode kann man die für sich praktikabelste auswählen, wir haben uns in diesem Fall für die E-Mail-Validierung entschieden
-
Abschließend
Anfrage
starten -
Im Anschluss erhält man - bei Auswahl der E-Mail-Validierung- eine E-Mail an das Postfach seiner Domain die man nur noch bestätigen muss.
Erstellen der Zielgruppe
- Zu
EC2
wechseln und dort unterLastenausgleich
→Zielgruppen
auswählen - Create target group Screenshots zu sehen weiter verfahren
-
Target Type : Instances
-
Target group name hinzufügen
-
Protokoll und Port bleiben bei der Vorauswahl auf
Http
und Port80
-
VPC auswählen → aufpassen das es dasselbe ist wie bei der EC2 -Instanz des Clusters
-
Mit
Next
zum nächsten Step, wo man jetzt sein Cluster schon sehen sollte
-
das Cluster auswählen und per
Ìnclude as pending below
der Zielgruppe hinzufügen -
mit
Create Target Group
die Zielgruppe erstellen
Loadbalancer erstellen
-
Load Balancer
auswählen (EC2
→Lastausgleich
) -
Load Balancer erstellen
und dann den Schritten der folgenden Screenshots folgen
-
Mit
Create load balancer
die Erstellung des Load Balancers abschließen
Erstellen einer gehosteten Zone
-
In der Suche nach
Route 53
suchen und dorthin wechseln -
Gehostete Zone erstellen auswählen
-
Gehostete Zone Konfigurieren
- Eine gehostete Zone wird erstellt, die bereits 2 Datensätze enthält. Wichtig ist hier der
NS
Eintrag, der 4 Name-Server Einträge enthält, die wir später noch benötigen!
-
Nun müssen wir noch 2 weitere Datensätze hinzufügen, beide vom Typ
A-Record
. -
Datensatz 1 sieht wie folgt aus:
- Und hier Datensatz 2
-
Als Ergebnis erhalten wir die folgende Zone mit 4 eingetragenen Datensätzen
Vorhandene Domain mit gehosteter Zone in Route 53 verbinden
Bei unserer Domain müssen wir nun den Nameserver dahingehend ändern, dass die vorhandenen Einträge durch die Einträge von unserer gehosteten Zone in Route 53
ersetzt werden.
Dies ist in den folgenden Screenshots am Beispiel unserer Strato Domain abgebildet:
Das übernehmen der Änderungen kann etwas dauern, bei uns war es in der Regel nach spätestens 15 Minuten der Fall.
Konfigurieren der Listener unseres Loadbalancers
Zuerst fügen wir einen weiteren Listener hinzu. Dazu den Loadbalancer auswählen, im Tab auf Listener klicken und dann auf neuen Listener hinzufügen. Hier wählen wir Https
auf Port 443
, leiten an unsere Zielgruppe weiter und fügen anschließend noch unser am Anfang des Tutorials erstelltes Zertifikat hinzu.
Nun haben wir 2 Listener, einen für Port 80
auf Http
und einen für Port 443
auf Https
Abschließend konfigurieren wird die beiden noch einmal um:
- Zuerst für den Listener auf Port
80
. Dazu bei dem entsprechendem Listener aufRegeln bearbeiten/anzeigen klicken
und anschließend den Listener wie folgt konfigurieren:
-
Als Letztes den Listener für Port
443
wie folgt konfigurieren:1. bestehende Regel (1) bearbeiten
2. Regel hinzufügen und konfigurieren:
3. Regel hinzufügen und konfigurieren:
-
Der Listener für
`Https
sollte dann so aussehen:
-
Und das Ergebnis in der Loadbalancer Übersicht ungefähr so
Geschafft!
Sämtliche Requests von example.com
werden auf den Http - Listener weitergeleitet und sind somit abgesichert. Sämtliche Kommunikation hinter dem Loadbalancer - sprich die Docker Container - können weiterhin per Http
kommunizieren!
Interne Requests gehen aber an HTTPS
. Ein Request vom Frontend zum z.B. service-a
sähe folgendermaßen aus: