0

I wanted to restrict access to certain pages of my website in a certain controller to a certain IP address range, which I figured out how to be done but I can't find a way to get the IP address range using PURE code... Is it possible anyways?

mr.coder
  • 59
  • 4
  • Possible duplicate of [What's the difference between request.remote\_ip and request.ip in Rails?](https://stackoverflow.com/questions/10997005/whats-the-difference-between-request-remote-ip-and-request-ip-in-rails) – Matthew Sep 15 '18 at 17:12

2 Answers2

2

You can find the IP of the client making the request from request.remote_ip .

Then define a custom constraint to restrict the access to certain IPs or IP ranges.

Your route.rb file would look like this

require "ipaddr"

MyApp::Application.routes.draw do
  resources :users

  constraints Whitelist.new do
     get 'protected_routes'
  end

end

class WhiteList
  def initialize
    @ips = ['127.0.0.1', '203.123.10.1']
    @ip_ranges = [
                   {
                     start_ip: '192.168.0.1',
                     end_ip:   '192.168.0.30'
                   },

                   {
                     start_ip: '10.1.1.1',
                     end_ip:   '10.1.1.100'
                   }
                 ]
  end

  def matches?(request)
    return true if @ips.include? request.remote_ip

    remote_ip_address = IPAddr.new(request.remote_ip).to_i

    @ip_ranges.each do |ip_range|
        low  = IPAddr.new(ip_range[:start_ip]).to_i
        high = IPAddr.new(ip_range[:end_ip]).to_i
        return true if (low..high)===remote_ip_address
    end

    return false
  end

end
mr.coder
  • 59
  • 4
Vishnuprasad R
  • 1,682
  • 13
  • 23
1
class SomeController < ApplicationController
  before_action :restrict_access, only: %i( action1 )

  def action1
    # something
  end

  def action2
    # something else
  end

  private

  def restrict_access
    unless TRUSTED_IPS.include? request.remote_ip
      flash[:error] = "Sorry. You are not allowed."
      redirect_to root_path
    end 
  end

  TRUSTED_IPS = [
    "192.168.1.13",
    "192.168.1.19",
  ]
end

That would allow you to restrict access to specific IPs. If you want to restrict to a single IP range, you could also do something like:

private

def restrict_access
  if !( ip_to_int(request.remote_ip) > ip_to_int(MIN_IP) 
    and ip_to_int(request.remote_ip) < ip_to_int(MAX_IP) )
    flash[:error] = "Sorry. You are not allowed."
    redirect_to root_path
  end
end

def ip_to_int(ip)
  request.remote_ip.split(".").map{|el| el.rjust(3,'0')}.join.to_i
end

MIN_IP = "192.168.0.13"
MAX_IP = "192.168.0.46"
Flavio Wuensche
  • 9,460
  • 1
  • 57
  • 54
  • Thank youu Flavio I would be using this code in some of my controllers as well I really appreciate your help! – mr.coder Sep 15 '18 at 21:13