Search code examples
spring-bootsslnettyspring-webfluxhttp2

Spring Boot 2 using Webflux, Netty and HTTP2, causing invalid certificate, possible misconfiguration


There is not much information that I've found in terms of configuration with Netty and Webflux using HTTP2.

I have used similiar configurations in the past without using reactor based spring boot modules, typically spring boot web. I have posted my steps below.

The problem is SSL not working correctly with Netty. Do I require more work in terms of setup? Hoping to get some pointers or examples to understand how to confiure this correctly please.

Generated Certificate

  • generate cert valid for local dev usage: mkcert localhost 127.0.0.1

  • output: certificate localhost+1.pem key localhost+1-key.pem

  • generate keystore with openssl: openssl pkcs12 -export -in localhost+1.pem -inkey localhost+1-key.pem -out keystore.p12 -name localdev

Application Files

application.yaml

server:
  port: 8443
  shutdown: graceful
  http2:
    enabled: true
  server:
    ssl:
      enabled: true
      #format of the keystore
      key-store-type: PKCS12
      #path to the keystore containing the cert
      key-store: classpath:keystore.p12
      #pw used to gen the keystore
      key-store-password: password
      #alias mapped to the certificate inside the keystore
      key-alias: localdev

build.gradle

plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id "com.google.osdetector" version "1.7.0"
}


dependencies {
    //HTTP2 Reactive Netty (auto-configured version via spring dependency BOM)
    runtimeOnly ("io.netty:netty-tcnative-boringssl-static::${osdetector.classifier}")

    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'  
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'

    runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
    runtimeOnly 'io.r2dbc:r2dbc-postgresql'

    
    testImplementation ('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'org.junit.jupiter:junit-jupiter-api'
    testImplementation 'io.projectreactor:reactor-test'
}

Running and Request

application running

2021-02-20 17:20:43.122  INFO 1 --- [main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port 8443
2021-02-20 17:20:43.143  INFO 1 --- [main] d.c.test.store.Application               : Started Application in 6.655 seconds (JVM running for 7.826)

curl request

curl --cert --http2 localhost+1.pem --key localhost+1-key.pem --insecure https://localhost:8443/actuator/health

Error response

curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number`

Performing the same request command but with http returns back actuator data you'd expect, so I'm missing some piece of the netty reactor based configuration, which I'm fairly new with.

Similiar question


Solution

  • Your application.yml file is incorrect. The ssl properties are effectively at server.server.ssl instead of server.ssl. Therefore the SSL settings have no effect and your server is an HTTP server instead of an HTTPS server. That's why curl works with http.

    To fix, remove line 6 (server:) and back indent line "ssl:" and following. This will give you (for example) server.ssl.enabled=true instead of server.server.ssl.enabled=true