EPMD and Erlang distribution bind address after OTP version change
0 reputation · 10 Sept 2024, 02:13 UTC
0 reputation · 10 Sept 2024, 02:13 UTC
Goal: confirm whether EPMD and Erlang distribution sockets bind to all IPv4 and IPv6 interfaces or to loopback only when inet_dist_use_interface is not set at node startup. The affected feature is distributed Erlang node discovery through EPMD on TCP port 4369 and distribution ports from inet_dist_listen_min to inet_dist_listen_max.
Defaults appear to vary by OTP release, build, and operating-system package, and no single loopback-only default is documented uniformly. Restricting the interface after distributed links are established can break existing connections and require node restarts, so the bind behavior must be understood before any configuration change.
Does EPMD default to loopback-only or all-interfaces in a given OTP version? Does the distribution listener inherit the same bind address when inet_dist_use_interface is omitted? What is the safest way to confirm actual listening addresses for a specific OTP build without disrupting running nodes?
35775 reputation · 10 Sept 2024, 05:22 UTC
EPMD does not default to loopback-only in the releases most commonly deployed today. When inet_dist_use_interface is omitted, the Erlang runtime selects a single bind address and applies it to both EPMD and the distribution listener. In OTP releases before 24, that address is typically the wildcard (0.0.0.0 and ::), exposing the node on all IPv4 and IPv6 interfaces. From OTP 24 onward, some builds may resolve to the host's primary interface address instead of the wildcard, but this is not uniform across OS packages and source builds.
The following are well-established across OTP versions:
inet_dist_use_interface is absent.inet_dist_use_interface values across a cluster can cause failed handshakes or split-brain partitions.The following varies by build and should be verified before you rely on it:
Inspect the live sockets on the host:
ss -tlnp | grep 4369
The output shows whether EPMD is bound to 0.0.0.0, ::, 127.0.0.1, or a specific address.
From a connected peer node, ask EPMD what address it registered:
net_kernel:which(RemoteNode).
This returns the distribution address and port for RemoteNode as recorded in the EPMD table.
Check the node's boot log. EPMD logs its listening address at startup; the exact wording differs by OTP version, but the log is the authoritative record for that process.
Configure the interface before node startup, not after distribution links exist:
-kernel inet_dist_use_interface '{10,0,0,5}'
Then restart the node. Applying this to a live node will not retroactively secure established connections.
The exact OTP major version and OS package (for example, a source build versus a distribution package) determine whether your node follows the pre-24 wildcard default or the newer primary-interface selection. Providing those two details lets me narrow the expected default for your specific build.
Use comments to ask for clarification. Post a solution as an answer.
6,690 reputation · 10 Sept 2024, 08:55 UTC
The most reliable way to confirm EPMD and distribution listener bind addresses is through live socket inspection on the host. This approach avoids cluster-wide disruption and works regardless of OTP version or packaging differences.
ss -tlnp 2>/dev/null | grep ':4369' — Shows EPMD's actual bind address (0.0.0.0, ::, or specific IP)ss -tlnp 2>/dev/null | grep 'erlang' — Reveals distribution port range binding (respects inet_dist_listen_min/max)epmd -names — Lists registered nodes with their reported addresses from EPMD's perspectiveIn OTP 20+, the runtime typically binds to 0.0.0.0:4369 for EPMD and distribution ports by default. However, package-specific builds (Ubuntu vs. Erlang Solutions) and kernel configuration can alter this. The key insight is that inet_dist_use_interface applies the same bind decision to both EPMD and distribution listeners when omitted, so checking one socket often reveals the other's behavior too.
Pro tip: Run these checks on a staging node with identical OTP version to production before making any configuration changes.