summaryrefslogtreecommitdiff
path: root/content/ejabberd.md
blob: eff3b3604d19e44056f57292195b8bfd11e4e15f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
---
title: "ejabberd"
date: 2022-03-29
icon: 'ejabberd.png'
tags: ['service']
short_desc: "A chat server based on XMPP."
---

[Ejabberd](https://ejabberd.im) is a server for the XMPP protocol written in Erlang. It's more scalable, and easier to setup than [Prosody](/prosody) due to having most of its modules built-in and pre-configured by default.

## Prerequisites

### Subdomains

Ejabberd presumes that you have already created all the **required and optional subdomains** for its operation prior to running it.

Depending on the usecase, you may need any or all of the following domains for XMPP functionality:

-   **example.org** - Your XMPP hostname
-   **conference.example.org** - For `mod_muc`, Multi User Chats (MUCs)
-   **upload.example.org** - For `mod_http_upload`, file upload support
-   **proxy.example.org** - For `mod_proxy65`, SOCKS5 proxy support
-   **pubsub.example.org** - For `mod_pubsub`, publish-subscribe support (A fancier RSS)

Only the **example.org** domain is required for basic, private chat usage.
If you do **not** wish to use a certain domain, just disable it's associated module and ejabberd won't complain when it can't find it's associated certificate.
For example, if you don't want [Publish-Subscribe](https://xmpp.org/extensions/xep-0060.html) support, just comment out the `mod_pubsub` config in `/etc/ejabberd.yml`:

```yml
##  mod_pubsub:
##    access_createnode: pubsub_createnode
##    plugins:
##      - flat
##      - pep
##    force_node_config:
##      ## Avoid buggy clients to make their bookmarks public
##      storage:bookmarks:
##        access_model: whitelist
```

This guide will assume **all these subdomains** have been created.

#### Custom Subdomains

If you wish to customize any of these domains, edit `/etc/ejabberd.yml` and under every appropriate module that needs a subdomain, add the following setting:
```yml
mod_muc:
  host: {{<hl>}}muc.example.org{{</hl>}}
```

## Installation

To get the latest version of ejabberd, you need to first setup the ejabberd apt repositories:

```sh
curl -o /etc/apt/sources.list.d/ejabberd.list https://repo.process-one.net/ejabberd.list
curl -o /etc/apt/trusted.gpg.d/ejabberd.gpg https://repo.process-one.net/ejabberd.gpg
```

Then update the repositories and install the `ejabberd` package:

```sh
apt update
apt install ejabberd
```

## Configuration

The ejabberd server is configured in `/etc/ejabberd/ejabberd.yml`.
Changes are only applied by restarting the ejabberd daemon in systemd:

```sh
systemctl restart ejabberd
```

### Hostnames

The **XMPP hostname** is specified in the `hosts` section of
`ejabberd.yml`:

```yml
hosts:
  - {{<hl>}}example.org{{</hl>}}
```

### Certificates

Unlike [Prosody,](https://prosody.im) ejabberd doesn\'t come equipped
with a script that can automatically copy over the relevant certificates
to a directory where the ejabberd user can read them.

One way of organizing certificates for ejabberd is to have them stored
in `/etc/ejabberd/certs`, with each domain having a separate directory
for both the fullchain cert and private key.

Using certbot, this process can be easily automated with these commands:

```bash
DOMAIN={{<hl>}}example.org{{</hl>}}

# Set the domain names you want here
declare -a subdomains=("" "conference." "proxy." "pubsub." "upload.")

for i in "${subdomains[@]}"; do
    certbot --nginx -d $i$DOMAIN certonly
    mkdir -p /etc/ejabberd/certs/$i$DOMAIN
    cp /etc/letsencrypt/live/$i$DOMAIN/fullchain.pem /etc/ejabberd/certs/$i$DOMAIN
    cp /etc/letsencrypt/live/$i$DOMAIN/privkey.pem /etc/ejabberd/certs/$i$DOMAIN
done
```
*Note: Just like with Prosody, you might want to write this script to a file and setup a [cronjob](/cron) to run it periodically. This should help prevent your certificates from expiring.*

Make sure all the certificates are readable by the `ejabberd` user:
```sh
chown -R ejabberd:ejabberd /etc/ejabberd/certs
```

To enable the use of all these certificates in ejabberd, the following
configuration is necessary:

```yml
certfiles:
  - "/etc/ejabberd/certs/*/*.pem"
```

### Admin User

The **admin user** can be specified in `ejabberd.yml` under the `acl`
section:

```yml
acl:
  admin:
    user: admin
```

This would make **admin@example.org** the user with administrator
privileges.

### File Uploads

To ensure full compliance with XMPP standards, add the following configuration to `mod_http_upload`:

```yaml
mod_http_upload:
    put_url: https://@HOST@:5443/upload
    docroot: {{<hl>}}/var/www/upload{{</hl>}}
    custom_headers:
      "Access-Control-Allow-Origin": "https://@HOST@"
      "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
      "Access-Control-Allow-Headers": "Content-Type"
```

Make sure to create and give the `ejabberd` user ownership of `/var/www/upload` or any other directory you choose to use for file uploads:

```sh
chown -R ejabberd:ejabberd /var/www/upload
```

### Message Archives

The ejabberd server supports keeping archives of messages through its `mod_mam` module. This can be enabled by uncommenting the following lines:

```yml
mod_mam:
  assume_mam_usage: true
  default: always
```

## Database

### Why use a database?

We can find the following comment in the `mod_mam` section of `/etc/ejabberd.yml`:

```yml
mod_mam:
  ## Mnesia is limited to 2GB, better to use an SQL backend
  ## For small servers SQLite is a good fit and is very easy
  ## to configure. Uncomment this when you have SQL configured:
  ## db_type: sql
```

As these comments imply, an **SQL backend** is strongly recommended if you wish to use your ejabberd server for anything more than just testing. Ejabberd supports **MySQL, SQLite** and **PostgreSQL.** For the purpose of efficiency, this guide will use **PostgresSQL** because other server software like [Matrix](/matrix) and [PeerTube](/peertube) support it.

### Installing PostgreSQL

PostgreSQL is available in the Debian repositories:

```sh
apt install postgresql
```

In addition, you will have to install the **appropriate headers for Erlang,** the language ejabberd is written in, so it can actually interact with the PostgreSQL server:
```sh
apt install erlang-p1-pgsql
```

Start the PostgreSQL daemon to begin using it:

```sh
systemctl start postgresql
```

### Creating the Database

To create the database, first create a PostgreSQL user for ejabberd:

```sh
su -c "createuser --pwprompt ejabberd" postgres
```

Then, create the database and make `ejabberd` its owner:

```sh
su -c "psql -c 'CREATE DATABASE ejabberd OWNER ejabberd;'" postgres
```

### Importing Database Scheme

Ejabberd does **not** create the database scheme by default; It has to be imported into the database before use.

```sh
su -c "curl -s https://raw.githubusercontent.com/processone/ejabberd/master/sql/pg.sql | psql ejabberd" postgres
```

### Configuring ejabberd to use PostgreSQL

Finally, add the following configuration to `ejabberd.yml`:

```yml
sql_type: pgsql
sql_server: "localhost"
sql_database: "{{<hl>}}ejabberd{{</hl>}}"
sql_username: "{{<hl>}}ejabberd{{</hl>}}"
sql_password: "{{<hl>}}psql_password{{</hl>}}"

default_db: sql
```
That line at the end sets **every module's database** to default to the `sql` backend. This includes the `mod_mam` module, so all our data is being stored with PostgreSQL.

### Voice and Video Calls

Ejabberd supports the **TURN** and **STUN** protocols to allow internet users behind NATs to perform voice and video calls with other XMPP users. **This is enabled by default using [ejabberd_stun](https://docs.ejabberd.im/admin/configuration/listen#ejabberd-stun-1).**

**However,** if you plan on running ejabberd alongside **other applications** that require TURN and STUN, such as Matrix, then you'll have to setup your own external TURN server using Coturn.

#### Setup with Coturn and `mod_stun_disco`

Firstly, setup a TURN and STUN server with [Coturn,](/coturn) using an **authentication secret.**

Then, edit `mod_stun_disco` to contain the appropriate information for
your turnserver:

```yml
  mod_stun_disco:
    secret: "{{<hl>}}your_auth_secret{{</hl>}}"
    services:
      -
        host: {{<hl>}}turn.example.org{{</hl>}}
        type: stun
      -
        host: {{<hl>}}turn.example.org{{</hl>}}
        type: turn
```


## Using ejabberd

### Registering the Admin User

To begin using ejabberd, firstly start the ejabberd daemon:

```sh
systemctl restart ejabberd
```

Then, using `ejabberdctl` as the ejabberd user, register the admin user which is set in `ejabberd.yml`:

```sh
su -c "ejabberdctl register {{<hl>}}admin example.org password{{</hl>}}" ejabberd
```

This will create the user **admin@example.org.**

### Using the Web Interface

By default, ejabberd has a web interface accessible from **http://example.org:5280/admin**. When accessing this interface, you will be prompted for the admin credentials:

{{< img src="/pix/ejabberd-login.webp" >}}

After signing in with the admin credentials, you will be able to manage
your ejabberd server from this web interface:

{{< img src="/pix/ejabberd-admin.webp" >}}

## Further Configuration

For a deeper look into all the modules and options, have a look at the following ejabberd documentation:
- Ejabberd's [Listen Modules](https://docs.ejabberd.im/admin/configuration/listen/) and [Listen Options](https://docs.ejabberd.im/admin/configuration/listen-options/)
- Ejabberd's [Top-Level Options](https://docs.ejabberd.im/admin/configuration/toplevel/)
- Ejabberd's [Modules' Options](https://docs.ejabberd.im/admin/configuration/modules/)

*And with that, you've successfully setup your ejabberd XMPP server!*

---

Written by [Denshi.](https://denshi.org)
Donate Monero at:
`48dnPpGgo8WernVJp5VhvhaX3u9e46NujdYA44u8zuMdETNC5jXiA9S7JoYMM6qRt1ZcKpt1J3RZ3JPuMyXetmbHH7Mnc9C`