Rails app call APIs using proxy - ruby-on-rails

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.

Related

Redis ios client using websocket in secure way

I am currently communicating with my Redis instance from my iOS client using a websocket. I specify the host address and the listening port and execute some Redis Commands from my IOS client directly.
The reason I am doing that because I am doing real live geolocation tracking and executing these commands from my backend which is in php will result in latency.
I am afraid that this is not the most secure way because if someone knows my host address and ports he will be able to access my Redis Instance.
My question is how can I communicate with my Redis Instance from my iOs client using a websocket but in a more secure way.
#Ahmed,
I read the answer provided by #ThatCampbellKid and the comments and understand your wish to have the iOS client communicate directly with the Redis server.
However, Redis was NOT designed for this approach. As indicated in the documentation (emphasis added):
Redis is designed to be accessed by trusted clients inside trusted environments.
The internet is not a trusted environment and the direct access allows Redis to be accessed by non-trusted clients.
The same documentation gives the following example (emphasis added):
In the common case of a single computer directly exposed to the internet, such as a virtualized Linux instance (Linode, EC2, ...), the Redis port should be firewalled to prevent access from the outside. Clients will still be able to access Redis using the loopback interface.
The correct approach would be to use a dynamic application to authenticate clients and bridge between clients and the Redis server.
You can use JWT (the nginx module suggested by #ThatCampbellKid), PHP, Ruby, node.js, Java, C or whatever you want - but you will need to use something.
I'm sorry to say this, but any other shortcut will expose your system to security risks.
EDIT:
Yes, you can still use WebSocket.
The difference is that this architecture is not secure:
Client <=(WebSockets)=> Redis
And this architecture is secure (if implemented correctly):
Client <=(WebSockets)=> Authentication Layer <=(TCP)=> Redis
There are a couple ways of doing it, depending on how your project is set up. You could add an NGINX loadbalancer in front of your php/redis containers that accepts JSON Web Tokens for authentication.
https://www.nginx.com/blog/authentication-content-based-routing-jwts-nginx-plus/
Redis has the ability to do authentication as well, but isn't considered best practices it looks like, but you can find more information about it here also:
https://redis.io/commands/auth
As you said you are already running Nginx then have a look at the Nchan websockets module
Your Nginx install can then serve websocket connections directly and it has support for several methods of client authentication as well as direct integration with redis

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"

Jenkins Server - Issues with setting URL

I am trying to set up an internal Jenkins server for our QA team and facing some issues with the server URL. This is inside a corporate network and all sort of firewall and proxy settings are in place, however we need to access the server only with in our internal network. This server runs from a Mac Mini. I was able to install and access the server without any issues using localhost:8080.
I tried to set a custom URL (something like testjenkins.local:8080)under the Manage Jenkins option and never was able to access the server. The only option worked for me is with the IP address (IP:8080). I was able to access the server from other machines in the network using this URL.
The real problem with the above setup is that the machine IP changes(I am not able to make it static), and hence wont be able to get an always working URL.
Highly appreciate if any one guide me in the wright direction.
Given you have a dynamic IP on your server, a good alternative would be using ngrok. Ngrok can expose the port 8080 of that server to the internet via secure tunnels, and you can access it via an URL, so changes in the IP won't affect it.
However, ngrok exposes the server to the whole Internet. To make it accessible only for your team you can add authentication in both ngrok tunnel and Jenkins server (would it work for you?).

How to view neo4j database on the hosted linode server

I am running standalone neo4j database server at localhost:7474 on a linode instance.
Is there any way to view this in the browser?
If you have SSH access to the Linode instance then you can run ssh -L 7474:localhost:7474 youruser#123.123.123.123 which will tunnel the remote port 7474 to localhost 7474. In your browser you can now use http://localhost:7474 to see the remote server without opening anything to the world.
You want what's called a "reverse proxy". Outside of your box, you can't talk about localhost:7474 as a hostname. So you want an external facing web server that "proxies" requests and sends them to localhost:7474.
One such option is Apache mod_proxy used as a reverse proxy. Examples on how to use it are behind the link. In general it's going to boil down to a configuration directive that looks something like:
ProxyPassReverse /neo4j http://localhost:7474
You also really want to read the documentation on securing the neo4j server.
WARNING - neo4j's web interface will let you do just about anything without authentication, including delete all of your data, change it, put new data in, and so on. It is a very bad idea to expose that functionality to the entire internet. So if you use a reverse proxy as suggested above, make sure you add some authentication layer (again you can do this with apache and mod_proxy) to permit just any random person from connecting to your instance and optionally deciding to trash it.

Can not get remote ip in Rails 3

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

Resources