Cannot bind Mongodb to VM's public ip

Environment: Google Cloud Platform’s virtual machine, CentOS 8, MongoDB 4.2

The default instance works (bound to 127.0.0.1), Wanted to make the database available on public ip. When updating mongod.conf file to also include public ip, mongod service won’t start.

With the default setting, mongodb starts.

sudo vi /etc/mongod.conf

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

But when following this https://docs.mongodb.com/manual/core/security-mongodb-configuration/ to add the public ip (e: 1.2.3.4) as:

bindIp: 127.0.0.1,1.2.3.4 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

and done these:

1. Deleted sudo rm -rf /tmp/mongodb-27017.sock
2. sudo systemctl restart mongod 

Shows the below error:

Tried all combinations… none of these worked:

bindIp: 127.0.0.1,1.2.3.4
bindIp: 127.0.0.1, 1.2.3.4
bindIp: [127.0.0.1,1.2.3.4]
bindIp: "127.0.0.1,1.2.3.4"

Hi @Suren_Konathala,

Can you check the MongoDB server logs for more details on why the service isn’t starting? The default location on CentOS should be /var/log/mongodb.

You can include multiple bind IP addresses in a comma-delimited list or alternatively use net.bindIpAll to bind to all network interfaces on this instance. A cloud instance typically will not have a public IP until you explicitly add one, and you would want a static IP (see: Google Cloud: Reserving a static external IP address) if you are using that to connect to your MongoDB deployment.

Before binding to a public IP, I strongly recommend reviewing the MongoDB Security Checklist and ensuring you have enabled authentication, configured role-based access control, and set up TLS/SSL.

If a bindIp directive isn’t working (and this is the only value you’ve changed for a previously working configuration), some common reasons are:

  • You are trying to bind to an IP that isn’t associated with a local network interface on this instance (the IP address should appear in the output of ifconfig -a | grep "inet").

  • There is a running process already bound to the requested IP and port number.

  • You have a syntax error in your MongoDB config file.

  • You aren’t editing the correct config file (which doesn’t appear to be the case here). /etc/mongod.conf is the default on CentOS if you installed the official MongoDB packages and are starting as a service).

If you are still having issues, please share the relevant lines from the MongoDB log which should include the reason for the mongod process shutting down. It is also easier to review if you can share log lines and similar information as text rather than images.

Regards,
Stennie

Thanks for the detailed explanation @Stennie

  1. the VM has a reserved static IP (attached) … but when i run ifconfig -a | grep "inet" it does not show up.

  2. Logs show as

2020-07-10T00:00:07.406+0000 I  CONTROL  [main] ***** SERVER RESTARTED *****
2020-07-10T00:00:07.414+0000 I  CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none
'
2020-07-10T00:00:07.645+0000 W  ASIO     [main] No TransportLayer configured during NetworkInterface startup
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] MongoDB starting : pid=10069 port=27017 dbpath=/var/lib/mongo 64-bit host=cordboard-
prod1
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] db version v4.2.8
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] git version: 43d25964249164d76d5e04dd6cf38f6111e21f5f
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.1.1c FIPS  28 May 2019
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] allocator: tcmalloc
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] modules: none
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] build environment:
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten]     distmod: rhel80
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten]     distarch: x86_64
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten]     target_arch: x86_64
2020-07-10T00:00:07.646+0000 I  CONTROL  [initandlisten] options: { config: "/etc/mongod.conf", net: { bindIp: "127.0.0.1,35.232.21.94", port
: 27017 }, processManagement: { fork: true, pidFilePath: "/var/run/mongodb/mongod.pid", timeZoneInfo: "/usr/share/zoneinfo" }, storage: { dbP
ath: "/var/lib/mongo", journal: { enabled: true } }, systemLog: { destination: "file", logAppend: true, path: "/var/log/mongodb/mongod.log" }
}
2020-07-10T00:00:07.647+0000 E  STORAGE  [initandlisten] Failed to set up listener: SocketException: Cannot assign requested address
2020-07-10T00:00:07.648+0000 I  CONTROL  [initandlisten] now exiting
2020-07-10T00:00:07.648+0000 I  CONTROL  [initandlisten] shutting down with code:48
  1. I have this IP configured to a domain that is working (using an A record -> pointing to this static IP)

Maybe something to do with the IP address on the VM?

Hi @Suren_Konathala,

Yes, this is definitely a problem with network configuration for the VM.

The MongoDB startup exception indicates that the requested IP address is not a local network IP that can be assigned by the bindIp directive:

Failed to set up listener: SocketException: Cannot assign requested address

From your screenshot, it looks like you may have set up SSH port forwarding from an external IP address to the internal IP address. If so, your VM would not have a local network interface associated with the external IP: all requests will be forwarded via SSH and (from mongod's point of view) appear to be coming from localhost or the private IP.

If your intent was to add a public external IP that allows direct connection to your deployment, the Google Cloud docs I suggested earlier should be helpful. You may want to contact Google Cloud support for further guidance on creating your desired network configuration.

Regards,
Stennie

One solution i found to be working… (this is not secure though)

  1. Remove mongodb installation
  2. Reinstall… but don’t start the service yet
  3. Edit vi /etc/mongod.conf as
     ...
    # network interfaces. 
    net:
      port: 27017
      bindIp: 0.0.0.0
    ...
    
  4. Enable, start service
    sudo systemctl enable mongod
    sudo systemctl start mongod
    sudo systemctl status mongod
    
  5. Add Firewall rule to allow 27017 (ingress, allow 27017)

Was able to connect to this mongodb using VM’s static IP on MongoDB Compass

mongodb://user:password@1.2.3.4:27017/?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false

Hi,

I know this is a few days old and you already found a solution, but I noticed from the screenshot that you’re on a GCP VM with an internal and an external IP address. From your MongoDB log it seems that you tried to have MongoDB bind to the reserved external IP address 35.232.21.94. But as you also mentioned, you can’t see this IP address on the VM itself. Instead, I think you should be able to see the internal IP address 10.128.0.6 in the VM (e.g. ifconfig/ip addr). So the VM only knows its internal IP address but it has no knowledge of the external address. In fact, the external address can be changed at any time and the VM wouldn’t notice - the internal IP address would stay the same. You should be able to have MongoDB bind to the internal IP address 10.128.0.6. For connections coming from externally, i.e. from outside of your GCP network, GCP will route/NAT from the external IP address to the internal address of your VM.

I hope I understood the context correctly and that this makes some sense.

That’s a great observation… thanks much @frankshimizu
We were concerned about the security using 0.0.0.0 to bind. Will try the internal IP.

Hi @Suren_Konathala,

If you are forwarding an external IP to an internal IP (i.e. the external IP is not a local network interface), you still need to have appropriate firewall restrictions for the external IP.

From the mongod 's point of view, any forwarded requests will appear to be via the internal IP. The bindIp configuration only specifies the local IP addresses the process is listening to; it is not a firewall.

Binding to 0.0.0.0 (aka bindIpAll) configures your process to listen to all local network interfaces, which would be equivalent to binding to localhost and the private IP (if the external IP is not a local interface). Binding to specific network interfaces (rather than all) is a better approach to avoid accidentally having an instance listening to a public network interface added after initial configuration

The ingress configuration on your firewall can be used to limit remote connections to trusted network ranges. You should also enable TLS/SSL (and other measures in the Security Checklist) to secure your deployment.

Regards,
Stennie