Search code examples
ruby-on-railsherokuproxyblock

Block an undesirable proxy from accessing a Rails 2.3.15 app on Heroku


I'm looking for a way to block a specific proxy, for example this one:

http://demosites.conversionsupport.com/reverseproxydemo?domainpath=http://stackoverflow.com

I don't want it accessing/displaying my rails 2.3.15 app on Heroku. I've played with the gems rack-rewrite and rack-block, but had no luck going that route because I need to block by domain name, not IP address (the thing is hosted on ghs.google.com, which I'd rather not block)

In a perfect world I could redirect to my canonical URL, but I'd also settle for a 503 or a 404.

(The reverse-proxy in question is used to show off the proxy owner's chat widget app, but on any website, instead of restricting use to sites owned by the proxy owner's potential clients. It also causes some nasty crawl bot errors to be logged in google's web master tools. That in and of itself isn't a big deal, but when coupled with that breaking-the-site-functionality thing, and the fact that my site has a Creative Commons license which requests the site not be reused for commercial purposes, it makes me want to put a stop to it.)


Solution

  • Since none of the gems we mentioned above can be used with rails 2.3.15 (which I've since updated to 2.3.18), and I don't have the time to do the arduous upgrade from rails 2 to rails 3, I ended up going with the solution below. (Note: this solution only applies to pages served from /app. It does not apply to pages served from /public. I'm still looking for a solution to protecting the pages served from /public.)

    I dropped the bits of code below into /app/controllers/application_controller.rb

    1.2.3.* is a placeholder for the block of IP addresses that I'm actually blocking. Replace 1.2.3 with the first three octets of the 0/24 range that you want to block, or replace 1.2.3.* with a single ip address to block a single IP. You'll also want to replace http://YourCanonicalDomain.tld/503.html with the address of your 503 page, or other page you want to send users to so they can view your page at the URL it was meant to be displayed at, instead of leaving them at the reverse proxy's URL:

    before_filter: block_ip
    

    then later in the file:

    def block_ip
          if request.remote_ip.match('1.2.3.*')
        redirect_to "http://YourCanonicalDomain.tld/503.html"
        return
      end
    end
    

    My 503.html, which resides in /public, displays a note to the user that they're trying to view content in a way that is not allowed, and that they'll shortly be redirected to the homepage for the site. The 503.html contains this within the :

    <meta http-equiv="REFRESH" content="15;url=http://YourCanonicalDomain.tld">
    

    Replace http://YourCanonicalDomain.tld with the page you want to redirect users to. Raise or lower the number 15 to raise or lower the amount of time the page is displayed before the user is redirected.