14

It was easy for me to connect to my remote mysql server on AWS using a sequelpro, however I'm struggling with doing the same thing with mongodb.

I tried setting up an ssh tunnel via command line like so:

ssh -fN -l root -i path/to/id_rsa -L 9999:host.com:27017 host.com

I also tried it with replacing host with an ip address

the idea is to forward all mongodb connections on port 9999 to the one on the host on port 27101.. however when I run the command:

mongo --host localhost --port 9999

the connection fails, I get this instead:

MongoDB shell version: 2.6.0
connecting to: localhost:9999/test
channel 2: open failed: connect failed: Connection timed out
channel 3: open failed: connect failed: Connection timed out
2014-05-22T14:42:01.372+0300 DBClientCursor::init call() failed
2014-05-22T14:42:01.374+0300 Error: DBClientBase::findN: transport error: localhost:9999 ns: admin.$cmd query: { whatsmyuri: 1 } at src/mongo/shell/mongo.js:148
exception: connect failed

if I run sudo netstat -plnt I get the following (which seems in order):

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      4242/node           
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1342/httpd2-prefork 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      2552/sshd           
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      2505/master         
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      11719/mongod        
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      16561/redis-server  

any idea what i'm doing wrong?

update: this is how the final functional command looks like (credit goes to kenster):

ssh -fN -i ~/path/to/id_rsa -L 6666:localhost:27017 root@remote.server.com

where the -fN command make this command run in the background

19

The "channel 2" and "channel 3" lines are from ssh. The sshd instance on the remote server is trying to connect to host.com port 27017 in order to service a tunnel connection, and it's getting a "connection timed out" error.

In other words, sshd on the remote server can't reach the target of the tunnel. Since the remote host is also the host which you're supposedly tunneling to, it's hard to say what the specific problem is. It could be that "host.com" resolves to more than one IP address. You're making an SSH connection to one server in the cluster, and then a different server in the cluster is being chosen as the tunnel target. You could try changing the tunnel target to "localhost" instead of "host.com":

ssh -fN -l root -i path/to/id_rsa -L 9999:localhost:27017 host.com

Update:

"-L 9999:localhost:27017" means that the ssh client on the local server listens for connections on port 9999. When it gets a connection, it tunnels the connection to the sshd instance on the remote server. The remote sshd instance connects from there to localhost:27017. So "localhost" here is from the perspective of the remote server.

With the netstat output, it's a little clearer why it wasn't working before. The "127.0.0.1:27017 " part means that Mongodb is specifically bound to the localhost (127.0.0.1) interface on the remote host. You can't contact that instance of mongodb directly by trying to connect to the host's regular IP address--you can only contact that instance of mongodb through the localhost address. And of course, since it's localhost, you can only contact if from a client running on the same host.

So, the way you're doing it now--tunnel a connection to the server through ssh and then connect to localhost from there--is the way to do it.

  • that's really strange.. the way you use -L seems to contradict the ssh man page: -L [bind_address:]port:host:hostport Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side. it explicitly says that host is the remote server's host.. you are using it for local? – abbood May 22 '14 at 23:01
  • I tried the same command with an ip address.. but same result.. btw I updated my question to show the result of me running netstat for listening services if that helps – abbood May 22 '14 at 23:35
  • after reading around here and here turns out your way is the correct way. however I have a question.. in the first link the guy explains why your command is necessary--> – abbood May 23 '14 at 0:09
  • 1
    ssh -L 27017:myserver:27017 user@myserver Should listen on port 27017 on localhost, then tunnel over the ssh connection to my server and then hit myserver on port 27017. Now, if myserver is listening on only localhost, this won't work, because the hostname may be pointing to the external IP address. If that is the case, try this ssh -L 27017:localhost:27017 user@myserver – abbood May 23 '14 at 0:10
  • can you please explain what this means? what does 'hostname is only pointing to external IP address' mean? – abbood May 23 '14 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.