Disable hostname verification

2,477 views
Skip to first unread message

Michi

unread,
Feb 19, 2016, 10:45:51 AM2/19/16
to Akka User List
Hi,

I have written a small HTTPS test server and client and now I try to disable hostname verification. Here is the code:

object HttpsServer extends App {

implicit val system = ActorSystem("system")
implicit val mat = ActorMaterializer()
implicit val ec = system.dispatcher

val serverContext: HttpsContext = {
val password = "123456789".toCharArray
val context = SSLContext.getInstance("TLS")
val ks = KeyStore.getInstance("PKCS12")
val is = getClass.getResource("mykeystore.pkcs12").openStream()
ks.load(is, password)
val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
keyManagerFactory.init(ks, password)
context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)
// start up the web server
HttpsContext(context)
}

// credentials used to authenticate users
val credentials = Map("test" -> ("test", Set("user")))

// authenticator used to authenticate users, uses credentials
def authenticator[T](cred: Credentials) : Option[Set[String]] =
cred match {
case cred@Credentials.Provided(name) =>
credentials.get(name).flatMap {
case (pass, roles) =>
if(cred.verify(pass))
Some(roles)
else
None
}
case Credentials.Missing =>
None
}

val route = authenticateBasic("HTTP test server", authenticator) { roles ⇒
get {
path ("test.txt") {
complete ("Hello, World")
}
}
}

val binding = Http(system).bindAndHandle(
interface = "0.0.0.0",
port = 6443,
handler = route,
httpsContext = Some(serverContext)
)

binding onFailure {
case ex: Exception => println("Failed to bind to port 8888, reason {}", ex)
}
}

object ConnectionLevelHttpsClient extends App {

val config = ConfigFactory.parseURL(getClass.getResource("httpsclient.conf"))

implicit val system = ActorSystem("ConnectionLevelHttpsClient", config)
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher

val auth = Authorization(BasicHttpCredentials("test", "test"))

private val trustfulSslContext: SSLContext = {

object NoCheckX509TrustManager extends X509TrustManager {
override def checkClientTrusted(chain: Array[X509Certificate], authType: String) = ()
override def checkServerTrusted(chain: Array[X509Certificate], authType: String) = ()
override def getAcceptedIssuers = Array[X509Certificate]()
}

val context = SSLContext.getInstance("TLS")
context.init(Array[KeyManager](), Array(NoCheckX509TrustManager), null)
context
}

val trustfulClientContext: HttpsContext =
HttpsContext(trustfulSslContext)

val allHostsValid = new HostnameVerifier() {
override def verify(s: String, sslSession: SSLSession): Boolean = true
}
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid)


val connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]] =
Http().outgoingConnectionTls("localhost", 6443, httpsContext = Some(trustfulClientContext))
val responseFuture: Future[String] =
Source.single(HttpRequest(uri = "/test.txt", headers = List(auth)))
.via(connectionFlow)
.runWith(Sink.head).flatMap { response =>
if (response.status == StatusCodes.OK) {
Unmarshal(response).to[String]
} else {
Future.successful("Error: " + response.status)
}
}
responseFuture.onSuccess {
case result => println(result)
}
responseFuture.onFailure {
case ex => ex.printStackTrace()
}
}

The whole project is here: https://github.com/mthaler/akka-http-test

The server is using a self-signed certificate and the client ignores the certificate. The code works, but when I change

Http().outgoingConnectionTls("localhost", 6443, httpsContext = Some(trustfulClientContext))

to

Http().outgoingConnectionTls("127.0.0.1", 6443, httpsContext = Some(trustfulClientContext))


I get an error:

akka.stream.ConnectionException: Hostname verification failed! Expected session to be for 127.0.0.1

I tried to disable hostname verification by setting an all-trusing hostname verifier and also by including

akka.ssl-config.ssl.loose.acceptAnyCertificate=true
akka.ssl-config.loose.disableHostnameVerification = true
akka.ssl-config.ssl.loose.disableHostnameVerification = true


ssl-config.ssl.loose.acceptAnyCertificate=true
ssl-config.loose.disableHostnameVerification = true
ssl-config.ssl.loose.disableHostnameVerification = true


in httpsclient.conf. I also tried to remove my custom HttpsContext. But nothing seems to work. I am using Java 7 and akka-http 2.0.3.
How can I disable hostname verification?

(I know it is not good practice to trust all certificates and disable hostname verification.)

Best regards,
Michael

Konrad Malawski

unread,
Feb 19, 2016, 10:55:56 AM2/19/16
to akka...@googlegroups.com, Michi
Hi,
Have you tried setting akka.ssl-config.hostnameVerifierClass to your custom "accept everything" classname?

-- 
Cheers,
Konrad 'ktoso’ Malawski
Akka @ Typesafe
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Michi

unread,
Feb 19, 2016, 11:10:55 AM2/19/16
to Akka User List, michael...@physik.tu-muenchen.de
Hi Konrad,

thanks for the quick reply, that works! Out of curiosity: is there a way to do this on a per connection basis?

Best regards,
Michael

Konrad Malawski

unread,
Feb 19, 2016, 11:12:35 AM2/19/16
to akka...@googlegroups.com, Michi, michael...@physik.tu-muenchen.de
Currently there isn't a way to do this per connection.
In general we'd prefer to not make disabling these kinds of checks actually, but I know that's not a very popular statement.

Could you open a ticket or submit a PR that documents how to do this using the current scheme?
Thanks a lot in advance.

-- 
Cheers,
Konrad 'ktoso’ Malawski
Akka @ Typesafe

Endre Varga

unread,
Feb 19, 2016, 11:15:25 AM2/19/16
to akka...@googlegroups.com, Michi
Cannot the self-signed certs be added to the truststore though? That would be the "proper" workaround.

-Endre

Konrad Malawski

unread,
Feb 19, 2016, 11:16:41 AM2/19/16
to akka...@googlegroups.com, Endre Varga, Michi
Yeah, I guess you're right that we should document that instead.
We talked with Will that in ssl-config we'll want to remove all the "loose" settings (including disabling this check), so documenting with that in mind probably makes more thanks.

-- 
Cheers,
Konrad 'ktoso’ Malawski
Akka @ Typesafe

Michi

unread,
Feb 19, 2016, 11:33:11 AM2/19/16
to Akka User List, michael...@physik.tu-muenchen.de
I documented it here: https://github.com/mthaler/akka-http-test/

I can open a ticket later. What is a PR?

I think it would be useful for test-code to keep the option to disable certificate / hostname validation. For tests that only run on localhost security is not an issue at all. Running tests on different computers might cause problems if certificate / hostname verification is enabled.

I guess you can work around some of these problems e.g. by creating your own CA and using that for signing certificates but that seems overkill to me.

Best regards,
Michael

Endre Varga

unread,
Feb 19, 2016, 11:38:19 AM2/19/16
to akka...@googlegroups.com, Michi
The issue with security is always that if you make something convenient, even for testing, then somehow it ends up in production :(

-Endre

Roland Kuhn

unread,
Feb 19, 2016, 11:47:11 AM2/19/16
to akka-user, michael...@physik.tu-muenchen.de
Hi Michael,

19 feb 2016 kl. 17:33 skrev Michi <michael...@physik.tu-muenchen.de>:

I documented it here: https://github.com/mthaler/akka-http-test/

I can open a ticket later. What is a PR?

I think it would be useful for test-code to keep the option to disable certificate / hostname validation. For tests that only run on localhost security is not an issue at all. Running tests on different computers might cause problems if certificate / hostname verification is enabled.

I guess you can work around some of these problems e.g. by creating your own CA and using that for signing certificates but that seems overkill to me.

I don’t agree: if you write a program that shall have certain security characteristics, then you must certainly test it under the same constraints that you will run it with in production. Otherwise you run something that you have not tested. How would you test the failure scenarios where precisely these hostname checks fail? This should be handled (and probably reported) properly.

Therefore I don’t see the private CA as a workaround, I see it as a necessity so that security is practiced by everyone involved.

Regards,

Roland



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


Michi

unread,
Feb 22, 2016, 10:04:15 AM2/22/16
to Akka User List, michael...@physik.tu-muenchen.de
Hi Roland,
 
I don’t agree: if you write a program that shall have certain security characteristics, then you must certainly test it under the same constraints that you will run it with in production. Otherwise you run something that you have not tested. How would you test the failure scenarios where precisely these hostname checks fail? This should be handled (and probably reported) properly.

Therefore I don’t see the private CA as a workaround, I see it as a necessity so that security is practiced by everyone involved.
 
I have to admit my knowledge about SSL/TLS is very limited. But if hostname verification is causing trouble in our production code, I would not hesitate to switch it off for production code. Our code is used in an intranet, anyway and I am really not worried about man-in-the-middle attacks.

The obvious question is, why use https at all? I wouldn't, but the software we connect to is https only, so we have to live with it. This might be an exception and I guess we can get everything working with hostname verification (or maybe it just works, I did not try it yet). I am just not eager to spend lots of time to get security right if security is basically irrelevant, anyway.

Best regards,
Michael

Akka Team

unread,
Feb 22, 2016, 10:17:49 AM2/22/16
to Akka User List
Hi Michael,

On Mon, Feb 22, 2016 at 4:04 PM, Michi <michael...@physik.tu-muenchen.de> wrote:
Hi Roland,
 
I don’t agree: if you write a program that shall have certain security characteristics, then you must certainly test it under the same constraints that you will run it with in production. Otherwise you run something that you have not tested. How would you test the failure scenarios where precisely these hostname checks fail? This should be handled (and probably reported) properly.

Therefore I don’t see the private CA as a workaround, I see it as a necessity so that security is practiced by everyone involved.
 
I have to admit my knowledge about SSL/TLS is very limited. But if hostname verification is causing trouble in our production code, I would not hesitate to switch it off for production code. Our code is used in an intranet, anyway and I am really not worried about man-in-the-middle attacks.

In this case the proper solution is to add the certificate of that service to a truststore. Then the truststore can be relatively easily installed on the client machines, i.e. you need to do this once.
 

The obvious question is, why use https at all? I wouldn't, but the software we connect to is https only, so we have to live with it. This might be an exception and I guess we can get everything working with hostname verification (or maybe it just works, I did not try it yet). I am just not eager to spend lots of time to get security right if security is basically irrelevant, anyway.

This is a very specific use case though.

-Endre


Best regards,
Michael

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.



--
Akka Team
Typesafe - Reactive apps on the JVM
Blog: letitcrash.com
Twitter: @akkateam

rdineshf...@gmail.com

unread,
Mar 15, 2017, 4:00:57 AM3/15/17
to Akka User List
Hi Team,
How do we disable Host verification using Akka http? Getting below exception.
akka.stream.ConnectionException: Hostname verification failed!

Code:
http.setDefaultClientHttpsContext(HttpsConnectionContext.https(context));
conSecure = ConnectHttp.toHostHttps(properties.getHost(), properties.getPort());
cstage = Source.single(hrequest)
.via(http
.outgoingConnection(conSecure)
)
.runWith(Sink.<HttpResponse>head(), materializer)
;

return cstage;

Konrad Malawski

unread,
Mar 15, 2017, 5:25:13 AM3/15/17
to akka...@googlegroups.com, rdineshf...@gmail.com
Read the docs: 

You should also force the SSL Config library to be 0.2.2

-- 
Konrad `ktoso` Malawski
Akka @ Lightbend

rdineshf...@gmail.com

unread,
Mar 15, 2017, 5:53:13 PM3/15/17
to Akka User List, rdineshf...@gmail.com
Got it thanks!

Kenny Karosy

unread,
Dec 11, 2018, 9:47:52 AM12/11/18
to Akka User List
I have a single use case where I'm calling Http().singleRequest and I'd like to disable the host verification.  I've tried:

val badSslConfig: AkkaSSLConfig = AkkaSSLConfig().mapSettings(s => s.withLoose(s.loose.withDisableSNI(true)))
val badCtx: HttpsConnectionContext = Http().createClientHttpsContext(badSslConfig)
Http().singleRequest(HttpRequest(... , connectionContext = badCtx)

Is there more needed?
Reply all
Reply to author
Forward
0 new messages