Wie bereits erwähnt habe ich mir zuhause einen neuen Homeserver aufgebaut. Auf diesem laufen diverse Anwendungen, unter anderem diverse auf Spring-Boot basierende Microservices. Die Anwendung ist über einen eigenen Port aus dem Internet erreichbar. Der Traffic wird hierbei über Spring Cloud Gateway gefiltert und (sofern die Berechtigung vorliegt) auf die einzelnen Systeme weiter geroutet. Eine Herausforderung beim Aufbau lag darin herauszufinden, wie ich Spring-Boot mit SSL Zertifikat von LetsEncrypt unter Debian 10 absichern kann.
Spring Boot Anwendung hinter der FritzBox
Wie so viele setze auch ich zuhause eine FritzBox ein. Das ist an dieser Stelle allerdings eigentlich irrelevant, denn die benötigten Features liefert im Grunde jede Router. Damit der Homeserver hinter dem Router aus dem Internet erreichbar ist sind 2 Dinge notwendig:
- ein dynamischer DNS damit der Server über eine gleichbleibenden Hostnamen erreichbar ist
- die Weiterleitung der definierten Ports vom Router auf den Server
Sobald diese Konfiguration vorgenommen ist kann der Server, sofern denn alles richtig läuft, aus dem Internet auf dem freigeschalteten Port erreicht werden.
SSL Zertifikat für DynDNS Eintrag erzeugen
Soweit so gut, doch wie kommen wir nun dazu den Hostname, welchen wir über den DynDNS-Anbieter erhalten haben, über ein SSL Zertifikat zu schützen. Im Idealfall soll das Zertifikat dann auch noch kostenneutral verwaltet werden können. Das Stichwort hierfür lautet LetsEncrypt.
Über Let´s Encrypt ist es möglich SSL-Zertifikate mit sauberer Authentifizierungschain zu erstellen, sofern man denn der “Eigentümer des Servers” ist, also Administrativen Zugang zu selbigem hat. Das Vorgehen ist recht trivial und hier sehr plakativ beschrieben.
Certbot mit Let´s Encrypt auf Debian 10 einrichten
Die ersten Versuche eine geeignete Lösung zu finden brachten mich ein wenig zur Verzweiflung. Na klar man findet diverse Tutorials im Internet, diese sind jedoch meist für Ubuntu oder für altere Debian Versionen. Ab der Version 10 von Debian ist die auf den meisten Seiten beschriebene Installation des Certbot jedoch nicht mehr möglich da für diese Variante Debian nicht mehr unterstützt wird.
Nach ein wenig Recherche dann doch die Lösung, der Certbot muss lediglich über snap auf Debian installiert werden. Im Grund nur ein kleiner Umweg welcher genau so zum Ziel führt.
Nachdem nun das SSL Zertifikat für die “eigene” DynDNS-Domain eingerichtet wurde kann dieses in einen Keystore für die Java-Anwendung gelegt werden. Dies geschieht über den folgenden Befehl:
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name <applicationName> -CAfile chain.pem -caname root -passout pass:<keystorePass>
Da der Certbot das SSL-Zertifikat regelmäßig erneuert (min. alle 3 Monate) habe ich das Kommando zur Aktualisierung des Keystores in einen Cronjob gepackt. Somit sorge ich dafür dass der Keystore immer über das aktuellste Zertifikat verfügt.
Spring Boot mit SSL Zertifikat – Konfiguration
In Projekten in welchen ich Spring-Boot einsetze versuche ich, die eigentlichen Anwendungen nicht völlig für die Anwender zu öffnen. Ich habe mir angewöhnt, die einzelnen Microservices hinter einem Gateway “zu verstecken”. Dieses Gateway (Spring Cloud Gateway) nimmt alle Aufrufe entgegen, prüft Berechtigungen und Aufbau der Aufrufe. Somit werden nur gültige Requests an die einzelnen Services weiter geroutet.
Durch diesen Ansatz geht der gesamte Traffic über das Gateway. Dieses ist also die einzige Anwendung die direkt von außen aufgerufen werden kann. Somit genügt es, aus externer Sicht, dieses Gateway mit einem SSL-Zertifikat auszustatten. Um diese Konfiguration durchzuführen passen wir nun noch die application.yaml an und fügen den Bereich der SSL-Konfiguration hinzu:
server:
port: <portAusForward>
ssl:
enabled: true
key-store-type: PKCS12
key-store: /home/ssl/keystore/keystore.p12
key-store-password: <keystorePass>
key-alias: <applicationName>