|
| 1 | +# Erlang Distribution |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +ejabberd uses the |
| 6 | +[Distributed Erlang](https://www.erlang.org/doc/system/distributed.html) |
| 7 | +feature for two purposes: |
| 8 | + |
| 9 | +- [`ejabberdctl`](managing.md#ejabberdctl) shell script |
| 10 | + that connects to your running ejabberd node to allow you executing |
| 11 | + [API](../../developer/ejabberd-api/index.md) commands in it, |
| 12 | + opening an interactive erlang shell, ... |
| 13 | + |
| 14 | +- [clustering](clustering.md) several ejabberd nodes that |
| 15 | + you deploy in separate machines to serve a large XMPP domain |
| 16 | + with fault-tolerance and scalability. |
| 17 | + |
| 18 | +There are three topics involved in erlang distribution: |
| 19 | + |
| 20 | +- [Cookie](#cookie), automatically generated, shared by your ejabberd nodes, and secret to the world |
| 21 | +- [Node Name](#node-name) that you pick for each ejabberd node to identify them in a cluster |
| 22 | +- **Port** number to use, determined using either: |
| 23 | + - [ERL_DIST_PORT](#erl_dist_port) environment variable that lets you assign your desired port number |
| 24 | + - [epmd](#epmd) program that assigns a random port number and maps names with ports |
| 25 | + |
| 26 | +## Cookie |
| 27 | + |
| 28 | +def:cookie |
| 29 | +: Random alphanumeric string assigned to each erlang [](def:node) used to secure connections between erlang nodes. |
| 30 | + See [Security in distributed erlang](https://www.erlang.org/doc/system/distributed#security). |
| 31 | + |
| 32 | +An Erlang node |
| 33 | +reads the cookie at startup from the command-line parameter |
| 34 | +`-setcookie`. If not indicated, the cookie is read from the file |
| 35 | +`$HOME/.erlang.cookie`. |
| 36 | + |
| 37 | +If this file does not exist, it is created |
| 38 | +immediately with a random cookie in the user `$HOME` path. |
| 39 | +This means the user running ejabberd must have a `$HOME`, |
| 40 | +and have write access to that path. |
| 41 | +So, when you create a new account in your system for running ejabberd, |
| 42 | +either allow it to have a `$HOME`, |
| 43 | +or set as `$HOME` a path where ejabberd will have write access. |
| 44 | +Depending on your setup, examples could be: |
| 45 | + |
| 46 | +``` sh |
| 47 | +adduser --home /usr/local/var/lib/ejabberd ejabberd |
| 48 | +``` |
| 49 | + |
| 50 | +or |
| 51 | + |
| 52 | +``` sh |
| 53 | +adduser --home /var/lib/ejabberd ejabberd |
| 54 | +``` |
| 55 | + |
| 56 | +Two Erlang nodes communicate only if |
| 57 | +they have the same cookie. Setting a cookie on the Erlang node allows |
| 58 | +you to structure your Erlang network and define which nodes are allowed |
| 59 | +to connect to which. |
| 60 | + |
| 61 | +Thanks to Erlang cookies, you can prevent access to the Erlang node by |
| 62 | +mistake, for example when there are several Erlang nodes running |
| 63 | +different programs in the same machine. |
| 64 | + |
| 65 | +Setting a secret cookie is a simple method to difficult unauthorized |
| 66 | +access to your Erlang node. However, the cookie system is not ultimately |
| 67 | +effective to prevent unauthorized access or intrusion to an Erlang node. |
| 68 | +The communication between Erlang nodes are not encrypted, so the [](def:cookie) |
| 69 | +could be read sniffing the traffic on the network. The recommended way |
| 70 | +to secure the Erlang node is to block the port 4369. |
| 71 | + |
| 72 | +## Node Name |
| 73 | + |
| 74 | +def:erlang node |
| 75 | +: A node in erlang connected to a cluster. |
| 76 | + See [Erlang node name](distribution.md#node-name) |
| 77 | + |
| 78 | +| Variable in ejabberdctl.cfg | Corresponding argument in Erlang/OTP | |
| 79 | +|---------------------------|--------------------------------------| |
| 80 | +| `ERLANG_NODE=ejabberd@localhost` | -[name](https://www.erlang.org/doc/apps/erts/erl_cmd#name) `ejabberd@localhost` <br>-[sname](https://www.erlang.org/doc/apps/erts/erl_cmd#sname) `ejabberd` | |
| 81 | + |
| 82 | +An Erlang node may have a node name. The name can be short (if indicated |
| 83 | +with the command-line parameter `-sname`) or long (if indicated with the |
| 84 | +parameter `-name`). Starting an Erlang node with `-sname` limits the |
| 85 | +communication between Erlang nodes to the LAN. |
| 86 | + |
| 87 | +Using the argument `-sname` instead of `-name` is a simple method to |
| 88 | +difficult unauthorized access to your Erlang node. However, it is not |
| 89 | +ultimately effective to prevent access to the Erlang node, because it |
| 90 | +may be possible to fake the fact that you are on another network using a |
| 91 | +modified version of Erlang [](def:epmd). The recommended way to secure the |
| 92 | +Erlang node is to block the port 4369. |
| 93 | + |
| 94 | +## `ERL_DIST_PORT` |
| 95 | + |
| 96 | +| Variable in ejabberdctl.cfg | Corresponding argument in Erlang/OTP | |
| 97 | +|---------------------------|--------------------------------------| |
| 98 | +| `INET_DIST_INTERFACE` | -kernel [inet_dist_use_interface](https://www.erlang.org/doc/apps/kernel/kernel_app.html#inet_dist_use_interface) | |
| 99 | +| `ERL_DIST_PORT=5210` | -[erl_epmd_port](https://www.erlang.org/docs/28/apps/erts/erl_cmd#erl_epmd_port) `5210` -[start_epmd](https://www.erlang.org/docs/28/apps/erts/erl_cmd.html#start_epmd) `false` | |
| 100 | + |
| 101 | +The TCP port where your Erlang node listens for Erlang distribution connections |
| 102 | +can be set with the environment variable `ERL_DIST_PORT` in the file `ejabberdctl.cfg`. |
| 103 | +When attempting to connect to other remote nodes, |
| 104 | +it will also try to connect to that port number. |
| 105 | + |
| 106 | +By default this variable is set to `5210`, |
| 107 | +but you can set any number you prefer as long as it isn't used in the machine, |
| 108 | +and it is the same for all the other ejabberd nodes that will build the cluster. |
| 109 | + |
| 110 | +When building a cluster of several Erlang nodes, |
| 111 | +all of them must have the same `ERL_DIST_PORT`, |
| 112 | +because this is used for listening and also for connecting. |
| 113 | +Consequently, if you want to build a cluster of several nodes in the same machine, |
| 114 | +each node must have a different IP address in `INET_DIST_INTERFACE`. |
| 115 | + |
| 116 | +Just as a small note: since Erlang/OTP 27.2, the argument `-erl_epmd_port` is obsoleted by |
| 117 | +[-kernel erl_epmd_node_listen_port](https://www.erlang.org/docs/28/apps/kernel/kernel_app#erl_epmd_node_listen_port). |
| 118 | +However, ejabberd does not yet use the new argument because ejabberd supports Erlang/OTP 25+. |
| 119 | + |
| 120 | + |
| 121 | +## epmd |
| 122 | + |
| 123 | +| Variable in ejabberdctl.cfg | Corresponding argument in Erlang/OTP | |
| 124 | +|---------------------------|--------------------------------------| |
| 125 | +| `INET_DIST_INTERFACE` | -kernel [inet_dist_use_interface](https://www.erlang.org/doc/apps/kernel/kernel_app.html#inet_dist_use_interface) | |
| 126 | +| `FIREWALL_WINDOW=XX-YY` | -kernel [inet_dist_listen_min](https://www.erlang.org/doc/apps/kernel/kernel_app.html#inet_dist_listen) `XX` inet_dist_listen_max `YY` | |
| 127 | +| `ERL_EPMD_ADDRESS` | [ERL_EPMD_ADDRESS](https://www.erlang.org/doc/apps/erts/epmd_cmd.html#environment-variables) | |
| 128 | + |
| 129 | +def:epmd |
| 130 | +: Small name server included in Erlang/OTP and used by Erlang |
| 131 | + programs when establishing distributed Erlang communications. |
| 132 | + See [`epmd (Erlang Port Mapper Daemon)`](https://www.erlang.org/doc/apps/erts/epmd_cmd.html) |
| 133 | + |
| 134 | +When [ERL_DIST_PORT](#erl_dist_port) is not set in `ejabberdctl.cfg`, |
| 135 | +Erlang starts the `epmd` program (which listens in port `4369`), |
| 136 | +and connects to that program to ask for a random port number to use. |
| 137 | + |
| 138 | +You should block the port `4369` in the firewall in such a way that |
| 139 | +only the programs in your machine can access it, |
| 140 | +or configure the environment variable `ERL_EPMD_ADDRESS` |
| 141 | +in the file `ejabberdctl.cfg`. |
| 142 | + |
| 143 | +When building a cluster of several ejabberd nodes, |
| 144 | +if you don't set [ERL_DIST_PORT](#erl_dist_port) |
| 145 | +with the same port number in `ejabberdctl.cfg` in all the nodes, |
| 146 | +then you must open the port `4369` for all the machines |
| 147 | +involved in the cluster so their epmd programs can be accessed. |
| 148 | +Remember to block the port so Internet doesn't have access to it. |
| 149 | + |
| 150 | +Once an Erlang node solved the node name of another Erlang node using |
| 151 | +EPMD and port `4369`, the nodes communicate directly. The ports used in |
| 152 | +this case by default are random, |
| 153 | +and can be restricted with the environment variable `FIREWALL_WINDOW` |
| 154 | +in the file `ejabberdctl.cfg`. |
| 155 | + |
| 156 | +The network interface where the Erlang node will listen and accept connections |
| 157 | +can be configured with the environment variable `INET_DIST_INTERFACE` |
| 158 | +in the file `ejabberdctl.cfg`. |
0 commit comments