Development Rails server that's compatible with both HTTP and HTTPS - ruby-on-rails

My application isn't quite ready to go full SSL so in the meantime, I am allowing SSL but not requiring it. I do require SSL for certain controllers and force redirects to HTTPS for actions in such controllers.
I can start a thin server using SSL via thin start --ssl. This works great for SSL testing. However, I cannot have HTTP and HTTPS running simultaneously on the same port. Obviously, this makes testing redirects from HTTP to HTTPS quite frustrating. I can run an Apache or nginx server on top but I don't really want to go through the trouble of doing that in my development environment.
To start two servers, one for SSL and without, I use foreman like so:
web: rails server
ssl: thin start --ssl -p 3001
This starts the HTTP server on port 3000 and HTTPS server on 3001. Now my question is. How do I create a "smart redirect" policy only on my development environment only such that redirects from HTTP to HTTPS intelligently changes the port from 3000 to 3001? Thanks!

Related

Ruby on Rails Thin and force_ssl, empty response over HTTP

I've set up several Ruby on Rails servers lately on CentOS 7.x using Thin as the web server and an SSL Certificate from Comodo.
I have enabled the force_ssl option in my config/environments/production.rb file, and I'm running my server with the command:
RAILS_ENV=production thin start -a <IP> -p 3000 --ssl --ssl-key-file <KEY FILE PATH> --ssl-cert-file <CERT FILE PATH>
I'm using devise, so in config/initializers/devise.rb I set
config.rememberable_options = { secure: true }
I also set some config in config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_secure_<domain>_session', httponly: true, secure: true
When I first access my server over HTTP from an internet browser I get an empty response message (tested with multiple browsers and multiple computers). When I access it over https directly it resolves fine (and SSL is working perfectly), and when I next try to access over http it redirects just fine. I'm not certain what I can do to fix this bar using nginx or Apache.
Here are the other questions I've read:
Rails with thin and ssl: http request not auto-redirected to https
Ruby on rails: force_ssl not redirecting from http to https when using thin start --ssl
Thin can only listen on one port and can only serve either SSL or non-SSL requests per instance. When thin is started with --ssl it attempts to process inbound connections as TLS connections, and will drop those which it can't negotiate (ie, plain HTTP requests).
You need to use nginx (or some other reverse proxy) to listen on multiple ports and terminate SSL, and then forward to Thin. Otherwise, you'll need to run multiple Thin instances, one serving SSL and the other not.

Separate port for some URLs in Rails app

My Rails app listens on single port for API calls and browser requests. To increase security I would like to open another port for API and make web page URLs unabailable for this port.
How to do this in Rails? (Possibly without losing current app integrity).
I use WEBrick or Puma during development and Apache+Passenger in production.
P.S.
Currently I'm thinking about making HTTP proxy which will forward API calls.
Unicorn will bind to all interfaces on TCP port 8080 by default. You may use the -l switch to bind to a different address:port. Each worker process can also bind to a private port via the after_fork hook. But I think it is not useful if you have nginx on top layer.

Why my app asks to choose to authenticate myself for my Rails app with HTTPS?

Env
Rails 4.0.4
Using SSL certificates for HTTPS connections
In my config/environments/production.rb
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
This is how I start my server:
thin start -e production -d -p 3001 -P ./tmp/pids/thin_https.pid --ssl --ssl-key-file /etc/ssl/current/www_domain_io.key --ssl-cert-file /etc/ssl/current/WWW.DOMAIN.IO.crt
Then I am getting this screen when accessing my production website:
I click OK, and I land on my page https://www.domain.io page successfully. The entity is verified and the https: show in green. So I am good ... but why do I get that "Select a certificate to authenticate to www.domain.io:443` ? I figured that once my entity was verified I should land automatically on my page ? Any ideas?
UPDATE
The documention shows --ssl-disable-verify option that is actually not available on thin 1.6.2 codename Doc Brown
SSL options:
--ssl Enables SSL
--ssl-key-file PATH Path to private key
--ssl-cert-file PATH Path to certificate
--ssl-disable-verify Disables (optional) client cert requests <=== this is NOT available
I have posted an issue on github
Thin lighthouse ticket about --ssl-disable-verify
Existing ticket on GitHub
I just don't understand how to get the version of thin where this option is available.
A similar post on SO suggests your .crt file includes the root CA certificate for your certificate chain. Remove it, and you should be good to go.
Intermediate certifcates should still remain in the .crt file, presumably.
You're starting your thin server on port 3001, but you're connecting to the regular https URL, which by default connects to port 443. So I assume you have a web server instance (Apache/nginx) proxying requests for thin.
If that's the case, you should disable SSL for thin, as this will be handled by the proxy server in front of your thin instance.
If you don't have a reverse proxy, and want to use just thin, you should specify the port where thin is listening in the URL (https://example.com:3001).

Start Unicorn using ssl in development

I'm migrating my rails app (still in development) from Thin to Unicorn. My app uses config.force_ssl = true.
When using Thin I could just write:
thin start --ssl
My question is: What is the equivalent way to start Unicorn with ssl in development?
If I correctly understood your question, you're trying to run unicorn on port 443.
This is a bad idea.
Instead, to achieve the same goal, I would suggest, run unicorn on an unprivileged port (above 1024), or better on a unix socket, and switch Nginx before, passing all static stuff directly trough nginx, and the rails stuff, trough unicorn.
I know this doesn't answer your question, but for the user, it will work exactly the same, with some benefits when your app server (unicorn) crashes, for example a nice rendered 502 error page served via nginx instead of a plain network error message seen in the browser of your users.
You can with this solution run X different applications on the same port, with different subdomains. a must have for a development machine with many projects.

Using Thin Web Server with HTTP and HTTPS

I'm using the Thin web server to serve my Rails app.
Starting the server with thin start serves http requests.
Starting the server with thin start --ssl serves https requests.
Is there a way to have thin serve both http and https requests concurrently?
The reason I ask is because when I use redirect_to some_path in my controllers, they redirect to http. Since thin is serving https requests, nothing is rendered.
Note: I'm using Rack::SSL in Rails 3.0.7.
(Comment converted to answer as requested.)
Simplest option is probably to run two separate instances of thin: one accepting SSL requests and one accepting plaintext requests. Any reason you don't want to do this? (Alternatively, if thin is running behind another web server, like Apache or Nginx, you only need one instance of thin: the frontend server can report whether the request came in over SSL.)
You can't accept both HTTP and HTTPS connections on the same port. (This is why, by default convention, HTTP runs on port 80 whereas HTTPS runs on port 443.)
you can use foreman (https://github.com/ddollar/foreman);
You create a Procfile with 2 process then start both with forman start command.
put this on a file called Procfile:
web: thin start
ssl: thin start --ssl
Then use foreman start and he start the 2 process.
This is how i am using... hope this helps you!

Resources