Connection refused when using Rack Proxy - ruby

I'm trying to catch all *.dev requests on port 80 and send them to the right Rack project by using Rack Proxy. I'm able to catch the requests and based on the URI I'll look for a config.ru in a specific folder. When I'm able to find one I'll boot up the server on port 3000.
After that, whenever I recieve a request on port 80, I try to set the HTTP_HOST to localhost:3000, but I'm getting the message Unexpected error while processing request: Connection refused - connect(2) for "localhost" port 3000. I am able to access the application through localhost:3000, but not through a *.dev domain. I already tried using different ports, but that's not working either, so I guess it has something to do with the user that's running it. However, I hope someone can help me with this.
require 'rack-proxy'
class AppProxy < Rack::Proxy
def rewrite_env(env)
request = Rack::Request.new(env)
site = request.host[0..-5]
uid = File.stat(__FILE__).uid
path = Etc.getpwuid(uid).dir + '/Software/Applications/'
front_controller = "#{path}#{site}/config.ru"
if File.file?(front_controller)
system "rackup -p 3000 -D #{front_controller} "
env["HTTP_HOST"] = "localhost:3000"
else
raise Exception.new "Not found"
end
env
end
end
run AppProxy.new
EDIT: I've checked if there is something listening on port 3000. After running the server and sudo lsof -i -n -P | grep TCP I get the following result for the ports 80 and 3000:
ruby 56247 root 10u IPv4 0x727d74bd0b95bd9b 0t0 TCP *:80 (LISTEN)
ruby 56247 root 11u IPv4 0x727d74bd0a3b9bfb 0t0 TCP 127.0.0.1:80->127.0.0.1:52773 (ESTABLISHED)
ruby 56255 root 12u IPv6 0x727d74bd094e3c8b 0t0 TCP [::1]:3000 (LISTEN)
I'm not sure if this is any useful because I don't know the exact meaning of this.

Solved it. The problem was that booting up the server was a bit slower then setting the HTTP_HOST to a different location and port 3000 was not in use yet. Waiting for a second solved the problem. My code looks like this now:
require 'rack-proxy'
class AppProxy < Rack::Proxy
def rewrite_env(env)
request = Rack::Request.new(env)
site = request.host[0..-5]
uid = File.stat(__FILE__).uid
path = Etc.getpwuid(uid).dir + '/Software/Applications/'
front_controller = "#{path}#{site}/config.ru"
if File.file?(front_controller)
system "rackup -D -p 3000 #{front_controller} "
sleep(1)
env["HTTP_HOST"] = "localhost:3000"
else
raise Exception.new "Not found"
end
env
end
end
run AppProxy.new

Related

Can't connect to remote PHP WebSocket server (Wrench) : ERR_CONNECTION_REFUSED

I'm trying to connect to a WebSocket server (PHP / Wrench) running on my webserver.
The configuration of the server looks like this:
$server = new \Wrench\Server("wss://localhost:8443");
$server->registerApplication('app',
new \Wrench\Application\EchoApplication());
$server->run();
I'm using port 8443 because I can't use 80 or 443 (Permission denied). The domain uses HTTPS so I have to use the wss: protocol.
I have no problem connecting to the PHP server when I run the script on my local machine (I just have to replace wss: by ws:).
When I run the server via SSH on my remote webserver, it seems to run correctly, but trying to connect to it via JS with the following call doesn't work:
var ws = new WebSocket("wss://dev.mydomain.net:8443/app");
I get an "Error in connection establishment: net::ERR_CONNECTION_REFUSED."
On my webserver panel control, the 8443 port (TCP) is open (in and out). When the PHP server is running, the command netstat -a | grep 8443 gives the following output, which I think should confirm it's open:
tcp 0 0 localhost:8443 *:* LISTEN
Is there an obvious detail I'm missing here?
I finally found a solution: instead of setting the URI of the server to localhost, I had to use 0.0.0.0. Now it works perfectly when I'm using HTTP (there's another problem when using HTTPS, but at least I have more information at this point).

Can't connect to public IP for EC2 instance

I have an EC2 instance which is running with the following security groups:
HTTP - TCP - 80 - 0.0.0.0/0
Custom UDP Rule - UDP - 1194 - 0.0.0.0/0
SSH - TCP - 22 - 0.0.0.0/0
Custom TCP Rule - TCP - 943 - 0.0.0.0/0
HTTPS - TCP - 443 - 0.0.0.0/0
However, when I try to access http://{PUBLIC_IP} or https://{PUBLIC_IP} in the browser, I get a "{IP} refused to connect" error. I'm new to AWS. Am I missing something here? What should I do to debug?
One way to debug this particular class of problem is to use netcat in order to determine where the problem lies.
If you run netcat against port 80 on the public IP address of your instance and just get a hang (no output at all), then most likely your security group isn't allowing traffic through. Here is an example from an EC2 instance that is in a security group that doesn't allow port 80 traffic inbound:
% nc -v 55.35.300.45 80
<just hangs>
Whereas if the security group is changed to allow port 80, but the EC2 instance doesn't have any process listening on port 80, you'll get the following:
% nc -v 55.35.300.45 80
nc: connectx to 52.38.300.43 port 80 (tcp) failed: Connection refused
Given that your browser gave you a similar "connection refused", most likely the problem is that there is no web server running on your instance. You can verify this by ssh'ing into the instance and seeing if you can connect to port 80 there:
ssh ec2-user#55.35.300.45
% nc -v localhost 80
nc: connect to localhost port 80 (tcp) failed: Connection refused
If you get something like the above, you're definitely not running a webserver.
I'm not sure if it's too late to help but I was stuck with a similar issue with my test server
SG Inbound: ssh -> 22
HTTP -> 80
NACL: default allow/deny settings
but still couldn't ping to the server from my browser, then I realize there's nothing running on the server that can serve the request, and I started httpd server (webserver) and it worked.
sudo yum -y install httpd
sudo service httpd start
this way you can test the connectivity if you are playing with SGs and NACLs and of course it's not the only way, just an example if you're figuring your System N/W out.
Have you installed webserver(ngingx/apache) to serve your requests. If so please share your the config files. (So that it will help to troubleshoot)
I think the reason is probably that you did not set up a web server for your EC2 instance, because if you try to access http://{PUBLIC_IP} or https://{PUBLIC_IP}, you need to have a background server to serve the http request as #Niranj Rajasekaran said.
By the way, by simply pinging the {PUBLIC_IP}, you could see if your connection to your EC2 instance is normal or not.
In command prompt or terminal, type
ping {PUBLIC_IP}
In my case, the server was running but available on just 127.0.0.1 so it refused connections from external hosts. To see if this is your situation, you can run
netstat -an | grep <port number>
If it says 127.0.0.1:<port number> instead of 0.0.0.0:<port number>, you have this problem.
Usually there's a flag or an argument in your server code somewhere to set the host to 0.0.0.0:
app.run(host='0.0.0.0') # flask example
However, in my case, I had already set this so I thought that couldn't possibly be the issue, which is how I ended up on this thread, which asks more generally about the problem. Unfortunately, I was using docker, and had set 0.0.0.0 on the container but was mapping that explicitly to 127.0.0.1 on the host in the docker-compose port-mapping:
ports:
- "127.0.0.1:<port number>:<port number>"
Changing that line to remove the host IP specification fixed the problem upon re-deploy:
ports:
- "<port number>:<port number>"

Ruby TCP chat server

Recently Iv'e been trying to program a simple TCP server to later build into a chat room. But every time I launch the server (server.rb), and then I try to use the client (client.rb) I get this error:
Sam#ANDERSAMERPC C:\Users\Sam\Documents\Coding
> client.rb
C:/Users/Sam/Documents/Coding/client.rb:6:in `initialize': No connection could be made because the target machine actively refused it. - connect(2) for "localhost" port 2001 (Errno::ECONNREFUSED)
from C:/Users/Sam/Documents/Coding/client.rb:6:in `open'
from C:/Users/Sam/Documents/Coding/client.rb:6:in `<main>'
I am using CMD to run this and I've tried turning off firewall briefly.
Here is the code for both of the programs...
This is server.rb
require 'socket'
server = TCPServer.open(2000) # Socket to listen on port 2000
loop {
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send time to the client
client.puts "Closing connection. Bye!"
client.close
end
}
Here's client.rb:
require 'socket'
hostname = "localhost"
port = 2000
s = TCPSocket.open(hostname, port)
while line = s.gets # Reads lines from socket
puts line.chop # And print with platform line terminator
end
s.close # Close socket when done
(This code is from http://www.tutorialspoint.com/ruby/ruby_socket_programming.htm just so you know.)
I guess there are 2 options:
Run your server.rb before client.rb.
Are you sure those are the exact same files that you are running. Because the error message says it can not connect to port 2001, whereas in both of your files they refer to 2000. Is it possible that you are editing and running different files? You will be surprised, how common this is here on SO :)

Ruby TCPServer always delay on dns reverse lookup? - how to disable?

I created a TCPServer with ruby gserver.
Everytime I connect remotly to the server, it takes 2-4 seconds until connection is established.
This is only happen if I connect from remote machine.
Connection from same machine has running the service will send immidiate response.
For the connection on same machine there is no difference if I connect via localhost or via the machines ip.
I think delay depends on reverse lookup but can not localize why.
in gserver.rb it is line 263
client = #tcpServer.accept
Here the delay occurs, I do not know what is in this method.
I added all machines which are used during tests to the local hosts file. But that changed nothing.
Same happens when using Webrick, I tried to set also
BasicSocket.do_not_reverse_lookup = true
as well as direct on the resulting server socket
Socket.do_not_reverse_lookup = true
as well as on client connection socket
client.do_not_reverse_lookup = true
But that also changed nothing on delay.
Whenever connection is established, the values of remote_host and remote_ip are resolved and as defined in hosts file.
I tried that running ruby 2.2.1 on ubuntu 14.04 as well as ruby 1.9.3 running debian wheezy.
Same behavior - (long) delay on connecting service.
Q: How to fix that / disable lookup on TCPServer?
The problem depends on my client machine where I run on MAC OSX Mav.
The used telnet client tries to open IPv6 connection and afterwards IPv4.
To solve the delay, just open connection with
telnet -4 my-server 3333
I have build a small connect echo servive where you can check resolves and timings.
If you change NO_REVERSE_LOOKUP you will get IPs or ADDRESSes and if not resolveable, different response times.
require 'socket'
NO_REVERSE_LOOKUP = true
CONNECT_PORT = 3333
puts "#{Time.now} Starting service on port: #{CONNECT_PORT}"
# the full hell - just to test if anything meets what we want
TCPServer.do_not_reverse_lookup = NO_REVERSE_LOOKUP
BasicSocket.do_not_reverse_lookup = NO_REVERSE_LOOKUP
Socket.do_not_reverse_lookup = NO_REVERSE_LOOKUP
srv = TCPServer.open(CONNECT_PORT)
puts "#{Time.now} Waiting for client"
client = srv.accept
puts "#{Time.now} Client connected"
client.do_not_reverse_lookup = NO_REVERSE_LOOKUP
client.print "Hello connected\n"
# in case that we disabled reverse lookup, we should only receive IP Adresses
puts "#{Time.now} Getting server address infos"
puts "SERVER INFO:"
puts NO_REVERSE_LOOKUP ? client.addr(:numeric) : client.addr(:hostname)
puts ""
puts "#{Time.now} Getting remote client infos"
puts "REMOTE INFO:"
puts NO_REVERSE_LOOKUP ? client.peeraddr(:numeric) : client.peeraddr(:hostname)
###
puts "#{Time.now} Closing connection"
client.close
puts "#{Time.now} End"
Thanks to drbrain from #ruby-lang irc for pointing me to the IPv6 problem.

Issues sending HTTP messages using Telnet?

I am going through exercises in the book "Sinatra Up & Running" and am trying to send HTTP messages to Sinatra using Telnet.
This is what I am trying to do
[~]$ telnet 0.0.0.0 4567
However, I get the error:
Trying 0.0.0.0...
telnet: connect to address 0.0.0.0: Connection refused
telnet: Unable to connect to remote host
Sinatra is listening on localhost:4567 instead of 0.0.0.0:4567 and I think that is indicative of the problem.
I found some documentation at http://www.sinatrarb.com/configuration.html that talks about being able to specifically configure the development environment to listen on 0.0.0.0. I passed in:
ruby server.rb -o set :bind, '0.0.0.0'
And was able to adjust where Sinatra was listening to 0.0.0.0:4567 but telnet 0.0.0.0 4567 still gives the same error messages.
When you tell the server to listen on 0.0.0.0, that isn't actually a specific address, you're really telling it to bind to all available network interfaces. To connect to it, use either 127.0.0.1 or localhost, which are special addresses that always mean "this host":
telnet 127.0.0.1 4567
If you bind Sinatra to 0.0.0.0:4567 and it is listening they you will be able to externally hit your machine via the machine's ip.
E.g. machine-01 (192.168.122.100) is running Sinatra, which is bound to 0.0.0.0:4567 then from machine-02 (192.168.122.200) you'll be able to telent 192.168.122.100:4567 (provided there are no firewalls).
As the other post suggested, if you're trying to do it all on machine-01, then you want to bind Sinatra to localhost:4567 (127.0.0.1:4567), then you will be able to telenet localhost:4567

Resources