#spring-boot #ssl #heroku
#весенняя загрузка #ssl #heroku
Вопрос:
Пытаюсь запустить SpringBoot на Heroku с самозаверяющим сертификатом и включенным SSL. Вот мое приложение.yaml:
server:
ssl:
key-store-type: PKCS12
key-store: classpath:server-dev.p12
key-store-password: changeit
key-password: changeit
key-alias: server-dev
trust-store: classpath:root_CA-truststore.jks
trust-store-password: changeit
trust-store-type: JKS
client-auth: need
enabled: true
# forward-headers-strategy: tried native / framework, didn't help
use-forward-headers: true
Вот мой SecurityConfig
@EnableWebSecurity
@Component
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final X509PrincipalExtractorWithCertificateValidation x509PrincipalExtractorWithCertificateValidation;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.requiresChannel()
.requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null)
.requiresSecure()
.and()
.authorizeRequests()
.antMatchers("/private/api/v1/security/test")
.authenticated()
.and()
.x509()
.x509PrincipalExtractor(x509PrincipalExtractorWithCertificateValidation)
.userDetailsService(userDetailsService())
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.csrf()
.disable();
}
}
что бы я ни делал, все запросы получают 400
Вот журнал curl:
curl -kvI https://my-server.herokuapp.com/swagger-ui.html#/
* Trying 34.246.118.170...
* TCP_NODELAY set
* Connected to my-server.herokuapp.com (XXX.XXX.XXX.XXX) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Heroku, Inc.; CN=*.herokuapp.com
* start date: Jun 15 00:00:00 2020 GMT
* expire date: Jul 7 12:00:00 2021 GMT
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA
* SSL certificate verify ok.
> HEAD /swagger-ui.html HTTP/1.1
> Host: my-server.herokuapp.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 400
HTTP/1.1 400
< Server: Cowboy
Server: Cowboy
< Date: Tue, 18 Aug 2020 23:13:58 GMT
Date: Tue, 18 Aug 2020 23:13:58 GMT
< Connection: keep-alive
Connection: keep-alive
< Content-Type: text/plain;charset=UTF-8
Content-Type: text/plain;charset=UTF-8
< Via: 1.1 vegur
Via: 1.1 vegur
<
* Connection #0 to host my-server.herokuapp.com left intact
Что я делаю не так?
UPD Я включил отладку для встроенного в SpringBoot tomcat
2020-08-19T00:21:58.085035 00:00 app[web.1]: 00:21:58.084 [https-jsse-nio-30633-Acceptor] DEBUG o.a.tomcat.util.threads.LimitLatch - Counting up[https-jsse-nio-30633-Acceptor] latch=1
2020-08-19T00:21:58.085334 00:00 app[web.1]: 00:21:58.085 [https-jsse-nio-30633-exec-9] DEBUG o.a.tomcat.util.net.NioEndpoint - Error during SSL handshake
2020-08-19T00:21:58.085336 00:00 app[web.1]: java.io.IOException: Found an plain text HTTP request on what should be an encrypted TLS connection
2020-08-19T00:21:58.085337 00:00 app[web.1]: at org.apache.tomcat.util.net.SecureNioChannel.processSNI(SecureNioChannel.java:322)
2
Heroku по какой-то причине отправляет HTTP-трафик….
Ответ №1:
У меня была точно такая же проблема, как и у вас. Я также хотел настроить MTLS с помощью Spring Boot.
К сожалению, MTLS не поддерживается Heroku, поскольку соединения от маршрутизатора к серверным динамическим системам являются чистыми HTTP-запросами. Это немного трагично, но, похоже, вам нужно найти другое решение.
Смотрите здесь официальный ответ из раздела справки Heroku: