Make the network an authorization boundary of its own: trusted interfaces, private paths, no public database port, and separate application/admin planes.
Network Exposure, Firewalls/Private Networking, Bind Settings, and Administrative Separation
Authentication cannot compensate for a database port reachable from places that never need it. AtlasMart separates the application path, administrative path, and untrusted networks before adding more users or features.
Learning objectives
Explain why bind settings, host-port publication, routing, firewall/security-group policy, and private networking are separate controls.
Build an isolated Docker network where the database is reachable by the application path but has no public host port.
Separate an application service account from an administrative identity and network path.
Prove an unconnected container cannot reach the database while an attached application container can.
Diagnose the dangerous combination of broad binding, public port publication, and weak/no authentication without changing the host firewall.
This lesson pins
MongoDB Community Server 8.3.8 with
mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim, mongosh 2.10.0, and
PyMongo 4.17.0 where driver behavior is useful. The
mandatory path is free/local and disposable. Topology: one
auth-enabled standalone attached to two isolated Docker
networks: atlasmart-ch22-app-net and
atlasmart-ch22-admin-net. The database has no host
port publication at all; application and administrative clients
enter through separate container networks. The database is never
published on an untrusted interface; any host mapping is
loopback-only on port 27179. Authentication/TLS
state is stated next to each experiment rather than assumed.
Default read/write concern and primary read preference are used
unless an example says otherwise.
FCV is observed and never changed. Atlas,
Enterprise Advanced, KMS, LDAP, Kerberos, OIDC, and commercial
SIEM products are optional discussion paths, not mandatory lab
dependencies. Secrets shown are synthetic local-only example
secrets or generated ephemeral material and must not be reused.
Product runtime labs were not executed in the generation
environment, so authentication outcomes, certificate
fingerprints, rotation timing, network observations, and
audit/log records must be measured locally rather than copied as
invented output.
1. A MongoDB listener is only one layer of network exposure
net.bindIp/--bind_ip controls which
interfaces mongod listens on. Docker
-p, cloud security groups, host firewalls,
Kubernetes Services, load balancers, VPNs, and routing decide
which sources can reach those interfaces. Treating
bind_ip_all as synonymous with "public" is
incomplete; treating a private bind as sufficient even when
another proxy forwards the port is equally incomplete. The
production question is end-to-end reachability from each source
class.
| Control | What it decides | AtlasMart test |
|---|---|---|
| mongod bind | which local/container interfaces accept connections | inspect command/config and listening socket |
| Docker/network routing | which containers share a private path | docker network inspect membership |
| host port publication | whether host/LAN can route into container port | docker inspect shows no PortBindings |
| MongoDB authorization | what an authenticated identity may do after reaching server | positive/negative role tests |
| TLS | whether transport is encrypted and endpoint identity validated | certificate/hostname evidence from Lesson 3 |
2. Build separate application and administration network planes
This lab intentionally uses --bind_ip_all inside
the container because the server must accept traffic from two
private Docker networks. Safety comes from not publishing port
27017 to the host and from attaching only intended clients. In
production, bind to trusted private interfaces where possible
and reinforce that with network policy/firewalls; never depend
on one layer alone.
docker network rm atlasmart-ch22-app-net atlasmart-ch22-admin-net 2>/dev/null || truedocker network create atlasmart-ch22-app-netdocker network create atlasmart-ch22-admin-netdocker rm -f atlasmart-ch22-l4 2>/dev/null || truedocker run -d --name atlasmart-ch22-l4 \ --network atlasmart-ch22-admin-net \ mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --auth --bind_ip_all# Attach the same DB to the application network under a stable private alias.docker network connect --alias atlasmart-db atlasmart-ch22-app-net atlasmart-ch22-l4# Bootstrap the admin locally inside the container.docker exec atlasmart-ch22-l4 mongosh --quiet --host 127.0.0.1 --eval ' const a=db.getSiblingDB("admin"); a.createUser({user:"atlasAdmin",pwd:"local-only-change-me",roles:[{role:"root",db:"admin"}],mechanisms:["SCRAM-SHA-256"]}); const app=db.getSiblingDB("atlasmart"); app.createUser({user:"catalog-api",pwd:"catalog-local-only",roles:[{role:"read",db:"atlasmart"}],mechanisms:["SCRAM-SHA-256"]}); app.products.insertOne({sku:"NET-22",tenantId:"tenant-a",name:"Private-network product"});'# Verify there is NO host port publication.docker inspect atlasmart-ch22-l4 --format '{{json .HostConfig.PortBindings}}'docker network inspect atlasmart-ch22-app-net --format '{{json .Containers}}'docker network inspect atlasmart-ch22-admin-net --format '{{json .Containers}}'
3. Prove reachability from the application plane and non-reachability from an unrelated network
A container attached to atlasmart-ch22-app-net can
resolve the private alias and authenticate as the read-only
service. A default-network container is not attached and should
not resolve/reach that alias. These are network tests; they do
not replace authorization tests. The application account is also
prevented from administrative operations even after it reaches
the server.
# Expected: private application client can reach DB and read.docker run --rm --network atlasmart-ch22-app-net mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim \ mongosh "mongodb://catalog-api:catalog-local-only@atlasmart-db:27017/atlasmart?authSource=atlasmart" \ --quiet --eval 'printjson(db.products.findOne({sku:"NET-22"}))'# Expected: same identity reaches DB but cannot administer users.docker run --rm --network atlasmart-ch22-app-net mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim \ mongosh "mongodb://catalog-api:catalog-local-only@atlasmart-db:27017/atlasmart?authSource=atlasmart" \ --quiet --eval 'db.getSiblingDB("admin").createUser({user:"nope",pwd:"x",roles:[]})' || true# Expected: container on the default network cannot resolve/reach atlasmart-db.docker run --rm mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim \ mongosh "mongodb://atlasmart-db:27017/" --serverSelectionTimeoutMS 2000 \ --quiet --eval 'db.runCommand({ping:1})' || true
4. Administrative separation is both identity and path
An administrator needs broader privileges, but that does not
mean those credentials should be usable from every application
host. The admin network exists only for the administrative
client. In larger environments, equivalent controls include
management subnets, private endpoints, VPN/bastion workflows,
mTLS, just-in-time credentials, and source restrictions. MongoDB
user/role authenticationRestrictions can
additionally constrain client/server address ranges, but it
should supplement—not replace—network segmentation.
docker run --rm --network atlasmart-ch22-admin-net mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim \ mongosh "mongodb://atlasAdmin:local-only-change-me@atlasmart-ch22-l4:27017/admin?authSource=admin" \ --quiet --eval 'printjson(db.runCommand({connectionStatus:1,showPrivileges:true}))'
5. Deliberately wrong architecture: broad bind + public mapping + no auth
The dangerous pattern is not a single setting but a conjunction:
--bind_ip_all, host publication such as
-p 0.0.0.0:27017:27017, and missing/weak access
control. The lab does not execute that
configuration. Instead, treat it as a review rule: if a proposed
deployment contains a wildcard/public port, the change fails
security review until authentication, TLS, private-network
policy, source restrictions, and an explicit business need are
documented. Do not manipulate the learner's real host firewall
to simulate safety.
Network policy must exist before exposure, not as a follow-up task. Configuration drift, a temporary security-group rule, a Docker publish flag, or an alternate interface can bypass assumptions. Verify effective reachability continuously and test from both allowed and denied source networks.
6. Verification, cleanup, and production judgment
-
docker inspectreports no host port binding for the database. -
The application-network client reaches
atlasmart-dband authenticates. - The default-network client cannot resolve/reach the private database alias.
- The application identity cannot create users even when network reachability exists.
- The admin identity is exercised from a separate admin network.
Production network design should minimize exposed interfaces, use private routing, enforce source policy at multiple layers, require TLS, and separate administrative identities and paths from application traffic. Monitor unexpected source addresses, repeated authentication failures, connection spikes, and configuration changes. A firewall rule is not a substitute for MongoDB authorization, and MongoDB authorization is not a substitute for private networking. Lesson 5 completes the security loop by designing evidence that these controls were actually exercised and reviewed.
docker rm -f atlasmart-ch22-l4 2>/dev/null || truedocker network rm atlasmart-ch22-app-net atlasmart-ch22-admin-net 2>/dev/null || true
Check your understanding
- Does --bind_ip_all necessarily mean the database is public?
- Why use both network segmentation and MongoDB authorization?
- Why is an admin network useful if admin credentials are strong?
- Should the lab open the real host firewall to demonstrate a bad rule?
- What is the required evidence that the DB has no host exposure in this lab?
Review the answers
1. No. It controls server-side listening interfaces; actual reachability also depends on routing, port publication, firewall/security-group policy, and proxies. It is still a setting that requires careful network controls.
2. They defend different boundaries: the network limits who can reach the service; authorization limits what an authenticated identity can do after reaching it.
3. It reduces the set of sources from which those high-impact credentials can even be presented, lowering exposure and making access more observable.
4. No. The course contract prefers isolated Docker networks and static/configuration evidence rather than risky host firewall changes.
5. Docker port-binding inspection plus a failed reachability test from a container outside the private networks.
Authoritative references
Version-sensitive behavior in this lesson was checked against current MongoDB documentation at generation time. Re-check these sources before applying the procedures to a later server or managed-service release.
- MongoDB Security
- Security Checklist for Self-Managed Deployments
- Localhost Exception in Self-Managed Deployments
- Role-Based Access Control in Self-Managed Deployments
- SCRAM Authentication
- createUser Command
- Built-In Roles
- Privilege Actions
- User-Defined Roles
- Configure MongoDB Instances for TLS
- Connection String TLS Options
- Self-Managed Internal/Membership Authentication
- Rotate Keys for Self-Managed Replica Sets
- rotateCertificates Command
- IP Binding in Self-Managed Deployments
- Auditing
- Configure Audit Filters
- System Event Audit Messages
- Atlas Database Auditing
- MongoDB 8.3 Release Notes
- mongosh Release Notes
- PyMongo Release Notes