Can not get remote ip in Rails 3 - ruby-on-rails

I am trying to get client ip in Rails 3.
Application is installed in cloud hosting, with SSL, and nginx server.
I wrote some code to get client ip.
request.remote_ip
request.env['HTTP_X_FORWARDED_FOR']
But it returns wrong address, like '10.159.21.86'
Is there any issue related Nginx server, or SSL installation?

def remote_ip
#remote_ip ||= (#env["action_dispatch.remote_ip"] || ip).to_s
end
request.remote_ip gets the ip address of the client outside of local proxies but If your request is coming from your development machine and the development machine is where your server is, probably you will get 127.0.0.1 or wrong ip But if the request is coming from another machine, this will be the IP the remote machine. However, under various conditions this may not be the real IP of the machine (machine behind proxy, using tor or other tool to hide it e.t.c.). so you can also try:-
request.env['REMOTE_ADDR']
You should visit this post written by rails contributor describing Repeated headers and Ruby web servers

I believe the issue you have is the same described in the following Engine Yard support request: HAProxy, SSL Requests & Request IP Addresses.
Apparently there is a workaround, but you are supposed to contact them directly to know what it is.
The docs team is working on formal documentation, for the short term, please open a ticket and a support engineer can help out.

If you're using SSL with HAProxy (the default configuration for multi-instance environments) then it will not be able to pull the remote IP due to the hand-off from HAProxy to Nginx. We have a solution that uses stunnel to get around this but since all SSL decryption is done on the App Master instance, if you have more than about five instances then performance will suffer.
The other option is to use Elastic Load Balancer instead of HAProxy. The documentation for that is at https://support.cloud.engineyard.com/entries/21715452-Use-Elastic-Load-Balancing-with-Engine-Yard-Cloud.
Evan

Related

Connect to rails server remotely from raspberry pi

I have ssh'd into my rasberry pi and built a rails application.
Now how do I load the rails app from another machine?
I have tried IP:port in a web browser, but this fails.
Can I use ssh from a web browser to load the rails server process?
Are there gems I need to install to do this?
Is there any good documentation that I have missed?
SOLUTION
use ngrok to tunnel https://medium.com/#karimbutt/using-ngrok-to-create-a-publicly-accessible-web-facing-raspberry-pi-server-35deef8c816a#.sraso7zar
Maybe the problem is with the IP address you're trying to use. Servers don't necessarily forward their public IP traffic to localhost automatically.
Perhaps you could configure the IP address somehow, I don't know (others might?). Alternatively, you have a use a "local tunnel" service like ngrok or localtunnel. What these do is create a public URL for your localhost (i.e. your "loopback" address), so anyone can access it.
I spoke with a Ngrok author via email. He ensured me that I shouldn't need to expect any downtime from the service or to have to manually restart it. Although keep in mind that if you're on the free plan, whenever you restart Ngrok you're going to get a different URL. He also described it as kind of like a "souped up SSH -R"

Rails app call APIs using proxy

I have subscribed to an API service which provides access based on static IP (For both Live and Testing).
Since my development area ISP doesn't provide a static IP, I have enabled API access to my staging machine IP, which is static. I installed squid and enabled/setup a proxy server in my staging server so that I can use it as a proxy and make calls to the API while i do development.
I am using Mac for my development and Networking>Proxy settings wont work for system wide( Terminal ). Due to this, I was using Trial versions of MacProxy, proxifier( proxy clients) and all was was working fine till trial expired. Are there any free alternatives to this for Mac?
I tried to setup proxy by creating ssh socks proxy and setting http_proxy="xxx". In terminal. When I check terminal IP post setting using curl ipecho.net/plain ; echo, it shows proper IPs but when I run local rails development server and tries to access the API, its rejecting call with invalid IP (it shows non proxied IP)
An free alternative that might solve your problem might be a project on github:
sshuttle (read me)
It forwards TCP and DNS requests a remote ssh server.
The most basic use of sshuttle looks like this:
./sshuttle -r username#sshserver 0.0.0.0/0 -vv
To tunnel all traffic you might do:
./sshuttle --dns -vr ssh_server 0/0
There are also helper functions available here, which can simpify some of the commands.
The system level proxy settings aren't used by ruby applications. Typically this is a code level option passed to the library you are using to make connections.
If you want Savon to use a proxy then you need to pass this to Savon when you create the client:
client = Savon.client(proxy: "http://example.org", ...)
If this call is being made inside a gem, then unless that gem already provides that option then you would need to fork it to add the option
The gem you mention seems to already implement this - it's configuration class has a proxy attribute that seems to be passed through to savon.

How do I make my ruby on rails app respond to external requests (visible to the public on the internet)?

Problem:
My rails app (on my local machine) only responds to requests sent from the same machine to localhost, 127.0.0.1, or my internal ip address. When I try to hit it using my internet ip or from any other machine, inside or outside of my network, it just times out. I'm on Mac OS 10.9.1, ruby 1.9.3, rails 4.0.0.
I've done a lot of searching but all I can find is problems where people didn't forward their ports or bind the right ip.
Here are the areas I've investigated:
Ports -
I've tried several different ports. I configured my router to forward every port I tried but got the same result. I thought maybe there was a problem with the router so I built a simple server in Java and bound all the same ports I was binding with my rails app. Sure enough, when I hit the Java app using my internet ip it worked just fine so the router/firewall/port forwarding isn't the problem. Also, I run an apache server on port 80 and that has never had any problems. I turned apache off and tried port 80 for my rails app but that didn't fix the problem.
Rails Server -
I started with WEBrick and I thought that perhaps there was some setting inside that blocked external requests. I searched google extensively and found nothing on that matter. Just to be safe I installed Thin and got the exact same result I did with WEBrick. One interesting thing is that when the rails server is started, the external request takes a long time to time-out, but the server console displays no output at all. However if I try to send the same request w/out starting the server at all it fails immediately.
User Permissions -
I started the server with root (i'm starting to just shoot in the dark here) and it had no effect.
Environment -
I was starting in development environment originally because I'm developing but just for fun I tried starting in production and it also made no difference.
PLEASE HELP ME SMART PEOPLE
Update:
I installed the app on my Ubuntu machine and it doesn't have this problem! So that suggests the problem may have something to do with Mac OS.
SOLVED:
It turns out that in the System Preferences -> Security & Privacy -> Firewall in Mac OS, it was somehow set to block incoming connections to Ruby 1.9.3. I must have accidentally set that some time ago.
The problem is you are probably trying to request the page from your local machine (or any computer on your local network, behind your firewall) to your public IP expecting a result... not unless you setup routes through your firewall for this (and not usually available on a consumer level router... linksys, dlink, etc)
So forward port 80 if you are using something like pow, or 3000 for web bricks default port to your local machine
Then have someone outside your local lan request your external (public) IP
This may be related: Rails 3.1 on Ubuntu 11.10 under VirtualBox very slow
Your mention of slowness combined with the use of webrick makes me think you've got some reverse-DNS lookup awfulness going on. A quick first step is hacking /etc/hosts to bypass this lookup.
The situation I dealt with on Ubuntu was solved in the short-term by hacking /etc/hosts. You could do this quick hack in order to see if it is indeed just webrick's reverse-DNS lookup. Edit /etc/hosts and add a line for the external user's IP address, something like this:
156.123.48.55 TestPerson
Replace the IP address with the tester's IP address. Since you said you can get the external request to hit an Apache server on port 80, you can grab their IP address from the Apache access logs if necessary, otherwise just ask the person testing.
You could also try a different web server, such as unicorn, which may help out. Add "gem unicorn-rails" to your Gemfile, run bundle install, and then (according to their docs), rails server will just use unicorn directly.
With any local server, you'll need to correctly configure port forwarding on your firewall. Like said by CaptChrisD, tests must be done by an external IP/browser (if you own a server, ssh on it, then w3m to test).
I already had same symptom (server started => timeout, server stopped => fail) and the origin was an issue with firewall configuration. I think it is your problem.
With MacOS, Pow is really awesome: installation is easy, no configuration required (no /etc/hosts…). Moreover, they give you a hook for external access to your virtualhosts (but you still need port forwarding on your firewall).
Otherwise, there is other solutions like Forward to do it without firewall configuration (30-days free trial).
Hope this helps!

Connect to remote database from Heroku with static IP (Since database server will only allow whitelisted IPs)

I am running a Ruby on Rails application on Heroku and my database is in someother place where it will be accessed with certain whitelisted IP's only but since heroku doesn't provide dynamic IP's I thought of using proximo.
Please help me how to connect to remote database with proximo from heroku.
We had a difficult time achieving this (we ended up whitelisting every domain)
IP's
The problem is Dyno's are hosted on AWS' EC2 cloud - meaning they aren't actually Heroku's servers. This causes a lot of problems, as the IPs are all shrouded & change:
Because the Heroku dyno grid is dynamic in nature, the IP address that
a given dyno will be assigned over time will be both dynamic and
unpredictable. This dynamic sourcing of outbound traffic can make it
difficult to integrate with APIs or make connections through firewalls
that require IP-based whitelisting
After seeing the proximo addon, you may be able to achieve what you need using a static IP
Proximo
According to the proximo tutorial on Heroku's site, you should be able to install the add-on & receive your outbound IP relatively simply:
$ heroku addons:add proximo:development
Adding proximo to sharp-mountain-4005⦠done, v18 ($5/mo)
Your static IP address is 127.0.0.1
You should then be able to use this on your db host - to allow the IP
No ruby database adapters natively support proxy connections so for database access you need to proxy your calls via a SOCKS proxy. A SOCKS wrapper script to do this is available as part of our QuotaGuard Static Heroku add-on.
You configure this by prepending the call to the wrapper script in your Procfile so should work with minimal integration.
web: bin/qgsocksify bundle exec unicorn -p $PORT -c ./config/unicorn.rb
By default this wrapper routes all outbound TCP traffic via the proxy but there is additional configuration available to limit this to just your database traffic.
A workaround is to whitelist all IP adresses from your SQL database provider admin interface:
You can do this by whitelisting 0.0.0.0/0. (In Google Cloud SQL, you can do this under "authorized networks")
If you do so, it is highly recommended to configure your connection to use SSL and to only allow SSL connections to your database.
You can configure NGINX as your reverse proxy to allow your Heroku app to connect to the IP address(which is your NGINX server and whitelisted), the reverse proxy will connect to the DB.
https://stackoverflow.com/a/27874505/1345865
http://blog.talenox.com/post/107675614745/how-to-setup-static-ip-on-heroku

Remotely viewing web pages served by pow.cx

Using WEBrick you could navigate to an app you were serving from another device/virtual machine by navigating to your.ip.address.here:port
Is it possible to do something similar with pow.cx?
The latest version of Pow (0.4.0) now includes xip.io support. You can read about the release here.
Here's a quick explanation of how this helps Pow serve your Rails apps across your entire local network, from their post:
Say your development computer’s LAN IP address is 10.0.0.1. With the
new version of Pow, you can now access your app at
http://myapp.10.0.0.1.xip.io/. And xip.io supports wildcard DNS, so
any and all subdomains of 10.0.0.1.xip.io resolve too.
Here's a description of xip.io, from their site:
xip.io runs a custom DNS server on the public Internet. When your
computer looks up a xip.io domain, the xip.io DNS server extracts the
IP address from the domain and sends it back in the response.
There are basically two options:
Don't use pow: run your applications on localhost as usual and access them as usual
Edit the hosts file (or local DNS) to point your server machine ip
Example accessing from a virtual windows machine:
Suppose you are running two rails applications in pow: store.dev and auth.dev, and you want to access them from a windows xp virtual machine to test them with IE, you only need to edit your hosts file to add the lines:
C:\WINDOWS\system32\drivers\etc\hosts
# Allow to access applications in pow.
# The ip address points to the host machine localhost, that usually is the default gateway
10.0.2.2 store.dev
10.0.2.2 auth.dev
And then open the IE browser to access your applications in http://store.dev and http://auth.dev respectivelly.
Specifically, no, because Pow uses the Host header of the request to determine which app you need to access. To get that working remotely, you would have to have the remote machine map the required domain name to your IP address - either with a local DNS server or by editing the HOSTS file. Both of which are possible but annoying.
The simplest thing to do in that case is to start up a standalone Rails server as you mentioned (using ./script/server or rails s depending on the version), and then you can address http://[ip address]:3000 as before.
In other words, Pow works because it intercepts your local domain resolution, something that isn't affected by (or available to) remote machines.

Resources