Unable to create SSL HttpClient using IP address instead of hostname

1,296 views
Skip to first unread message

Richard S

unread,
May 28, 2014, 11:28:11 AM5/28/14
to ve...@googlegroups.com
Take the simple example from the HTTPS examples folder, but modify it so it connects to google.com:443 instead of the default localhost:4443

var vertx = require('vertx')
var console = require('vertx/console')

var client = vertx.createHttpClient().host('google.com').port(443).ssl(true).trustAll(true);

client.getNow('/', function(resp) {
  console.log("Got response " + resp.statusCode());
  resp.bodyHandler(function(body) {
    console.log("Got data " + body);
  })
});

I get a 301 MOVED, which is fine.

Now replace google.com with an IP address (I used ping google.com for example)

var vertx = require('vertx')
var console = require('vertx/console')

var client = vertx.createHttpClient().host('62.254.36.178').port(443).ssl(true).trustAll(true);

client.getNow('/', function(resp) {
  console.log("Got response " + resp.statusCode());
  resp.bodyHandler(function(body) {
    console.log("Got data " + body);
  })
});

I now get 

javax.net.ssl.SSLHandshakeException: Failed to create SSL connection

at org.vertx.java.core.http.impl.DefaultHttpClient$6$1.operationComplete(DefaultHttpClient.java:693)

at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:679)

at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:606)

at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:564)

at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:430)

at io.netty.handler.ssl.SslHandler.notifyHandshakeFailure(SslHandler.java:1049)

at io.netty.handler.ssl.SslHandler.setHandshakeFailure(SslHandler.java:1038)

at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:912)

at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:827)

at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:228)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:141)

at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:341)

at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:327)

at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785)

at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:116)

at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:494)

at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:461)

at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:378)

at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:350)

at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)

at java.lang.Thread.run(Thread.java:744)



Not sure if there is a workaround for this? I need to access servers using their IP address, not their hostname.

Thanks 

Alexander Lehmann

unread,
May 28, 2014, 3:41:04 PM5/28/14
to ve...@googlegroups.com
First of all, I should point out that IP addresses with https make only limited sense since it is not possible to get a published server certificate with an IP adress (at least I think its not possible). Nevertheless it should work and when using e.g. curl -k accessing the ips from google.com works (even works in Firefox after accepting the certificate exception).

This is not limited to ip address urls, I found a similar thing with some valid https urls, but I wasn't able to narrow that down yet.

Richard S

unread,
Jun 13, 2014, 6:05:46 AM6/13/14
to ve...@googlegroups.com
Thanks, I appear to have found a workable solution. It appears we need to not only trustAll but also disable host verification. So this code now works:

var vertx = require('vertx')
var console = require('vertx/console')

var client = vertx.createHttpClient().trustAll(true).host('173.194.34.69').port(443).ssl(true).verifyHost(false);


client.getNow('/', function(resp) {
  console.log("Got response " + resp.statusCode());
  resp.bodyHandler(function(body) {
    console.log("Got data " + body);
  })
});


Thanks!

Tim Fox

unread,
Jun 13, 2014, 6:58:44 AM6/13/14
to ve...@googlegroups.com
Bear in mind you are opening yourself to man in the middle attacks by doing this. Certificates are only valid against the host the certificate was issued for which is why you fail to connect with an ip address and host verification turned on.

Although the traffic will be encrypted in this case, you have no guarantee that who you are connecting is the right server.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Richard Scorer

unread,
Jun 13, 2014, 7:52:41 AM6/13/14
to ve...@googlegroups.com
Thanks Tim, that’s a vital point to remember; 

Thankfully this is purely for in house testing. We prefer to use the full name and SSL certificate when we can, but in this instance we require the ability to access the same hostname but with a different IP address depending on the environment we’re testing against. 

Each env has its own DNS server, if we could tell the SSL connection that we need to use a specific DNS server then we could use the hostname. For example, if you had DNS server 1.2.3.4 for QA and 1.2.3.5 for Dev you could possibly make this kind of call, and still have the SSL certificate be verified under the covers.

> var client = vertx.createHttpClient().host(’hostname.com').port(443).ssl(true).usingDnsResolver(‘1.2.3.4’);

But I think that far exceeds the HttpClient specs, and is very rarely needed :) 

Now we’ve got a workable solution we can move on to building the rest of our code.

Cheers,
Richard


On 13 June 2014 at 11:58:46, Tim Fox (timv...@gmail.com(mailto:timv...@gmail.com)) wrote:

> Bear in mind you are opening yourself to man in the middle attacks by doing this. Certificates are only valid against the host the certificate was issued for which is why you fail to connect with an ip address and host verification turned on.
>
> Although the traffic will be encrypted in this case, you have no guarantee that who you are connecting is the right server.
>
> On 13/06/14 11:05, Richard S wrote:
> > Thanks, I appear to have found a workable solution. It appears we need to not only trustAll but also disable host verification. So this code now works:
> >
> > var vertx = require('vertx')
> > var console = require('vertx/console')
> >
> > var client = vertx.createHttpClient().trustAll(true).host('173.194.34.69').port(443).ssl(true).verifyHost(false);
> >
> > client.getNow('/', function(resp) {
> > console.log("Got response " + resp.statusCode());
> > resp.bodyHandler(function(body) {
> > console.log("Got data " + body);
> > })
> > });
> >
> >
> > Thanks!
> >
> > On Wednesday, May 28, 2014 8:41:04 PM UTC+1, Alexander Lehmann wrote:
> > > First of all, I should point out that IP addresses with https make only limited sense since it is not possible to get a published server certificate with an IP adress (at least I think its not possible). Nevertheless it should work and when using e.g. curl -k accessing the ips from google.com(http://google.com) works (even works in Firefox after accepting the certificate exception).
> > >
> > > This is not limited to ip address urls, I found a similar thing with some valid https urls, but I wasn't able to narrow that down yet.
> > >
> > >
> > >
> > > On Wednesday, May 28, 2014 5:28:11 PM UTC+2, Richard S wrote:
> > > > Take the simple example from the HTTPS examples folder, but modify it so it connects to google.com:443(http://google.com:443) instead of the default localhost:4443
> > > >
> > > > var vertx = require('vertx')
> > > > var console = require('vertx/console')
> > > >
> > > > var client = vertx.createHttpClient().host('google.com(http://google.com)').port(443).ssl(true).trustAll(true);
> > > >
> > > > client.getNow('/', function(resp) {
> > > > console.log("Got response " + resp.statusCode());
> > > > resp.bodyHandler(function(body) {
> > > > console.log("Got data " + body);
> > > > })
> > > > });
> > > >
> > > >
> > > > I get a 301 MOVED, which is fine.
> > > >
> > > > Now replace google.com(http://google.com) with an IP address (I used ping google.com(http://google.com) for example)
> > To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com(mailto:vertx+un...@googlegroups.com).
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/BnEwsNM8vsI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com(mailto:vertx+un...@googlegroups.com).

petermd

unread,
Jun 13, 2014, 8:43:59 AM6/13/14
to ve...@googlegroups.com
Do you need to access multiple env's from the same VM? If you just need to set a single DNS resolver for the VM then I think you could do that via "sun.net.spi.nameservice.nameservers

see

Richard Scorer

unread,
Jun 13, 2014, 8:49:46 AM6/13/14
to ve...@googlegroups.com, petermd
At the moment yes we need it from the same VM, we don’t like doing anything the easy way ;)

Interesting idea though. We could maybe fire off a container per env each with its own DNS setup, and use clustering to collate the results. That could be an interesting project for the weekend :)

Thanks! 
Richard

--

You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/BnEwsNM8vsI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages