Sichere Entdeckung mit Spring Cloud Netflix Eureka

Das Erstellen eines standardmäßigen Erkennungsmechanismus auf der Grundlage von Spring Cloud Netflix Eureka ist ziemlich einfach. Dieselbe Lösung, die über eine sichere SSL-Kommunikation zwischen Discovery-Client und -Server aufgebaut ist, kann eine etwas fortgeschrittenere Herausforderung darstellen. Ich habe kein vollständiges Beispiel für eine solche Anwendung im Web gefunden. Lassen Sie uns versuchen, es ausgehend von der serverseitigen Anwendung zu implementieren.

1. Generieren Sie Zertifikate

Wenn Sie seit einigen Jahren Java-Anwendungen entwickeln, haben Sie wahrscheinlich schon von keytool gehört. Dieses Tool ist in Ihrem Verzeichnis ${JAVA_HOME}\bin verfügbar und dient der Verwaltung von Schlüsseln und Zertifikaten. Wir beginnen mit der Generierung des Schlüsselspeichers für die serverseitige Spring Boot-Anwendung. Hier ist der entsprechende Keytool-Befehl, der ein Zertifikat generiert, das in der JKS-Keystore-Datei mit dem Namen eureka.jks gespeichert ist.

1.png

2. Einrichten eines sicheren Erkennungsservers

Da der Eureka-Server in die Spring Boot-Anwendung eingebettet ist, müssen wir ihn mit Standard-Spring-Boot-Eigenschaften sichern. Ich habe die generierte Keystore-Datei eureka.jks im Klassenpfad der Anwendung abgelegt. Jetzt müssen Sie nur noch einige Konfigurationseinstellungen in der Datei „application.yml“ vorbereiten, die auf den Speicherort, den Typ und das Zugriffspasswort der Keystore-Datei verweisen.

Server:
Port: 8761
SSL:
aktiviert: wahr
Schlüsselspeicher: Klassenpfad:eureka.jks
Schlüsselspeicherpasswort: 123456
Vertrauensspeicher: Klassenpfad:eureka.jks
Trust-Store-Passwort: 123456
Schlüsselalias: eureka

3. Einrichten der bidirektionalen SSL-Authentifizierung

Wir werden unser Beispiel ein wenig komplizieren. Eine standardmäßige SSL-Konfiguration geht davon aus, dass nur der Client das Serverzertifikat überprüft. Wir erzwingen die Zertifikatsauthentifizierung des Clients auf der Serverseite. Dies kann erreicht werden, indem die Eigenschaft server.ssl.client-auth auf need gesetzt wird.

Server:
SSL:
client-auth: brauchen

Das ist noch nicht alles, denn wir müssen auch das Zertifikat des Clients zur Liste der vertrauenswürdigen Zertifikate auf der Serverseite hinzufügen. Lassen Sie uns also zuerst den Schlüsselspeicher des Clients mit demselben keytool-Befehl wie für den Schlüsselspeicher des Servers generieren.

2.png

Jetzt müssen wir Zertifikate aus generierten Schlüsselspeichern sowohl für die Client- als auch für die Serverseite exportieren.

3.png

Schließlich importieren wir das Zertifikat des Clients in den Keystore des Servers und das Zertifikat des Servers in den Keystore des Clients.

4.png

4. Ausführen eines sicheren Eureka-Servers

Die Beispielanwendungen sind auf GitHub im Repository sample-secure-eureka-discovery verfügbar. Nach dem Ausführen der Discovery-Service-Anwendung ist Eureka unter der Adresse verfügbar Server ist gesichert.

5.png

Nun, das Eureka-Dashboard ist manchmal ein nützliches Tool, also importieren wir den Schlüsselspeicher des Clients in unseren Webbrowser, um darauf zugreifen zu können. Wir müssen den Schlüsselspeicher des Clients vom JKS- in das PKCS12-Format konvertieren. Hier ist der Befehl, der die erwähnte Operation ausführt.

$ keytool -importkeystore -srckeystore client.jks -destkeystore client.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass 123456 -deststorepass 123456 -srcalias client -destalias client -srckeypass 123456 -destkeypass 123456 -noprompt

5. Anwendungskonfiguration des Kunden

Bei der Implementierung einer sicheren Verbindung auf der Clientseite müssen wir im Allgemeinen dasselbe tun wie im vorherigen Schritt – einen Schlüsselspeicher importieren. Dies ist jedoch nicht sehr einfach, da Spring Cloud keine Konfigurationseigenschaft bereitstellt, mit der Sie den Speicherort des SSL-Schlüsselspeichers an einen Erkennungsclient übergeben können. Erwähnenswert ist, dass der Eureka-Client den Jersey-Client nutzt, um mit der serverseitigen Anwendung zu kommunizieren. Es mag ein wenig überraschen, dass es sich nicht um Spring RestTemplate handelt, aber wir sollten uns daran erinnern, dass Spring Cloud Eureka auf dem Netflix OSS Eureka-Client aufbaut, der keine Spring-Bibliotheken verwendet.
Die HTTP-Basisauthentifizierung wird Ihrem Eureka-Client automatisch hinzugefügt, wenn Sie z. B. Sicherheitsanmeldeinformationen in die Verbindungs-URL einfügen. Für eine erweiterte Konfiguration, z. B. das Übergeben von SSL-Keystore an den HTTP-Client, müssen wir @Bean vom Typ DiscoveryClientOptionalArgs bereitstellen.
Das folgende Codefragment zeigt, wie die SSL-Verbindung für den Erkennungsclient aktiviert wird. Zuerst legen wir den Speicherort der Keystore- und Truststore-Dateien mit der Java-Systemeigenschaft javax.net.ssl.* fest. Anschließend stellen wir eine benutzerdefinierte Implementierung des Jersey-Clients basierend auf den Java-SSL-Einstellungen bereit und legen ihn für die DiscoveryClientOptionalArgs-Bean fest.

@Bohne
public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() löst NoSuchAlgorithmException aus {
DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs();
System.setProperty(“javax.net.ssl.keyStore”, “src/main/resources/client.jks”);
System.setProperty(“javax.net.ssl.keyStorePassword”, “123456”);
System.setProperty(“javax.net.ssl.trustStore”, “src/main/resources/client.jks”);
System.setProperty(“javax.net.ssl.trustStorePassword”, “123456”);
EurekaJerseyClientBuilder-Builder = new EurekaJerseyClientBuilder();
builder.withClientName(“Konto-Client”);
builder.withSystemSSLConfiguration();
builder.withMaxTotalConnections(10);
builder.withMaxConnectionsPerHost(10);
args.setEurekaJerseyClient(builder.build());
Argumente zurückgeben;
}

6. Aktivieren von HTTPS auf der Clientseite
Die im vorherigen Schritt bereitgestellte Konfiguration gilt nur für die Kommunikation zwischen Discovery-Client und Eureka-Server. Was ist, wenn wir auch HTTP-Endpunkte sichern möchten, die von der clientseitigen Anwendung bereitgestellt werden? Der erste Schritt ist ziemlich derselbe wie für den Erkennungsserver: Wir müssen den Schlüsselspeicher generieren und ihn mithilfe der Spring Boot-Eigenschaften in der Datei „application.yml“ festlegen.

Server:
Port: ${PORT:8090}
SSL:
aktiviert: wahr
Schlüsselspeicher: Klassenpfad: client.jks
Schlüsselspeicherpasswort: 123456
Schlüsselalias: Kunde

Während der Registrierung müssen wir den Eureka-Server „informieren“, dass die Endpunkte unserer Anwendung gesichert sind. Um dies zu erreichen, sollten wir die Eigenschaft eureka.instance.securePortEnabled auf true setzen und auch den nicht sicheren Port deaktivieren, der standardmäßig mit der Eigenschaft nonSecurePortEnabled aktiviert ist.

Eureka:
Beispiel:
nonSecurePortEnabled: false
securePortEnabled: wahr
sichererPort:

server.pÖrtstatusPageUrl:https://lÖcalhÖst:{server.port} statusPageUrl: https://localhost:

server.pÖrt/healthhÖmePageUrl:https://lÖcalhÖst:{server.port}/health homePageUrl: https://localhost:

7. Client-Anwendung ausführen

Schließlich können wir eine clientseitige Anwendung ausführen. Nach dem Start sollte die Anwendung im Eureka Dashboard sichtbar sein.

6.png

Alle Endpunkte der Client-Anwendung sind in Eureka unter dem HTTPS-Protokoll registriert. Ich habe auch die Standardimplementierung des Aktuator-Endpunkts /info überschrieben, wie im folgenden Codefragment gezeigt.

@Komponente
öffentliche Klasse SecureInfoContributor implementiert InfoContributor {

@Override
public void contribute(Builder builder) {
    builder.withDetail("hello", "I'm secure app!");
}

}
Jetzt können wir versuchen, den Endpunkt /info noch einmal zu besuchen. Sie sollten die gleichen Informationen wie unten sehen.

7.png

Wenn Sie alternativ versuchen, auf der Clientseite das Zertifikat festzulegen, dem die Serverseite nicht vertraut, wird beim Starten Ihrer Clientanwendung die folgende Ausnahme angezeigt.

8.png

Fazit

Die Sicherung der Verbindung zwischen Microservices und dem Eureka-Server ist nur der erste Schritt zur Sicherung des gesamten Systems. Wir müssen uns um eine sichere Verbindung zwischen Microservices und Konfigurationsserver und auch zwischen allen Microservices während der Kommunikation zwischen Diensten mit @LoadBalanced RestTemplate oder dem OpenFeign-Client kümmern. Beispiele für solche Implementierungen und viele mehr finden Sie in meinem Buch Frühlingswolke meistern.

Leave a Reply

Your email address will not be published.