-
Notifications
You must be signed in to change notification settings - Fork 1
SSL(TLS)
SYS
openssl s_client -connect google.com:443
COST of TLS handshake
curl -w "dns_resolution: %{time_namelookup}, tcp_established: %{time_connect}, ssl_handshake_done: %{time_appconnect}, TTFB: %{time_starttransfer}\n" -o /dev/null -s "https://sushi.herokuapp.com/"
JAVA
eg: -Djavax.net.debug=ssl,handshake,data,trustmanager
bash-4.3# cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.4.6
PRETTY_NAME="Alpine Linux v3.4"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"
keytool -list -v -keystore /opt/jdk/jre/lib/security/cacerts
#https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html
REACTIVE netty
package com.example.reactivewebclient
//https://github.com/reactor/reactor-netty/pull/1455
import io.netty.channel.ChannelOption.CONNECT_TIMEOUT_MILLIS
import io.netty.handler.timeout.ReadTimeoutHandler
import io.netty.handler.timeout.WriteTimeoutHandler
import mu.KotlinLogging
import org.springframework.http.HttpMethod.GET
import org.springframework.http.MediaType
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.BodyInserters
import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono
import reactor.netty.http.client.HttpClient
import java.time.Duration.ofMillis
import java.util.concurrent.TimeUnit
@Service
class BSService(webclientB: WebClient.Builder) {
private val log = KotlinLogging.logger {}
lateinit var webClient: WebClient
init {
val httpClient: HttpClient = HttpClient.create()
.option(CONNECT_TIMEOUT_MILLIS, 5000)
.responseTimeout(ofMillis(5000))
.doOnConnected { conn ->
conn.addHandlerLast(ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS))
.addHandlerLast(WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS))
}
//warm the fuck up
httpClient.warmup().subscribe()
webClient = webclientB
.clientConnector(ReactorClientHttpConnector(httpClient))
.baseUrl("https://data.nsw.gov.au/data/api/3/action/datastore_search")
.build()
log.info { "webclient BUILT" }
}
fun get(): Mono<String> {
return webClient.method(GET)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue("{\"resource_id\": \"2776dbb8-f807-4fb2-b1ed-184a6fc2c8aa\", \"limit\": 5, \"q\": \"jones\" }"))
.retrieve()
.bodyToMono(String::class.java)
.onErrorResume { handleErr(it) }
}
private fun handleErr(t:Throwable):Mono<String> {
log.error("MOTHERFUCVKER", t)
return Mono.just("BLEEP")
}
}
https://github.com/benjaminknauer/spring-mvc-web-client-first-request-slow-demo
TLS 1.3
https://www.oracle.com/java/technologies/javase/8u261-relnotes.html
https://bugs.openjdk.java.net/browse/JDK-8248721
https://github.com/netty/netty/commit/b1d3aad404a39143da7a86c121d60f35c0d21108
Sample: openssl s_client -connect data.nsw.gov.au:443 -prexit #TLSv1.2 openssl s_client -connect okta.com:443 -prexit #TLSv1.2 openssl s_client -connect aalto.fi:443 -prexit #TLSv1.3
curl -w "dns_resolution: %{time_namelookup}, tcp_established: %{time_connect}, ssl_handshake_done: %{time_appconnect}, TTFB: %{time_starttransfer}\n" -o /dev/null -s "https://iag-nrma-silver-prd.okta.com/"
MTLS client
supposed
curl -vvv --cacert /Users/hoaphan/dev/code/springboot-tls/client.pem \
--key /Users/hoaphan/openssl/client-key1.pem \
--cert /Users/hoaphan/openssl/client-cert1.pem \
https://localhost:8080/actuator
now this in Kotlin:
kotlin
fun testMTLS() {
val sslContext: SslContext = sslContext()!!
val httpClient: HttpClient = HttpClient.create().secure {
sslSpec -> sslSpec.sslContext(sslContext)
}
val client = WebClient.builder()
.clientConnector(ReactorClientHttpConnector(httpClient))
.baseUrl("https://localhost:8080/actuator")
.build()
val res = client.get()
.retrieve()
.bodyToMono(String::class.java)
StepVerifier
.create(res)
.expectNext("""{"_links":{"self":{"href":"https://localhost:8080/actuator","templated":false},"health":{"href":"https://localhost:8080/actuator/health","templated":false},"health-path":{"href":"https://localhost:8080/actuator/health/{*path}","templated":true}}}""")
.expectComplete()
.verify()
}
private fun sslContext(): SslContext{
val clientSslKeyStorePassword = "changeit"
val clientSslTrustStorePassword:String = "changeit"
FileInputStream("/Users/hoaphan/dev/code/springboot-tls/client/cert.jks").use { keyStoreFileInputStream ->
FileInputStream("/Users/hoaphan/.sdkman/candidates/java/11.0.11.hs-adpt/lib/security/cacerts").use { trustStoreFileInputStream ->
val keyStore = KeyStore.getInstance("jks")
keyStore.load(keyStoreFileInputStream, clientSslKeyStorePassword.toCharArray())
val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance("SunX509")
keyManagerFactory.init(keyStore, clientSslKeyStorePassword.toCharArray())
val trustStore = KeyStore.getInstance("jks")
trustStore.load(trustStoreFileInputStream, clientSslTrustStorePassword.toCharArray())
val trustManagerFactory: TrustManagerFactory = TrustManagerFactory.getInstance("SunX509")
trustManagerFactory.init(trustStore)
return SslContextBuilder
.forClient()
.keyManager(keyManagerFactory)
.trustManager(trustManagerFactory)
.build()
}
}
}