1

In one of my project we are moving away from akka (v10.2.9) to http4s (v0.23.12). In akka we are creating http server using akka.http.scaladsl.Http object which internally creates HttpConnectionContext for server using AkkaSSLConfig which by default has hostNameVerifier enabled on server side as well, Which checks host names against CN and SAN. You can disable this hostNameVerification using this parameter

akka.ssl-config.loose.disableHostnameVerification = true

When I dug deeper into this I got to know hostNameVerification should enabled on Client side only to avoid man in the middle attack.

However, while moving from akka to http4s I still want to keep the functionality of hostNameVerification. I read the http4s documentation and I am using BlazeServerBuilder but I didn't find any provision to enable hostNameVerification on server side. How can this be achieved with http4s and scala.

tpsaitwal
  • 422
  • 1
  • 5
  • 23

1 Answers1

0

You can use withSslContext for this.

val sslContext = ???
val sslParams = TLSParameters(endpointIdentificationAlgorithm = Some("https")).toSSLParameters

blazeBuilder.withSslContextAndParameters(sslContext, sslParameters)

All params of the TLSParameters you can find here https://github.com/typelevel/fs2/blob/main/io/jvm/src/main/scala/fs2/io/net/tls/TLSParameters.scala

  • this does not solves the problem. This enables only mutual TLS. That while connecting to server, client must specify certificate. And on server side if root of this certificate is present in truststore this request is allowed. But I want to configure server in such a way that it rejects request from client xyz if the server does not have certificate with cn xyz in truststore and not just its CA. – tpsaitwal Nov 30 '22 at 10:54
  • It seems that I didn't understand you. Probably you have to configure custom `X509TrustManager` that will do any check that you want. After pass it to your ssl context `val sslContext: SSLContext = SSLContext.getInstance("SSL") sslContext.init(null, Array(YourTrustManager), new java.security.SecureRandom())` and put this ssl context to the server builder `.withSSLContext(context)` – Stanislav Kovalenko Nov 30 '22 at 13:40
  • I understand what you are trying to say. If in truststore you have root CA of client certificate then server would trust the call coming from client. And if we want one to one mapping we need to add self signed client certificate to server trust store. But I don't want to do that. What I want to do is. Though we have only root CA in trust store. I still want to identify client and allow client only if certain CN is present in CN name or DNS name. And I only have hold of sslContext – tpsaitwal Dec 02 '22 at 08:45
  • using `X509ExtendedTrustManager` and `endpointIdentificationAlgorithm` in sslParams should help to enable this verification. But I'm not sure how to customise HostnameVerification. Also I found a test case in blaze sources, but it seems that there is a hostname verification set on client side https://github.com/http4s/blaze/blob/f1e4bb253c7facf66fefed661f22bbd25ab0803b/blaze-server/src/test/scala/org/http4s/blaze/server/BlazeServerMtlsSpec.scala. I saw your question in GitHub, I hope that someone will give more explanation how to do it. – Stanislav Kovalenko Dec 02 '22 at 11:13
  • Also I find this question that might help https://stackoverflow.com/questions/18139448/how-should-i-do-hostname-validation-when-using-jsse – Stanislav Kovalenko Dec 02 '22 at 11:16
  • I think that some classes from https://github.com/lightbend/ssl-config can be reused in http4s. It doesn't look as an akka specific stuff. – Stanislav Kovalenko Dec 02 '22 at 11:34
  • thank you. I find the links you have given very helpful. From what I have read on this topic till now, to avoid man in the middle attack such things are enabled only on client side. But on server side as there are many checks like certificate whitelisting, authentication, etc. This would be additional overhead to identify clients. Like google if want to identify some client they can trust using root CA but not exact hostname. And in cloud age we cannot expect that. Also in akka this is quite old implementation that too internationally have used client side config. – tpsaitwal Dec 02 '22 at 13:39