Skip to content

Commit b045b2c

Browse files
committed
Add EPMD Exposure Blog
1 parent bb55131 commit b045b2c

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

assets/css/blogs.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ div.blog-post > table {
2424
border-collapse: collapse;
2525
}
2626

27+
div.blog-post .responsive-image {
28+
width: 100%;
29+
}
30+
2731
div.blog-post > td, th {
2832
border: 0.0625rem solid #ddd;
2933
padding: 0.5rem;
513 KB
Loading
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
{
2+
"title": "Exposed EPMD: A Hidden Security Risk for RabbitMQ and the BEAM Ecosystem",
3+
"authors": ["The Security Working Group"],
4+
"slug": "epmd-public-exposure",
5+
"category": "security",
6+
"tags": ["security", "epmd", "cybersecurity", "rabbitmq"],
7+
"datetime": "2024-12-12T21:01:48.619713Z"
8+
}
9+
---
10+
EPMD, essential for Erlang and RabbitMQ clustering, is often exposed online—posing hidden security risks and requiring quick mitigation steps.
11+
---
12+
13+
The Erlang Port Mapper Daemon (EPMD) is a built-in component that facilitates clustering across Erlang-based applications (including RabbitMQ). While EPMD is essential in trusted network environments, it was never intended for exposure on the public internet. Recent scans have revealed over 85,000 instances of publicly exposed EPMD, with roughly half associated with RabbitMQ servers.
14+
15+
If left unsecured, an exposed EPMD endpoint can potentially grant attackers a foothold, enabling them to join your cluster, run arbitrary code, and compromise your systems. Fortunately, mitigation steps are straightforward: disable EPMD if you’re not clustering, or restrict it behind a firewall and proper network configuration.
16+
17+
## TL;DR
18+
19+
**Check if you’re exposed:**
20+
- Run a port scan:
21+
```bash
22+
nmap -p 4369 -sV [Your Public IP]
23+
```
24+
If the output shows:
25+
```
26+
PORT STATE SERVICE
27+
4369/tcp open epmd
28+
```
29+
Your EPMD port is exposed.
30+
31+
**For Erlang/Elixir users:**
32+
- Remove or avoid using `-name` or `-sname` if you don’t need clustering.
33+
- Bind distribution to a non-public interface with `vm.args`:
34+
```bash
35+
-kernel inet_dist_use_interface '{127, 0, 0, 1}'
36+
```
37+
- Use a firewall or security group rules to restrict external access.
38+
39+
**For RabbitMQ users:**
40+
- RabbitMQ runs on Erlang and uses EPMD behind the scenes. Even if you never interact directly with Erlang, you may still be affected.
41+
- Check the RabbitMQ networking documentation to learn how to identify exposed ports and close them:
42+
[https://www.rabbitmq.com/docs/networking#epmd](https://www.rabbitmq.com/docs/networking#epmd)
43+
- The Erlang Ecosystem Foundation’s security hardening guide explains what EPMD is, which ports it uses, and how to close them down:
44+
[https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/distribution](https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/distribution)
45+
46+
## What is EPMD and How Does it Work?
47+
48+
Erlang was designed from the ground up for concurrency, distribution, and fault tolerance. To support clustering (distributed Erlang nodes connecting and communicating seamlessly), Erlang relies on EPMD. EPMD runs as a small daemon that keeps track of Erlang nodes and their associated ports. When a node starts with `-name` or `-sname`, it registers with EPMD on the host machine’s port 4369.
49+
50+
In a controlled environment—such as an internal network—this works well. EPMD makes it easy for nodes to discover each other, connect, and form distributed clusters.
51+
52+
**Key points:**
53+
- EPMD listens on port 4369 by default.
54+
- It’s assumed that EPMD is only reachable from within a trusted network.
55+
- Many Erlang/Elixir build tools and release pipelines (like Rebar3, Mix, and Distillery releases) enable EPMD by default.
56+
57+
## Why is Exposing EPMD a Bad Idea?
58+
59+
### Risk of Unauthorized Cluster Access
60+
61+
EPMD itself does not enforce strong authentication. Erlang clustering uses a “cookie” as a shared secret, but this cookie is not intended as a robust security mechanism—it’s more of a sanity check to prevent accidental cross-node connections. If an attacker can guess or brute-force the cookie, they could join your cluster.
62+
63+
Once inside the cluster, the attacker could potentially run arbitrary Erlang Remote Procedure Calls (RPCs), giving them full control of the application and underlying system. While no widespread internet-based attacks on EPMD have been documented publicly, the theoretical risk is real. A known timing-based brute-force approach is described here:
64+
[https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/](https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/)
65+
66+
### Scope of the Problem
67+
68+
Shodan (a search engine for internet-connected devices) reveals over 85,000 publicly accessible EPMD instances. Among them, around 40,000 are associated with RabbitMQ.
69+
Top countries hosting exposed EPMD endpoints include China (18,444), the United States (15,771), and Germany (10,263). Major cloud hosting platforms (DigitalOcean, Hetzner, Aliyun, Tencent, OVH, Amazon, and others) also host significant numbers of exposed instances, typically due to default configurations and lack of firewall restrictions.
70+
71+
[![World Map showing number of exposed EPMD instances](/images/posts/epmd-public-exposure/world-map.png) {: .responsive-image}](https://www.shodan.io/search/report?query=product%3A%22Erlang+Port+Mapper+Daemon%22)
72+
73+
### Not Just Erlang Developers at Risk
74+
75+
RabbitMQ, a popular message broker built on Erlang, runs EPMD under the hood. Many RabbitMQ users may not be aware that EPMD exists or that it’s exposed. This lack of awareness can lead to overlooked vulnerabilities, as users trust defaults without applying basic network hygiene.
76+
77+
## How to Secure Your EPMD
78+
79+
**1. Use a Firewall or Restricted Network Interfaces**
80+
81+
If you don’t need external clustering, ensure EPMD isn’t exposed:
82+
83+
- Bind EPMD to localhost or a private network interface. In `vm.args`, specify:
84+
```bash
85+
-kernel inet_dist_use_interface '{127, 0, 0, 1}'
86+
```
87+
- Deploy firewalls, security groups, or network access control lists (ACLs) to ensure port 4369 is not reachable from untrusted networks.
88+
89+
**2. Remove Clustering Options if Not Needed**
90+
91+
If you’re not clustering multiple Erlang/RabbitMQ nodes, don’t start the node with `-name` or `-sname`. Without these options, your application won’t register with EPMD at all. If you only run a single RabbitMQ node and do not need distribution, consider disabling or limiting it according to the official networking and clustering documentation.
92+
93+
**3. Mitigation is Simple**
94+
95+
A small configuration change or a single firewall rule can often resolve the issue. Once you’ve made changes to close or secure EPMD, scan again to confirm:
96+
97+
```bash
98+
nmap -p 4369 -sV [Public IP]
99+
```
100+
101+
If you’ve successfully closed the port, the output should look like this:
102+
```
103+
PORT STATE SERVICE
104+
4369/tcp closed epmd
105+
```
106+
107+
**4. Follow Best Practices from the Community**
108+
109+
- **RabbitMQ**: The official networking guide shows how to identify EPMD ports and close them down.
110+
- **Erlang Ecosystem Foundation**: The security hardening guide explains what EPMD is, which ports are used, and how to secure them.
111+
112+
## Conclusion
113+
114+
EPMD is a powerful mechanism for distributed Erlang applications and RabbitMQ clusters, but it was never meant to be exposed to the internet. Fortunately, securing EPMD is straightforward, often just a matter of adding a firewall rule, adjusting a configuration setting, or using loopback interfaces. By taking these simple steps, you prevent unauthorized access, reduce risk, and keep your applications safe.

0 commit comments

Comments
 (0)