When working with MongoDB replica sets behind proxy servers, a common pain point emerges: while standalone connections work fine, replica set mode fails because the driver receives internal addresses from the isMaster response. Here's why this happens:
// What the driver sees from isMaster response:
{
"hosts": [
"member1-private-ip:27017",
"member2-private-ip:27017",
"member3-private-ip:27017"
],
"setName": "replcaSetName",
"ismaster": false,
"secondary": true
}
The most reliable approach is to configure DNS records that map to your proxy servers:
- Create DNS entries for each member (member1.yourdomain.com → proxy-public-ip:27017)
- Configure MongoDB to use these DNS names in replica set configuration
// Replica set configuration example:
rs.initiate({
_id: "replcaSetName",
members: [
{ _id: 0, host: "member1.yourdomain.com:27017" },
{ _id: 1, host: "member2.yourdomain.com:27018" },
{ _id: 2, host: "member3.yourdomain.com:27019" }
]
})
For quick testing or temporary solutions, you can use these MongoDB URI options:
mongodb://usr:pwd@proxy-server-public-ip:27017,proxy-server-public-ip:27018,proxy-server-public-ip:27019/db?
replicaSet=replcaSetName&
connectTimeoutMS=30000&
socketTimeoutMS=30000&
serverSelectionTimeoutMS=50000&
retryWrites=true&
readPreference=secondaryPreferred
For enhanced security, consider creating SSH tunnels instead of direct proxy:
# Create multiple SSH tunnels
ssh -N -L 27017:member1-private-ip:27017 user@proxy-server-public-ip
ssh -N -L 27018:member2-private-ip:27017 user@proxy-server-public-ip
ssh -N -L 27019:member3-private-ip:27017 user@proxy-server-public-ip
Then connect using localhost:
mongodb://usr:pwd@localhost:27017,localhost:27018,localhost:27019/db?replicaSet=replcaSetName
- Monitor proxy connection limits (MongoDB drivers maintain multiple connections)
- Implement connection pooling properly
- Set appropriate timeouts based on your network latency
- Consider using a dedicated proxy like HAProxy with MongoDB-specific configuration
# Example HAProxy configuration
frontend mongodb_front
bind *:27017
mode tcp
timeout client 3600s
default_backend mongodb_back
backend mongodb_back
mode tcp
balance leastconn
timeout server 3600s
timeout connect 10s
server mongo1 member1-private-ip:27017 check
server mongo2 member2-private-ip:27017 check
server mongo3 member3-private-ip:27017 check
When working with MongoDB replica sets behind a proxy, you'll encounter a fundamental problem: the replica set members communicate their internal network addresses to clients through the isMaster response. Here's what happens:
// What the client receives when connecting
{
"hosts": [
"member1-private-ip:27017",
"member2-private-ip:27017",
"member3-private-ip:27017"
],
"setName": "replcaSetName",
"ismaster": true
}
The MongoDB driver follows these steps when connecting:
1. Contacts the initial seed list (your proxy addresses)
2. Receives the replica set configuration with internal IPs
3. Attempts to connect directly to those internal IPs (which fails)
Solution 1: DNS Rewriting
Create DNS entries that map the internal hostnames to your proxy public IPs:
member1.yourdomain.com -> proxy-public-ip
member2.yourdomain.com -> proxy-public-ip
member3.yourdomain.com -> proxy-public-ip
Then connect using:
mongoUri = new MongoClientURI(
"mongodb://usr:pwd@member1.yourdomain.com:27017," +
"member2.yourdomain.com:27018," +
"member3.yourdomain.com:27019/db?replicaSet=replcaSetName"
);
Solution 2: Connection String Modifications
Use the directConnection option in modern drivers (4.0+):
mongoUri = new MongoClientURI(
"mongodb://usr:pwd@proxy-public-ip:27017," +
"proxy-public-ip:27018," +
"proxy-public-ip:27019/db?" +
"replicaSet=replcaSetName&directConnection=false"
);
For HAProxy users:
frontend mongodb_front
bind *:27017
mode tcp
option tcplog
default_backend mongodb_back
backend mongodb_back
mode tcp
option tcp-check
server mongo1 member1-private-ip:27017 check
server mongo2 member2-private-ip:27017 check
server mongo3 member3-private-ip:27017 check
For Node.js MongoDB driver:
const { MongoClient } = require('mongodb');
const client = new MongoClient(
'mongodb://proxy-public-ip:27017,proxy-public-ip:27018/db?replicaSet=replcaSetName',
{
directConnection: false,
retryWrites: true,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 20000
}
);
Always ensure:
- Proxy connections use TLS/SSL
- Implement IP whitelisting on the proxy
- Use MongoDB SCRAM authentication
- Rotate credentials regularly