need a crash course in HTTPS / SSL for Rails - ruby-on-rails

I've got our Ruby on Rails app up and running on Heroku using HTTP. Now it's time to use HTTPS during the login process and for all transactions after the user is logged in. But I'm not sure where to start.
configuration
We're using:
Ruby (1.9.2)
Rails (3.0.5)
Devise (1.5.3)
Our domain (registered by GoDaddy) is oursite.com (not its real name), which resolves to oursite.herokuapp.com. I want secure transactions to be performed in a subdomain https://secure.oursite.com. I've purchased an SSL certificate from GoDaddy, created the key files, signed up for the Zerigo DNS service and set oursite.com nameservers to point at Zergo's servers. And on Heroku, I've done:
heroku domains:add secure.oursite.com
heroku ssl:add final.crt site.key
heroku addons:add ssl:hostname
the questions
If a user arrives at our site under http://oursite.com, how (and when) do I switch to https://secure.oursite.com?
How do I enforce using https for any secure transaction (e.g. submitting a password)?
How does one test this stuff using localhost:3000?
Concrete answers, general answers, and pointers to tutorials and examples are equally welcome. Thanks!

First:
redirecting from http://example.com to https://example.mysite.com
... is a very specific question that supersedes this very general question. I'll summarize the best bits of info I found in the last 24 hours, as it may be helpful to someone else.
The Heroku article on SSL is a must-read if you're deploying on Heroku.
Heroku also has an article describing how to purchase an SSL certificate from a general vendor as well an article describing how to purchase an SSL certificate from GoDaddy.
I was stuck for a while trying to configure the CNAME records for my Zerigo DNS service. The punch line is that if you create your Zerigo account using the Heroku dashboard, then you must configure your CNAME records using the Heroku dashboard as well. Gory details listed here.
If you're planning on upgrading to Rails 3.1, this is a good time to do so, since it has a built-in force_ssl method that is a clean replacement for various add-in gems (notably ssl_requirement).
Having said as much, the implementation of ssl_requirement in https://github.com/rails/ssl_requirement/blob/master/lib/ssl_requirement.rb is worth looking at, just to see how it uses redirect_to and the request object.
Simone Carletti has a comprehensive blog entry Configuring Rails 3 to use HTTPS and SSL, covering both Rails 3.0 and Rails 3.1.
Hope this is helpful...

I would have a look at ssl_requirement. This allows you to secure various parts of your application thus forcing you to only serve certain pages over HTTPS.
https://github.com/rails/ssl_requirement
With local development, you'll need to setup some sort of Apache / NGinx setup with a locally signed cert bolted on. A quick google uncovered this:
http://www.subelsky.com/2007/11/testing-rails-ssl-requirements-on-your.html

Related

Custom Heroku domain will not reflect upgrade from HTTP to HTTPS

I am using Automated Certificate Management that Heroku makes available for apps with paid dynos. my_app.herokuapp.com accurately reflects the SSL certificate and loads as a HTTPS:// page.
But my custom domain, www.my_app.com doesn't load as HTTPS://
My custom domain is from Google Domains and here is the CNAME mapping -
Custom Resource Records
www is mapped to www.my_app.com.herokudns.com.
Subdomain forward
my_app.com --> https://www.my_app.com
Any thoughts on where I could be going wrong? I can't seem to find step-by-step instruction anywhere, please point me to any resources you all found to be useful.

Heroku ACM Letsencrypt failure/waiting with rate limits

I have a site with multiple domains on Heroku, using Gandi for DNS. Using ACM on Heroku I got a lot of failures for the apex domains and tried again a few times - now my certs:info says "no SSL available" and certs:auto is stuck at "Waiting".
I also tried using different websites that are linked on letsencrypt and wanted to generate files and challenges, but did at some point get no challenge keys for my domains anymore.
Question: How can I check whether my requests are rate limited? Heroku does not show this info (just "waiting"). Thank you.

Rails tenanted app with CloudFlare and subdomains

I'm building a tenanted Rails application on Heroku which uses subdomains for each tenanted instance. The problem is I can't seem to get CloudFlare to properly cache a subdomain.
I have my Application hosted on heroku at say whatever.herokuapp.com
And using CloudFlare I'm pointing my main application at heroku's CNAME (whatever.herokuapp.com) and that works fine.
I'm using a wild cards *.mydomain.com on Heroku and then using CloudFlare again to point at them.
So say I create an app myinstance.mydomain.com on CloudFlare -> whatever.herokuapp.com
because I'm using the *.mydomain.com on Heroku it works fine.
BUT when I try to turn on the Acceleration (CloudFlare caching) it immediately breaks and all I see is a CloudFlare error Error 1001 telling me:
Most likely: if the owner just signed up for CloudFlare it can take a few minutes for the website's information to be distributed to our global network.
From their help desk:
Fundamentally in a standard set up the domain needs to be added to
CloudFlare in order for us to understand how to route traffic for that
domain.
If you wanted a setup where anybody in the world could CNAME to your
CloudFlare configuration, that is possible but it's an Enterprise
feature. We call it "Managed CNAME" - if that's something you're
interested in do let me know and I can put you in touch.
FYI, CloudFlare Enterprise averages at $5,000 a month.
CloudFlare is great in that it just works without much customization starting at zero cost, but unless your multi-tenanted app is for Bank of America or other Fortune 500 company I'd suggest something like Fastly ($5-50/month) or some other DIY caching solution that allows you to setup caching as you need rather than a one-size-fits-all top down solution.
https://devcenter.heroku.com/articles/fastly
Works directly with Heroku but there might be other solutions that work equally well.
That error can also occur if you're pointing a domain/subdomain not on CloudFlare to a domain that is on CloudFlare (creates a DNS resolution lookup error). I would probably contact CloudFlare support for additional assistance and troubleshooting.

Need to link WP Blog with Rails App on Heroku

I have a client who wants to migrate his Rails app to Heroku. However the client also has a blog associated with his domain that runs on WordPress. Currently, the WordPress blog is running happily alongside the Rails app, but once we migrate to Heroku, that clearly won't be possible.
The url for the app is like http://mydomain.com, and the url for the blog is like http://mydomain/blog.
I realize that the best long-term solution is to redo the blog in a Rails format like Toto or Jekyll. But in the short term, what is the best way to continue hosting the WP blog where it is (or somewhere) but use Heroku to run the app? The client doesn't want the blog to be on a subdomain, but to remain at mydomain/blog for SEO reasons and also since there is traffic to the blog. I have two ideas:
Use rack_rewrite or refraction (or just a regular old 301 and Apache mod_rewrite) on the old (non-Heroku) server to redirect the main url from the old site to Heroku. In this case, I can just leave the Wordpress blog running happily where it is. I think?? Is there a reason to choose one of those options (rack_rewrite, refraction, or mod_rewrite) over the others if I do it this way?
Switch the DNS info to point to the Heroku site, and then use a 301 redirect from the blog to the old site. But then I'll have to get the old (non-Heroku) site on a subdomain and use some kind of rewrite rules anyway so it looks like it isn't a subdomain.
Are either of these approaches preferable, or is there another way to do it that's easier that I'm missing?
The only tenable long term/scalable solution would be to host the blog permanently on a sub-domain or different domain and add a redirect from mydomain.com/blog to the new location (ie: blog.mydomain.com).
You would need a single server running a front-end like Apache/nginx on mydomain.com to serve up mixed back-ends like Rails and Wordpress and that is not possible on Heroku.
Sadly, this is where you need to dig in as a consultant and be stern with your client about the technical limitations.
Why does you client want to migrate to Heroku? Is there a larger goal behind that you could accomplish with different hosting where you control the front-end and can mix in different back ends?
Another solution is to set heroku to http://app.example.com, and Wordpress to http://example.com. You put your Wordpress-landing page in the root , and blog on /blog. When the user click "login" or "signup" on the landing-page, they're linked to the heroku-app.
This will be optimal in a SEO-perspective, but require some DNS-knowledge.
Winfield's answer is not correct. You can run a reverse proxy on your rack server (via Heroku) to direct to the blog, wherever it may be.
See https://github.com/jaswope/rack-reverse-proxy
After you install the gem and set up your app according to the docs, your ./config.ru file will have something like this:
use Rack::ReverseProxy do
reverse_proxy(/^\/blog(\/.*)$/,
'http://<app-name>.herokuapp.com$1',
opts = {:preserve_host => true})
end

Rails, Heroku and Subdomains. Is my special case scenario feasible?

Here is my scenario:
I have an application that will have to support multiple clients. Each client will be given a subdomain for there service. We will also have a brochure website that doesn't have the application, its just a website about the product and how potential clients can setup an account with us.
Given:
www.mycoolsite.com would point to a brochure app on Heroku.
client1.mycoolsite.com, client2.mycoolsite.com and client3.mycoolsite.com would all point to the same SaaS application that could tell the difference between each request and I should be able to handle so they only see their date (i.e. setting a global client_id or something like that)
How do I go about doing this? I haven't done a lot with DNS so I'm pretty clueless about where to start with this.
Thanks.
No sweat. We do that now, at Heroku. We happen to use Godaddy for the domain registrar, but any DNS control panel will let you do the same thing.
The other explanations I read here are a little general, here are the specifics...
The explanation at heroku is very good, at : http://docs.heroku.com/custom-domains
(there's even a very good screencast shows step by step)
the key thing is if your ROOT domain (mycoolsite.com) is at Heroku you want to create THREE "A" records, because they do some fault-tolerant crossover magic. So you'd have an A record for
75.101.163.44
75.101.145.87
174.129.212.2
Now for each subdomain you create a CNAME record
www -> proxy.heroku.com
client1 -> proxy.heroku.com
client2 -> proxy.heroku.com
client3 -> proxy.heroku.com
NOW on the HEROKu side, you have two apps right? The 'brochure app' and the saas app.
Login, and for each app go to Resources -> Addon -> Get More Addons ->Custom Domains (free)
for the brochure app, add ONE domain: www.mycoolsite.com
for the saas app, add each of the clients, eg:
client1.mycoolsite.com
client2.mycoolsite.com
client3.mycoolsite.com
That's it. works like a champ. Have fun.
What you're trying to do is very feasible, and quite easy to do.
You're going to need a combination of A and CNAME records. Simply put, A records map host names to IP addresses, and CNAME records act as aliases for A records.
Let's assume that your SaaS app is hosted at 10.0.0.1 and your Heroku app is at 192.168.0.1, and that you want www.mycoolsite.com and mycoolsite.com to point at the same IP.
(Note: I've never hosted anything at Heroku, so configuring DNS that may be slightly different)
First thing you'll need is an A record for the domain itself. (I've used BIND Zone File Syntax here - hopefully your DNS provider has a much simpler administration system.)
mycoolsite.com. A 192.168.0.1 ; heroku
www CNAME mycoolsite.com ; also heroku
These two records tell us that mycoolsite.com should point at Heroku's IP address, and that www.mycoolsite.com is an alternate name for mycoolsite.com, which will also resolve to Heroku's IP address.
Now, let's set up the DNS for your SaaS site. You could set up an A record for each sub-domain, but if you move servers, you'll have a lot of IP addresses to update. The simplest option is to configure one A record, then point your app's sub-domains at it:
sassapp A 10.0.0.1 ; saas app server canonical name
client1 CNAME sassapp ; alias
client2 CNAME sassapp ; alias
client3 CNAME sassapp ; alias
You can then add as many CNAMEs as you need.
I don't see this being an issue. Rails has had support for subdomains like that in the past with help from gems like subdomain_fu. In Rails 3, subdomain support is actually built in and covered by Ryan Bates http://railscasts.com/episodes/221-subdomains-in-rails-3. Take a look at that screencast for a good direction of where to start.
I believe you'll need the custom domains add-on for Heroku http://docs.heroku.com/custom-domains.
This won't be a problem. For DNS set up an A record for mycoolsite.com pointing to the server where you want your application. Set up an A record for www.mycoolsite.com that is configured for heroku. Now you will also want to redirect traffic that comes in on mycoolsite.com without www and redirect to www.mycoolsite.com, this will keep your top-level domain serving up your brochure app. Once requests are getting to your application you can follow the tutorial that raidfive linked to that will help you through handling subdomains inside of your application.

Resources