Skip to content
This repository

SSL / HTTPS #18

Open
meskyanichi opened this Issue May 22, 2011 · 29 comments

8 participants

Michael van Rooijen Ryan Bates Brandon Tilley Julian Pawlowski Manoj Greg Molnar Chris Edwards Cristiano Sousa
Michael van Rooijen

Hi Ryan,

I'm using PrivatePub in one of my projects and it seems that I'm getting the HTTPS:// warning from Chrome because PrivatePub is trying to do something over HTTP://. I believe it may be either:

  • Tries to connect to the Faye server as defined in the private_pub.yml
  • Loads the /faye.js file over HTTP and not HTTPS

By "warning" i don't mean the huge WARNING screen, but simply this: http://cl.ly/2x0G0L3R2s092P0B282U

I was wondering if you know a way to get around this? Would it require me to purchase a new SSL certificate specifically for the Faye server?

I'm running on NGINX as my web server, Unicorn as my App Server and Thin for the Faye server.

Any pointers are greatly appreciated! Thanks

Michael van Rooijen

Well I actually figured out how to route requests of my main domain that are coming in at the /faye url and proxy_pass them to my Thin Faye server.

server {
  listen                443;

  server_name           myapp.com;
  root                  /var/applications/current/rails/public;

  ssl                   on;
  ssl_certificate       /etc/ssl/my.crt;
  ssl_certificate_key   /etc/ssl/my.com.key;

  # Thin Faye Server
  location /faye {
    proxy_pass http://127.0.0.1:4001;
    break;
  }

  # Unicorn Main App
  location / {
    ...
  }
}

So now https://mydomain.com/faye.js properly without warning returns the javascript, but it seems that privatepub still can't connect to it or subscribe to channels when using HTTPS. Any idea why this is?

Thanks!

Michael van Rooijen

I think the problem is that PrivatePub only assumes HTTP. I see you're loading in net/http here: https://github.com/ryanb/private_pub/blob/master/lib/private_pub.rb#L2

From recent experiences that doesn't work with HTTPS by default. I'll have a look and see if I can fix this to work over HTTPS as well.

Michael van Rooijen

Well, I've been trying for the past 2-3 hours to get this working but without any luck.

I have no idea why PrivatePub or Faye won't accept HTTPS requests. I've also tried various http clients such as rest-client and nestful but still no luck. I'm probably doing it wrong though.

My https:// in the address bar is nice and green, but now PrivatePub won't work. :/ I personally don't really care whether it goes over https or http, as long as it doesn't show the https:// warning, which it's showing because the site is https:// but PrivatePub is sending or receiving data over http:// (in some way) which Chrome apparently doesn't like.

You have more in-depth knowledge about Faye/PrivatePub than I do of course, so I may just be missing something obvious. Any feedback, idea's or suggestions much appreciated! :)

Michael van Rooijen

Just a heads up, it seems I fixed it and it now properly works over HTTPS.

I'm going to clean up the mess I made, so much code snippets commented out and combinations used ha.

I'll submit the details here once I clean up everything, and if applicable I'll submit a pull request so you can support HTTPS:// with PrivatePub as well.

Michael van Rooijen

This is my current setup that's working:

In my /etc/nginx/conf/nginx.conf inside the server {} block listening on port 433 (ssl):

location /faye {
  proxy_set_header  X-Real-IP  $remote_addr;
  proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;

  root /var/applications/current/faye;
  proxy_pass http://127.0.0.1:4001; # im running faye on port 4001
  break;
}

Here I basically use my main domain, but add a location /faye {} to catch incoming requests starting with /faye and I proxy-pass them to my Faye Thin instance.

Next the config/private_pub.yml file:

server: "http://123.45.67.89:4001/faye"
secret_token: "my_secret_token"

Here I specify the IP address (on port 4001 / faye) directly, so it won't go through NGINX. Notice I am using HTTP and not HTTPS here. This is mainly because PrivatePub currently cannot do POST requests with SSL, so we submit post requests via the regular http protocol.

However, this means that the faye.js file will be fetch over HTTP, and the Faye Browser Client will also connect via HTTP to the Faye server. This is what's causing browsers like Chrome to throw a warning in the address bar. Not so elegant. So I opened up the private_pub.js file and changes the urls to the js file and the faye server:

// script.src = self.subscriptions.server + ".js";
script.src = 'https://mydomain.com/faye.js'

and

// self.fayeClient = new Faye.Client(self.subscriptions.server);
self.fayeClient = new Faye.Client("https://mydomain.com/faye");

Now they connect over HTTPS instead of HTTP (as defined in the private_pub.yml) while the POST requests happen from the Ruby app through regular HTTP.

This works fine at the moment for me, but I believe PrivatePub should support HTTPS POST requests as well since it's common that people will be using HTTPS for their apps. I've attempted to get that working, but have had no success yet.

Let me know what you think!

Ryan Bates
Owner
ryanb commented May 24, 2011

Thanks for reporting this issue. I agree it would be great if HTTPS were supported. The protocol should probably be stripped out and use whichever one the browser is using when fetching the faye.js file and connecting to the faye server.

It should also support https in the internal post request so you can specify it in the server config.

Michael van Rooijen

Definitely. I haven't figured out how to get HTTPS working. Googled around for solutions but it all seems a bit vague to me. Maybe you know whats up. An easy way to determine whether it's HTTPS would be when parsing the URI:

uri = URI.parse("https://mydomain.com/faye")
if uri.scheme == "https"
  # enable ssl
end

I believe this would also work:

uri = URI.parse("https://mydomain.com/faye")
if uri.port == 443
  # enable ssl
end

Something along those lines. You could also use uri.port which assumably would return 443. Though even with that I wasn't able to figure out how to make the net/http or net/https libraries submit a proper post request over https/ssl. Faye itself with PrivatePub (the browser/client) properly connect to the Faye server over HTTPS, that's no problem.

Let me know if you find anything. :)

Brandon Tilley

What do you think of a change like BinaryMuse@fbd0209? I haven't tested it with an actual SSL server yet--any feedback is appreciated.

Ryan Bates
Owner
ryanb commented May 26, 2011

@BinaryMuse that looks good, test it out and submit a pull request if it's working for you. Thanks!

Michael van Rooijen

Looks similar to what I tried, but I couldn't get it to work when I tried.

Any luck on your end @BinaryMuse? This is quite an important commit if it works.

Michael van Rooijen

Oh, I think one of the issues I faced was the fact that you need to enable SSL with Thin:

thin start -e production -p 4000 --ssl

One problem is that when you browse to that page, you get an "SSL not-verified" warning which messes with the POST request. You may want to try:

http = Net::HTTP.new(‘secure.somehost.com’, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.get(“/secured/page”)

Notice the http.verify_mode = OpenSSL:SSL::VERIFY_NONE which basically ignores verifications and should just do it. You probably want to give that a try if your current implementation isn't working.

Julian Pawlowski

I can also recommend using pound as a reverse proxy:
http://www.apsis.ch/pound

Obviously this is also working for SSL traffic transparently.

Manoj

I don't know how to do it with apache2. I just followed the guide that is given on readme. I created a config/private_pub_thin.yml which has

---
port: 4443
ssl: true
ssl_key_file:  /certs_path/sub.class1.server.ca.pem
ssl_cert_file: /certs_path/ca.pem
environment: production
rackup: private_pub.ru

when I run

RAILS_ENV=production bundle exec thin -C config/private_pub_thin.yml start

I get

>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4443, CTRL+C to stop

which seems fine I think. My config/private_pub.yml has

development:
  server: "http://localhost:9292/faye"
  secret_token: "secret"
test:
  server: "http://localhost:9292/faye"
  secret_token: "secret"
production:
  server: "https://interakt.co/faye"
  secret_token: "51e53bf7dc372a865b68083d9641f8871eea859e182212e36127b701bb8c6303"
  signature_expiration: 3600 # one hour

When I try https://interakt.co:4443/faye.js then it just keeps loading and doesn't load anything.

I don't know what wrong I am doing. Please help

Greg Molnar

The current version of private pub won't play nicely with https unfortunately. Ryan seems to have a time off from development so the project is a bit abandoned. I will try to contact him and ask him his plans about private_pub.

Manoj

@gregmolnar Thanks a lot. Do you have any clue about the last stable version that works smoothly with https?

Greg Molnar

You can give a try to this fork at the ssl branch https://github.com/BinaryMuse/private_pub/tree/ssl. I had a quick look and it should work ok.

Manoj

Its not compatible with rails 3.2 I guess because it is giving error when I tried rails g private_pub:install

WARNING: Nokogiri was built against LibXML version 2.8.0, but has dynamically loaded 2.7.8
      remove  config/initializers/private_pub.rb
      remove  app/helpers/private_pub_helper.rb
(erb):9:in `template': uninitialized constant ActiveSupport::SecureRandom (NameError)
    from /Users/manoj/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/erb.rb:838:in `eval'
    from /Users/manoj/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/erb.rb:838:in `result'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/file_manipulation.rb:117:in `block in template'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/create_file.rb:54:in `call'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/create_file.rb:54:in `render'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/create_file.rb:47:in `identical?'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/create_file.rb:73:in `on_conflict_behavior'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/empty_directory.rb:114:in `invoke_with_conflict_check'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/create_file.rb:61:in `invoke!'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions.rb:95:in `action'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/create_file.rb:26:in `create_file'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/actions/file_manipulation.rb:116:in `template'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/bundler/gems/private_pub-fbd0209827c5/lib/generators/private_pub/install_generator.rb:11:in `copy_files'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/invocation.rb:127:in `block in invoke_all'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/invocation.rb:127:in `each'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/invocation.rb:127:in `map'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/invocation.rb:127:in `invoke_all'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/group.rb:233:in `dispatch'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/railties-3.2.14/lib/rails/generators.rb:171:in `invoke'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/railties-3.2.14/lib/rails/commands/generate.rb:12:in `<top (required)>'
    from /Users/manoj/.rvm/gems/ruby-1.9.3-p448@intercom.com/gems/railties-3.2.14/lib/rails/commands.rb:29:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

Module SecureRandom is directly accessible in rails 3.2

Greg Molnar

It should pick it up if directly accessible:
https://github.com/ryanb/private_pub/blob/master/lib/generators/private_pub/templates/private_pub.yml#L9
Not sure why it doesn't work for you. What do you get in rails console for defined?(SecureRandom) ?

Greg Molnar

I see. That fork made before the refactor. The quickest route for now is to skip the use of the generator and just create the config file by hand.

Manoj

I having this issue with http too, I think first it is the problem of apache2 then https comes into picture I guess. Any idea about apache2 configuration?

Greg Molnar

You should setup apache to forward domain.tld/faye request to the port you are starting thin on. I am not using apache for a long time so not sure how to set that up but I am sure you find a lot of help if you google apache proxy pass.

Greg Molnar

Ok, I just had some time to look into this and realized that Ryan already added the https support. At the bottom of the readme (41a614c) an example of how to set it up. The actual PR: 914871a
This ticket should be closed.

Chris Edwards

@manoj2411 your config is wrong I think:

production:
  server: "https://interakt.co/faye"

Should be:

production:
  server: "https://interakt.co:4443/faye"

I'm having a problem where I can access faye.js, but when trying to publish_to I get:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

Greg Molnar

@chrise86 Is you certificate working in a browser? It looks like it is more of a certificate issue than anything with private_pub

Chris Edwards

@gregmolnar yep, the SSL is working on the site, green https :(

My private_pub_thin.yml:

---
port: 4443
ssl: true
pid: tmp/pids/faye.pid
# daemonize: true
ssl_key_file: certs/<file name>.key
ssl_cert_file: certs/<file name>.crt
environment: production
rackup: private_pub.ru
Greg Molnar

This looks good to me. I will do some tests and will come back to you.

Chris Edwards

@gregmolnar thanks Greg. I have no idea what it could be. I have noticed however, when ssh'ing into the server and running thin -C config/private_pub_thin.yml start without the daemonized option, and then using PrivatePub.publish_to in the console, that the thin server returns <SSL_incomp>

Cristiano Sousa

Any news on this? I'm having the same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.