njh / ruby-mqtt

Pure Ruby gem that implements the MQTT protocol, a lightweight protocol for publish/subscribe messaging.
http://www.rubydoc.info/gems/mqtt
MIT License
541 stars 135 forks source link

Add Support for Server Name Indication (SNI) #86

Closed cdurante closed 7 years ago

cdurante commented 7 years ago

Currently, the only way I've seen to handle a fleet of devices connecting to Mosquito brokers running in OpenShift containers requires support of TLS SNI on the client side. Support for SNI would be a very welcome addition to this library, since this is really the only active mqtt library for ruby, I thought I'd ask here first.

njh commented 7 years ago

Sorry, I am having laptop troubles at the moment, so can't do any work on this at the moment.

But looking at this Stack Overflow answer: http://stackoverflow.com/questions/30244745/opensslsslsslcontext-sni-servername-cb-not-working

It looks like it just involves setting @socket.hostname before calling @socket.connect: https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/client.rb#L267

Do you want to give it a go and see if it works?

njh commented 7 years ago

Hi,

Did you get a chance to see if this fixes your problem?

nick.

cdurante commented 7 years ago

Hey, I I got this to work. This way user can optionally provide in the @hostname parameter to indicate that server name checking should occur instead of always copying @host -> @hostname by default.

PR

89

njh commented 7 years ago

Is there a benefit to being able to specify both a hostname to connect to and a hostname to verify against? Shouldn't they always be both the same?

cdurante commented 7 years ago

That was a question I had when adding @hostname.... Certainly for my use case they should be the same, but I wasn't sure if there are use cases where you either wouldn't want to pass @hostname or you might want it to be different from @host.

njh commented 7 years ago

I have added SNI support in 3173302.

I haven't tested with OpenShift, but I have tested with sniproxy v.0.4.0 using the following configuration:

listener 127.0.0.1:8883 {
    protocol tls
    table TableName
}

error_log {
    filename /dev/stdout 
    priority debug
}

table TableName {
    localhost 37.187.106.16:8883
}

And the following Ruby script:

MQTT::Client.connect(:host => 'localhost', :port => 8883, :ssl => true) do |client|
  # If you pass a block to the get method, then it will loop
  client.get('#') do |topic,message|
    puts "#{topic}: #{message}"
  end
end

Without the fix in 3173302, it was getting SSL errors. With the fix, it was successfully connecting to test.mosquitto.org.

cdurante commented 7 years ago

Looks great