Configure WEBrick to use automatically generated self-signed SSL/HTTPS certificate - ruby-on-rails

I want to develop my Ruby on Rails application locally with SSL/HTTPS, but I'm having trouble trying to setup a server to use SSL. The following are the things I've already tried so far:
rails server [options]
The rails server command doesn't come with an ssl option (rails server --help):
Usage: rails server [mongrel, thin, etc] [options]
-p, --port=port Runs Rails on the specified port.
Default: 3000
-b, --binding=ip Binds Rails to the specified ip.
Default: 0.0.0.0
-c, --config=file Use custom rackup configuration file
-d, --daemon Make server run as a Daemon.
-u, --debugger Enable the debugger
-e, --environment=name Specifies the environment to run this server under
(test/development/production).
Default: development
-P, --pid=pid Specifies the PID file.
Default: tmp/pids/server.pid
-h, --help Show this help message.
Custom WEBrick instance with automatically generated self-signed SSL certificate
My Code
Following along with the WEBrick documentation for HTTPS, I made the following Ruby script that I run as ruby server.rb:
require 'webrick'
include WEBrick
root = File.expand_path './public'
cert_name = [
%w[CN localhost],
]
server = HTTPServer.new(
:BindAddress => '127.0.0.1',
:Port => '4430',
:DocumentRoot => root,
:SSLEnable => true,
:SSLCertName => cert_name # LOOK! SSLCertName IS SET!
)
# Shutdown gracefully on signal interrupt CTRL-C
# http://www.ruby-doc.org/core-2.1.1/Kernel.html#method-i-trap
trap('INT') { server.shutdown }
server.start
According to the documentation I linked to above:
This will start the server with a self-generated self-signed certificate.
and according to the documentation for WEBrick::Config,
WEBrick can automatically create a self-signed certificate if :SSLCertName is set.
The Errors
When I start the server, I get the following output:
INFO WEBrick 1.3.1
INFO ruby 2.1.1 (2014-02-24) [x86_64-darwin13.0]
INFO WEBrick::HTTPServer#start: pid=26059 port=4430
However, when I try to access https://localhost:4430/robots.txt, I get the following error in Chrome 33.0.1750.117:
and the following error when I try the same url in Firefox 27.0.1:
I looked up the ssl_error_rx_record_too_long error, and it looks like it can be caused by a few different things. Maybe WEBrick is still listening for HTTP requests on port 80, but that seems odd considering I explicitly set it to enable SSL on port 4430.
Access Logs
Additionally, here are the access log contents from WEBrick when I make the request for https://localhost:4430/robots.txt from Chrome, but I have no idea what any of it means (it looks like it's encoded in hex or something):
ERROR bad Request-Line `\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03S\x15ußð'¦\x14·áÚOá,j\x7FÅ=üüNn#\x02ëý\x0Fø‚\x00\x00(À+À/\x00žÌ\x14Ì\x13\x00œÀ'.
localhost - - [04/Mar/2014:01:42:39 EST] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03S\x15ußð'¦\x14·áÚOá,j\x7FÅ=üüNn#\x02ëý\x0Fø‚\x00\x00(À+À/\x00žÌ\x14Ì\x13\x00œÀ" 400 417
- ->
ERROR bad Request-Line `\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x02S\x15ußj\x05ç©!€¿'ÄÃåë!t…ß\x06pDÒÒ4?”»7\x19\x00\x00\x1EV\x00À'.
localhost - - [04/Mar/2014:01:42:39 EST] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x02S\x15ußj\x05ç©!€¿'ÄÃåë!t…ß\x06pDÒÒ4?”»7\x19\x00\x00\x1EV\x00À" 400 398
- ->
ERROR bad Request-Line `\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x01S\x15ußñom¾u<n¨ý9yö“¤Øcƒ{½wh)M#š1;\x00\x00\x1EV\x00À'.
localhost - - [04/Mar/2014:01:42:39 EST] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x01S\x15ußñom¾u<n¨ý9yö“¤Øcƒ{½wh)M#š1;\x00\x00\x1EV\x00À" 400 392
- ->
ERROR bad URI `\x04ËB¿É\\ ˆ2ðiwñ·*\x02\x06^´\x00#v\x00\x00\x14\x00ÿV\x00\x009\x005\x003\x002\x00\x05\x00\x04\x00/\x00'.
localhost - - [04/Mar/2014:01:42:39 EST] "\x16\x03\x00\x00?\x01\x00\x00;\x03\x00S\x15uß…N®ˆ\r\x04ËB¿É\\ ˆ2ðiwñ·*\x02\x06^´\x00#v\x00\x00\x14\x00ÿV\x00\x009\x005\x003\x002\x00\x05\x00\x04\x00/\x00" 400 389
- -> \x04ËB¿É\\ ˆ2ðiwñ·*\x02\x06^´\x00#v\x00\x00\x14\x00ÿV\x00\x009\x005\x003\x002\x00\x05\x00\x04\x00/\x00
Ruby Source for SSL Module
Also, I checked the Ruby source code for the SSL module, but I don't see anything obvious in there for why this might not be working:
def setup_ssl_context(config) # :nodoc:
unless config[:SSLCertificate]
cn = config[:SSLCertName]
comment = config[:SSLCertComment]
cert, key = Utils::create_self_signed_cert(1024, cn, comment) # LOOK HERE!
config[:SSLCertificate] = cert
config[:SSLPrivateKey] = key
end
# etc...
end
# Higher up in the file...
def create_self_signed_cert(bits, cn, comment)
# etc ...
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 1
name = OpenSSL::X509::Name.new(cn)
cert.subject = name
cert.issuer = name
# etc ...
end
My Environment
Here are the following things I'm using for development:
OS X Mavericks.
Ruby 2.1.1.
Rails 4.0.3.
Summary
So this is where I'm at currently, and I'm not sure how to proceed. I'm aware that I can just pass my own self-signed certificate file (generated with something like OpenSSL) to WEBrick, but the documentation says that WEBrick can automatically generate its own, and I'm really interested in getting that to work.
I'm also aware that I can use a different webserver like Thin with its --ssl option, but again, I wanted to use WEBrick, because it's the "out-of-the-box" web server for Rails, I want to be able to easily and quickly setup a development SSL web server without having to download additional gems and stuff like that.
I'm also aware that this solution exists, but again, I'm interested in having WEBrick automatically generate its own certificate (and besides, that solution seems to be a little overly complicated for what I'm trying to do).
So does anyone have any ideas of what might be wrong?

Okay, I figured out what was wrong, I should've paid closer attention to the instructions for HTTPS in WEBrick, this is the exact code from the example:
require 'webrick'
require 'webrick/https' # SEE THIS?
cert_name = [
%w[CN localhost],
]
server = WEBrick::HTTPServer.new(:Port => 8000,
:SSLEnable => true,
:SSLCertName => cert_name)
See that line that says require 'webrick/https'? I didn't have that in my original config. I didn't think that I'd need it.
Once I added it, my script started serving over HTTPS, and I could finally connect to https://localhost:4430/robots.txt. <face-palm>

Related

How to change WEBrick :AccessLog option when running RedMine?

I'm running RedMine via WEBrick using the following command line (simplified):
bundle exec rails server webrick -e production -p 3012 -P '/var/lib/redmine/redmine.pid'
I don't like how WEBrick outputs the peer address at the beginning of its access log lines (because I'm running it behind nginx and the peer address is always 127.0.0.1), so I want to change the access log format.
I know that I need to tune the :AccessLog config option for WEBrick, but I don't know how to get my hands on it. WEBrick is run by the rails server command, via the rack abstraction, and I don't see an obvious way to pass the necessary configuration to WEBrick.
So, is there any way to do it? Some command line switch? -c is the only switch that accepts some kind of configuration file, but it references "rackup", and I have no idea how to work with it.
Maybe it can be done by changing configuration files? I tried to modify additional_environment.rb by adding config[:AccessLog] = [ [ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT ] ], but it had no effect (although the file was executed), so I assume this file's config is not what is passed to WEBrick.
I'm pretty sure there is some way to configure this option without creating a new Rails application and invoking WEBrick manually, and hopefully even without changing RedMine files.

SSL Webrick on localhost not hosting ruby on rails app

How do I get Ruby On Rails Webrick to work with self-signed SSL certificate on localhost just to test https ?
Basically, Ived followed the work that has been done here:
Configure WEBrick to use automatically generated self-signed SSL/HTTPS certificate
And produce the script like the following:
require 'webrick'
require 'webrick/https'
cert_name = [
%w[CN localhost],
]
server = WEBrick::HTTPServer.new(:Port => 8000,
:SSLEnable => true,
:SSLCertName => cert_name)
# Shutdown gracefully on signal interrupt CTRL-C
# http://www.ruby-doc.org/core-2.1.1/Kernel.html#method-i-trap
trap('INT') { server.shutdown }
server.start
When I tried to access https://localhost:8000/, it did warn about trust but just went ahead, instead I had nothing come out but this. BTW, https works fine, just it seems its not getting the right route for SSL.
Not Found
`/' not found.
WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08) OpenSSL/1.0.2 at localhost:8000
console prints this:
[2015-07-25 23:38:25] INFO WEBrick::HTTPServer#start: pid=6765 port=8000
[2015-07-25 23:38:32] ERROR `/' not found.
localhost - - [25/Jul/2015:23:38:32 MYT] "GET / HTTP/1.1" 404 284
- -> /
The reason your server is returning that 404 is because the script you've set up is just for an empty WEBrick server; it doesn't actually mount your Rails app. The thread you linked to seemed to be using that script just as a minimal test for the SSL functionality. The full answer to getting WEBrick to work with SSL looks to be answered here: How do you configure WEBrick to use SSL in Rails?
However, I wouldn't recommend you bother. WEBrick is strictly meant as a development-only server, and isn't suitable for use in production (which is why it's hard to get it to do things like use SSL). Instead, either set up nginx as a SSL-serving proxy to your app or use a server which supports SSL easily, like thin does.

Rails server not starting with web sockets and redis options in rake task.

I have to use websockets in my rake task and for that I changed my event.rb to
config.synchronize = true
# Uncomment and edit to point to a different redis instance.
# Will not be used unless standalone or synchronization mode
# is enabled.
config.redis_options = {:host => 'localhost', :port => '3000'}
and when I start my rails server I get this error:
! Invalid request
Exiting
/usr/local/rvm/gems/ruby-1.9.3-p194#socialmail/gems/redis-3.0.4/lib/redis/connection/synchrony.rb:115:in `read': Got 'Protocol error, got "H" as reply type byte' as initial reply byte. If you're in a forking environment, such as Unicorn, you need to connect to Redis after forking. (Redis::ProtocolError)
What am I doing wrong?
Thanks
Hey thanks for the question, I personally couldn't get a rake task of mine to post to a websocket channel I had open on my rails server. Your synchronize command helped (along with starting a Redis server locally).
Your problem through - seems like you're pointing to 3000. Is that your rails server or the Redis instance? If you're running it locally, I'd omit that line.

Problems with Passenger + Nginx: Failed to connect to a master node. Rails config error?

We're not sure if this is something not configured properly in our Rails setting, but we're seeing this error in our nginx error logs get repeated: Exception PhusionPassenger::UnknownError in PhusionPassenger::Rack::ApplicationSpawner (Failed to connect to a master node at x.objectrocket.com:10804 ...
Here's a gist with more from the error log: https://gist.github.com/panabee/a291526f4dcf4cd434d9
How do we stop these errors?
We're on Rails 3.2.12.
This error means the ObjectRocket mongo server is refusing or timing out your connections. Contact them with the specific logs to work out why they refuse the connection.
Also, try setting your timeouts lower to avoid hanging connections for your clients:
MongoMapper.connection = Mongo::Connection.new(host, 27017, :connect_timeout => 1, :op_timeout => 1)
This sets the connect and read timeouts. There's a :timeout option as well: it's related to connection pooling, not connecting to the server.
Neither :op_timeout nor :connect_timeout have a default value. Verify their settings by reading MongoMapper.connection.connect_timeout.
If you're using the 1.8.0 mongo gem version or later, you may want to replace the deprecated Mongo::Connection class with Mongo::MongoClient.
Try to add
# encoding: UTF-8
In the first line of environment.rb.

How do I pass arguments to Thin in Rails 3.1+ to configure SSL?

I'm working on enabling SSL on a Rails app in a staging environment that uses the Thin gem. It seems like I'm only a few steps away. I've set config.force_ssl = true in config/environments/staging.rb.
Since I haven't told Thin where the SSL certificate and key are, rails puts !! Invalid request. At least I think that's why it's doing that.
I found that Thin can accept arguments to determine the location of the SSL certificate and key files, as in this answer. However, I can't figure out where to tell Rails to start Thin with these arguments. How do I do this?
If you're starting from the command line, you can run thin start --ssl instead of rails server (plus any other options listed in How can I pass SSL options into "rails server" in Rails 3.0?)

Resources