0

I've been doing some testing with Ruby drb. I have the following code (just the example code found on the ruby docs)

SERVER:

require 'drb/drb'
URI="druby://:9000"
class TimeServer
  def get_current_time
    return Time.now
  end
end
FRONT_OBJECT=TimeServer.new; $SAFE = 1
DRb.start_service(URI, FRONT_OBJECT)
DRb.thread.join

CLIENT:

require 'drb/drb'
SERVER_URI="druby://private-ip:9000"
DRb.start_service
timeserver = DRbObject.new_with_uri(SERVER_URI)
puts timeserver.get_current_time

This works if we're both connected to the same router (and share the same private-ip x.x.x.151 and x.x.x.155 for instance).

But, when we're testing on machines miles apart and changing the server URI to SERVER_URI="druby://public-ip-of-server:9000" on the client side, we're getting a connection timeout.

Does anyone know the solution? Port forwarding on the router is not an option.

sawa
  • 165,429
  • 45
  • 277
  • 381
KenGey
  • 406
  • 4
  • 15
  • What do you mean port forwarding is not an option? If the router or firewall is blocking port 9000 then you won't be able to connect unless you port forward. – Casper Dec 05 '12 at 14:50
  • Your only other option is an SSH tunnel if you can't port forward. – Casper Dec 05 '12 at 14:51
  • Ok, I also tried port 80 (default web service port on 'every' router that forwards to a pc with port 80 open), but without succes. – KenGey Dec 05 '12 at 15:09
  • 1) Are you sure the router forwards 80 to the pc that has DRB running (have you checked the router settings)? 2) Have you checked that the pc is not blocking port 80? – Casper Dec 05 '12 at 15:31
  • 1) No, I haven't done this... The reason is that I found somewhere that this is standard on every router. + I'm working on a script for users that don't have any idea what a router is in the first place. 2) If the computer was blocking port 80, I wouldn't be able to start the service in the first place i guess. Because running the script twice, the second time drb says the port is in use.. 3)If changing router settings is really necessary, I must find another way for ruby communication over the internet. But, how does software like Skype for instance does the trick? – KenGey Dec 05 '12 at 17:24
  • No it's not standard. If you have 5 computers connected to the router in your internal network and someone connects to port 80 from the outside how will the router know which internal computer to forward the connection to? The answer is it doesn't - unless you tell it. So you have to configure the router manually. If the computer is blocking port 80 you can still start the service. It's only blocking connections from the outside, it does not prevent you from creating the service. Skype uses UPnP and also uses an external server for connection routing. – Casper Dec 05 '12 at 19:57
  • That means in most cases Skype always connects OUT from the computer. People seldom connect IN to your computer. Outgoing connections are always easy to make, incoming is much harder unless you use UPnP to open ports in the router or some other advanced trickery. – Casper Dec 05 '12 at 19:58
  • So your options are: a) Move the server to a computer that is not behind a router, and always connect OUT from your client computers. I.e. reverse server and client in your system if that is possible. b) Study UPnP and see if you can find a library for Ruby on that..it could get quite complex. c) Manually configure the router. – Casper Dec 05 '12 at 20:00
  • Example on Skype: http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html – Casper Dec 05 '12 at 20:03
  • @Casper. Thanks for you explainations! I think the best option is to search for another solution than drb. It's for a Trimble SketchUp plugin so I can't expect users to configure their router. – KenGey Dec 06 '12 at 08:29

1 Answers1

0

I think your problem is that your dealing with a State-full Packet inspection firewall(spi). most firewall will not allow network connections from the outside that were not established from the inside first.

the way skype get around this is to have the client establish the connection to a server on the internet then connect back and have the client connect to additional port required to complete the contention. In any case one side needs to accept connections.

1) If you have access to a web server you could implement your service as a restfull web service.

2) drb does not provide encryption or security so you might want to think about wrapping it in ssl or ssh.