MongoDB/Network Access
From charlesreid1
Network Access
As mentioned in the Access Control section of the MongoDB page, one of the ways to provide coarse-grained access control to a MongoDB database is to limit network access to the port and server of the MongoDB host machine.
- We start by covering binding to particular network interfaces
- We cover considerations with Docker and the Mongo Docker pod at https://git.charlesreid1.com/pod-mongo
- We move on to network architectures that will place MongoDB in a protected zone:
- Classic firewall
- Access Mongo through SSH tunnel
- Mongo via VPN
- Place Mongo host on a private subnet, accessible via node(s) on a public subnet
Binding to a Network Interface
To set the network interface that MongoDB binds to, set the bind_ip option in the MongoDB config file.
Local requests only:
This address is the special localhost IP address, and tells MongoDB to only listen for local requests:
bindIp: 127.0.0.1
All requests:
This configuration is the opposite and tells MongoDB to listen for requests from any network interface:
bindIp: 0.0.0.0
on a public web server, this will bind to the public-facing interface.
Particular network:
If the MongoDB host is connected to two different networks, NetA and NetB, it will have two different IP addresses.
Suppose the host has the IP 10.0.0.3 on NetA and 192.168.1.6 on NetB.
To tell MongoDB to only listen for requests coming from NetA:
bindIp: 10.0.0.3
To tell MongoDB to only listen for requests coming from NetB:
bindIp: 192.168.1.6
To tell MongoDB to listen for requests from either network:
bindIp: [10.0.0.3,192.168.1.6]
or,
bindIp: 0.0.0.0
Network Access with Docker
If you're using the mongo pod at https://git.charlesreid1.com/docker/pod-mongo you have slightly different considerations for the network, but the same basic idea applies.
The docker pod controls what network ports and addresses Mongo binds to in the docker-compose.yml file. More precisely, at this line of the docker compose file: https://git.charlesreid1.com/docker/pod-mongo/src/branch/master/docker-compose.fixme.yml#L12
The ports directive of the MongoDB container in the docker compose file dictates the bind address and port schema. For example, A.B.C.D:XXXX:YYYY would indicate:
- Bind to the host network interface that has the IP address A.B.C.D and listen on it for incoming requests
- The host should have port XXXX open.
- Any incoming traffic to port XXXX is remapped to the MongoDB container to port YYYY
So the actual port configuration, shown below, would correspond to:
- Binding to the local interface (local requests only)
- Host port 27017 is open to requests, and forwards those requests to port 27017 in the container
A selection from the docker compose file: https://git.charlesreid1.com/docker/pod-mongo/src/branch/master/docker-compose.fixme.yml#L12
version: "3.1"
services:
stormy_mongodb:
build: d-mongodb
restart: always
ports:
- "127.0.0.1:27017:27017"
volumes:
- "mongo-data:/data"
....
To have MongoDB bind to a different address, like 10.0.0.3, change the line to:
ports:
- "10.0.0.3:27017:27017"
Network Architectures to Protect Mongo
Classic Firewall
TODO
Basic example is the AWS EC2 security model: by default, all ports are blocked by the firewall except for the port you want
You also specify the CIDR block from which you will accept traffic (i.e., from a narrow range, for something like SSH, or from anyone, if a public web server).
This is a classic method for protecting the MongoDB port for a public-facing server, or for making the MongoDB service only available to a select set of clients based on their IPs.
SSH Tunnel
TODO
If you have SSH access to both the client and the server, it is possible to set up an SSH tunnel between the client and the server and forward traffic to a local port, so that the MongoDB client can communicate with the server as though it were present on localhost (and the traffic is transparently forwarded by the SSH tunnel).
To do this, you set up an SSH connection from the client to the server, and use the -L flag to tell it to tunnel traffic through a local port. Use the syntax XXXX:localhost:YYYY, where XXXX is the local (MongoDB client) port and YYYY is the remote (MongoDB server) port.
For example, if you want traffic on localhost of the client, occurring on port XXXX, to be forwarded to the remote MongoDB server, and appear on port YYYY on the remote server, you can run this from the MongoDB client node:
(to start the tunnel in the background, you can add the -d flag)
$ ssh -d -L XXXX:localhost:YYYY user@ip-of-client
Typically for MongoDB both will be 27017:
$ ssh -d -L 27017:localhost:27017 user@ip-of-client