From beb2c7e4ed5fac5e2c7df1939d5ca2b1ae538f76 Mon Sep 17 00:00:00 2001 From: X166952 Date: Fri, 24 Mar 2023 13:43:47 +0100 Subject: [PATCH 1/3] Be able to configure SSL client protocols and ciphers --- .../gateway/config/GrpcSslConfigurer.java | 9 ++++++++ .../gateway/config/HttpClientProperties.java | 22 +++++++++++++++++++ .../config/HttpClientSslConfigurer.java | 8 +++++++ .../ssl/ForcedClientProtocolsSSLTests.java | 14 ++++++++++++ ...pplication-forced-client-protocols-ssl.yml | 13 +++++++++++ 5 files changed, 66 insertions(+) create mode 100644 spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java create mode 100644 spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java index f3b6907e10..1b989f9dd0 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java @@ -24,6 +24,7 @@ import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.springframework.util.CollectionUtils; /** * @author Alberto C. Ríos @@ -53,6 +54,14 @@ private SslContext getSslContext() throws SSLException { sslContextBuilder.trustManager(getTrustedX509CertificatesForTrustManager()); } + if(!CollectionUtils.isEmpty(ssl.getProtocols())) { + sslContextBuilder.protocols(ssl.getProtocols()); + } + + if(!CollectionUtils.isEmpty(ssl.getCiphers())) { + sslContextBuilder.ciphers(ssl.getCiphers()); + } + return sslContextBuilder.keyManager(getKeyManagerFactory()).build(); } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java index 1071931bee..990b72f1df 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java @@ -416,6 +416,12 @@ public static class Ssl { /** Key password, default is same as keyStorePassword. */ private String keyPassword; + /** The protocols to enable, or empty to enable the default protocols. */ + private List protocols = new ArrayList<>(); + + /** The cipher suites to enable, in the order of preference. empty to use default cipher suites. */ + private List ciphers = new ArrayList<>(); + public String getKeyStorePassword() { return keyStorePassword; } @@ -456,6 +462,22 @@ public void setKeyPassword(String keyPassword) { this.keyPassword = keyPassword; } + public List getProtocols() { + return protocols; + } + + public void setProtocols(List protocols) { + this.protocols = protocols; + } + + public List getCiphers() { + return ciphers; + } + + public void setCiphers(List ciphers) { + this.ciphers = ciphers; + } + public List getTrustedX509Certificates() { return trustedX509Certificates; } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java index 0938a8914c..b9ba9caed1 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java @@ -19,6 +19,7 @@ import java.security.cert.X509Certificate; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.springframework.util.CollectionUtils; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; import reactor.netty.http.client.HttpClient; @@ -60,6 +61,13 @@ else if (ssl.isUseInsecureTrustManager()) { setTrustManager(sslContextBuilder, InsecureTrustManagerFactory.INSTANCE); } + if(!CollectionUtils.isEmpty(ssl.getProtocols())) { + sslContextBuilder.protocols(ssl.getProtocols()); + } + if(!CollectionUtils.isEmpty(ssl.getCiphers())) { + sslContextBuilder.ciphers(ssl.getCiphers()); + } + try { sslContextBuilder.keyManager(getKeyManagerFactory()); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java new file mode 100644 index 0000000000..73db8e3bd8 --- /dev/null +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java @@ -0,0 +1,14 @@ +package org.springframework.cloud.gateway.test.ssl; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +@DirtiesContext +@ActiveProfiles("forced-client-protocols-ssl") +public class ForcedClientProtocolsSSLTests extends SingleCertSSLTests { + +} diff --git a/spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml b/spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml new file mode 100644 index 0000000000..dc22e06ac0 --- /dev/null +++ b/spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml @@ -0,0 +1,13 @@ +spring: + cloud: + gateway: + httpclient: + ssl: + protocols: + - TLSv1.3 + - TLSv1.2 + - TLSv1.1 + - TLSv1 + ciphers: + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 From bd7f33553a3e69085cb00c256ea46fb9744d7128 Mon Sep 17 00:00:00 2001 From: X166952 Date: Fri, 24 Mar 2023 17:38:16 +0100 Subject: [PATCH 2/3] Code format --- .../gateway/config/GrpcSslConfigurer.java | 3 ++- .../config/HttpClientSslConfigurer.java | 6 +++--- .../ssl/ForcedClientProtocolsSSLTests.java | 20 +++++++++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java index 1b989f9dd0..79f6919522 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java @@ -18,13 +18,14 @@ import javax.net.ssl.SSLException; +import org.springframework.util.CollectionUtils; + import io.grpc.ManagedChannel; import io.grpc.netty.GrpcSslContexts; import io.grpc.netty.NettyChannelBuilder; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import org.springframework.util.CollectionUtils; /** * @author Alberto C. Ríos diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java index b9ba9caed1..5234a3ac6f 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java @@ -18,15 +18,15 @@ import java.security.cert.X509Certificate; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.util.CollectionUtils; + +import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.SslProvider; -import org.springframework.boot.autoconfigure.web.ServerProperties; - public class HttpClientSslConfigurer extends AbstractSslConfigurer { private final ServerProperties serverProperties; diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java index 73db8e3bd8..95dd20b99e 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java @@ -1,11 +1,27 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.gateway.test.ssl; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - @SpringBootTest(webEnvironment = RANDOM_PORT) @DirtiesContext @ActiveProfiles("forced-client-protocols-ssl") From 36868a82892775123ee11376540a667bef6477b7 Mon Sep 17 00:00:00 2001 From: X166952 Date: Fri, 24 Mar 2023 19:02:59 +0100 Subject: [PATCH 3/3] Code format --- .../cloud/gateway/config/GrpcSslConfigurer.java | 8 ++++---- .../cloud/gateway/config/HttpClientSslConfigurer.java | 10 +++++----- .../test/ssl/ForcedClientProtocolsSSLTests.java | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java index 79f6919522..892cc9123a 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java @@ -18,8 +18,6 @@ import javax.net.ssl.SSLException; -import org.springframework.util.CollectionUtils; - import io.grpc.ManagedChannel; import io.grpc.netty.GrpcSslContexts; import io.grpc.netty.NettyChannelBuilder; @@ -27,6 +25,8 @@ import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.springframework.util.CollectionUtils; + /** * @author Alberto C. Ríos */ @@ -55,11 +55,11 @@ private SslContext getSslContext() throws SSLException { sslContextBuilder.trustManager(getTrustedX509CertificatesForTrustManager()); } - if(!CollectionUtils.isEmpty(ssl.getProtocols())) { + if (!CollectionUtils.isEmpty(ssl.getProtocols())) { sslContextBuilder.protocols(ssl.getProtocols()); } - if(!CollectionUtils.isEmpty(ssl.getCiphers())) { + if (!CollectionUtils.isEmpty(ssl.getCiphers())) { sslContextBuilder.ciphers(ssl.getCiphers()); } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java index 5234a3ac6f..3d65376e03 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java @@ -18,15 +18,15 @@ import java.security.cert.X509Certificate; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.util.CollectionUtils; - import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import reactor.netty.http.Http11SslContextSpec; import reactor.netty.http.Http2SslContextSpec; import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.SslProvider; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.util.CollectionUtils; + public class HttpClientSslConfigurer extends AbstractSslConfigurer { private final ServerProperties serverProperties; @@ -61,10 +61,10 @@ else if (ssl.isUseInsecureTrustManager()) { setTrustManager(sslContextBuilder, InsecureTrustManagerFactory.INSTANCE); } - if(!CollectionUtils.isEmpty(ssl.getProtocols())) { + if (!CollectionUtils.isEmpty(ssl.getProtocols())) { sslContextBuilder.protocols(ssl.getProtocols()); } - if(!CollectionUtils.isEmpty(ssl.getCiphers())) { + if (!CollectionUtils.isEmpty(ssl.getCiphers())) { sslContextBuilder.ciphers(ssl.getCiphers()); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java index 95dd20b99e..e5ed445213 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java @@ -16,12 +16,12 @@ package org.springframework.cloud.gateway.test.ssl; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + @SpringBootTest(webEnvironment = RANDOM_PORT) @DirtiesContext @ActiveProfiles("forced-client-protocols-ssl")