How to Securely Connect to MongoDB Server Through SSH Tunnel: A Developer’s Guide


1 views

When working with remote MongoDB servers, establishing a secure connection is crucial. The SSH tunnel method provides encrypted communication between your local machine and the remote database server. Here's the proper syntax for creating the tunnel:

ssh -fN -i ~/path/to/id_rsa -L [local_port]:localhost:[remote_port] [username]@[remote_host]

The original issue stemmed from incorrect tunnel configuration. Notice these key elements:

  • Use localhost as the target address in the tunnel (not the external hostname)
  • Ensure MongoDB is binding to 127.0.0.1 on the remote server (check netstat output)
  • Verify your SSH key permissions (chmod 600 recommended)

After establishing the tunnel, test with this MongoDB shell command:

mongo --host localhost --port [local_port]

For more verbose debugging, add the --verbose flag to see detailed connection attempts.

For production environments, consider these additional parameters:

ssh -fN -M -S /tmp/mongotunnel -i ~/.ssh/id_rsa \
-L 27018:localhost:27017 user@dbserver.example.com

This creates a master connection (-M) with a control socket (-S) for easier management.

Create a simple bash script to handle tunnel creation and verification:

#!/bin/bash
LOCAL_PORT=27018
REMOTE_PORT=27017
REMOTE_USER=dbadmin
REMOTE_HOST=dbserver.example.com
SSH_KEY=~/.ssh/mongo_id_rsa

# Create tunnel
ssh -fN -i $SSH_KEY -L $LOCAL_PORT:localhost:$REMOTE_PORT $REMOTE_USER@$REMOTE_HOST

# Verify connection
if mongo --host localhost --port $LOCAL_PORT --eval "db.version()" &> /dev/null; then
    echo "MongoDB connection successful"
else
    echo "Connection failed"
    exit 1
fi

If you encounter timeout issues, check these aspects:

# On remote server:
netstat -tulnp | grep mongo
# Should show: tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN [mongod pid]

# On local machine:
telnet localhost [local_port]
# Should establish connection (CTRL+] then quit to exit)

When working with remote MongoDB instances, direct connections might be restricted due to security policies. SSH tunneling provides a secure way to access MongoDB servers behind firewalls or in private networks. The error you're seeing typically occurs when the tunnel isn't properly established or MongoDB isn't configured to accept the connection.

The correct SSH tunnel command should look like this:

ssh -fN -i ~/path/to/private_key.pem -L LOCAL_PORT:localhost:REMOTE_MONGODB_PORT username@remote_host.com

From your error logs, I notice several potential issues:

1. Using 'host.com' instead of 'localhost' in the tunnel target
2. Possible firewall restrictions on either side
3. MongoDB might only be binding to 127.0.0.1

Here's the working solution that addresses these issues:

# Establish the SSH tunnel (run in your local terminal)
ssh -fN -i ~/.ssh/your_private_key -L 9999:localhost:27017 user@your-aws-instance.com

# Connect using mongo shell
mongo --host localhost --port 9999

After establishing the tunnel, verify it's working:

# Check local port listening
netstat -tulnp | grep 9999

# Basic MongoDB command to test
db.runCommand({connectionStatus: 1})

For production environments, consider these additional parameters:

ssh -fN \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=60 \
  -L 9999:localhost:27017 \
  -i ~/.ssh/production_key.pem \
  deploy@production-db.example.com

Create a reusable bash script:

#!/bin/bash
REMOTE_USER="dbadmin"
REMOTE_HOST="db.example.com"
LOCAL_PORT=47017
REMOTE_PORT=27017
KEY_PATH="$HOME/.ssh/mongo_prod_key"

ssh -fN -i $KEY_PATH -L $LOCAL_PORT:localhost:$REMOTE_PORT $REMOTE_USER@$REMOTE_HOST

echo "MongoDB tunnel established on port $LOCAL_PORT"

If connections fail:

1. Check MongoDB's bindIp in /etc/mongod.conf
2. Verify SSH key permissions (chmod 600)
3. Test basic SSH connectivity first
4. Check AWS security groups for port 22 access