Valid HTML 4.01 Transitional

Setting Up Ejabberd

James F. Carter <>, 2008-09-16

We aren't too happy with the old Jabber server (jabberd-2) and want to replace it with a more modern and more reliable one.

Here's a list of Jabber server software from Wikipedia. It is frequently updated; most recent on 2008-09-04 (12 days ago). For this evaluation I have restricted to open source, and excluded Java-based ones and obviously unsuitable ones. The implementation language is indicated in parens. Sorted worst to best.

in.jabberd (C)

Server is intended to be started by inetd. Link is dead.

WPJabber (C)

Wirtualna Polska -- Komunikator Spik. Po Polski. My skill in Polish is way inadequate to handle the installation instructions. Forget this. (Possibly I'm writing it off too quickly: apparently it's fairly widely used on some large sites.) (Python)

Python library mainly for providing jabberd2 with scripting capability. Useless for us.

pretzel (Python)

Looks like a "summer of code" project. Kind of sparse in the docs.

DJabberd (Perl)

Claims excellent performance. The intent is to provide a framework for developing specialized XMPP-based applications. But a vanilla sample server is included. This one looks like a possibility. I downloaded the code. There is no documentation whatsoever. Showstopper -- I'm not going to read 660 Kb of sources.

svn co localdirectory
This delivers some documentation. Nonetheless, it's still rather sparse. See particularly: ./DJabberd/README. When I tried to install it (for the procedure, see ./DJabberd/README in the sources) it warned me about the following missing prerequisites:

The tests all fail attempting to initialize Log4perl. This isn't going to fly. I gave it up. I'm not going to search all over for not-exactly-public dependencies with such tenuous documentation.

The next three are overkill for us.
Citadel (C)

Groupware, like Exchange or Horde, including IM service. Much more than we need.

iChat Server (C)

Apple iChat is intended for MacOS-X. But where do you get the sources? Features:

psyced (LPC)

Native protocol is PSYC but has multi-protocol capability including XMPP, IRC, telnet (??), Webchat, WAP. Talks server to server on PSYC, XMPP, IRC. Includes a HTTP server to show chat room history and membership. Can do SSL/TLS on all protocols supporting it. The whole thing is a bit experimental.

jabberd14 (C)

See jabberd2. jabberd14 is a separate fork of the predecessor code.

jabberd2 (C)

This is the one we already have. The organization of the components is dorky, in that each function is handled by a separate daemon in /usr/bin with a short name likely to collide with other short names. 60% of the time it won't shut down when asked to. We have had it freeze up in service occasionally. We want to upgrade this.

ejabberd (Erlang)

Many people on the web recommend this one, and apparently is fairly widely used. We're going to pick this one.

See this Wikipedia article about Erlang. It can be compiled, and also has different interpreters that execute it as-is, or which create bytecode. The Erlang provided by SuSE: it's an interpreter, but I'm not sure which style. According to the article, this language is used by several telecom companies (Ericsson, Nortel, T-Mobile) for fault-tolerant applications, as well as these projects:

(Why exclude Java? Because I don't know the language, and system administration of the packages has not gone smoothly, so I don't really trust it. Of course I don't know Erlang either. Possibly some reader will send me mail saying how much better one of the Java solutions is than ejabberd.)


I downloaded ejabberd-2.0.2 dated 2008-08-28. There is supposedly an OpenSuSE build of this. Not in the main distro, but from the SuSE build service. Available are ejabberd-2.0.0-2.3 and 3.1; I'll take the newer one. 0.6 Mb as RPM, 1.9 Mb installed. Also ejabberd-doc-(same), 1 Mb as RPM, 1.6 Mb installed.

Dependencies: erlang (of course). The SuSE build service has erlang-R11B5-5.1.i586.rpm erlang-R11B5-5.1.i586.rpm erlang-R12B2-8.1.i586.rpm erlang-R12B4-18.1.i586.rpm The third one is from the same person who built jabberd so I'm going with that one. 38 Mb as RPM, 91 Mb installed.

Read the docs:

Watch for these features:

Standard ports:

Main client port
Obsolete secure jabber port (we don't support this)
Server to server port (we don't have any)
Can interact with outside transports (we don't)
Web administration, need to enable in firewall.J. Port also can handle also http_poll; find out what that is for -- apparently a kludge for clients whose firewall won't let them connect outbound to port 5222. We don't support this.
Erlang IPC, should be (and is) blocked.


The persistent data is in /var/lib/ejabberd. It creates a user ejabberd (412) and a group ejabberd (492). Log files are in /var/log/ejabberd (need to be rotated).

You need to register a user and give it admin rights. See guide.html for the procedure.

In production, there is a configuration in the database which is affected by web admin actions. The main config file is effectively appended to that config -- probably overriding whatever is there. The main config file is supposed to be minimal, just enough to get the database loaded.

Config files in /etc/ejabberd:

Not touched, just a definition of /etc/resolv.conf.
Loads startup options when starting the daemon. Not touched.
The main configuration file. Quite a bit of editing.

With the provided ejabberd.cfg, the server starts up, of course uselessly since it's serving the wrong domain with no TLS. I made the following changes to ejabberd.cfg:

Fixing Screwups in Setup

/etc/init.d/ejabberd status says checkproc bad arguments. The provided startup script was horked. I re-wrote it, depositing a kludged up PID file and using it to check status the right way.

After my hacks to ejabberd.cfg, the server either dies after about 5 seconds, or hangs without listening on its port. /var/log/ejabberd/sasl.log reports: Crash report, syntax error before '{' (?). Presumably this is in the conf file.

ejabberd.cfg consists of a sequence of Erlang statements, and these must be syntactically valid. In particular, in a list the terms must be separated with commas (I accidentally removed one), and the last term may not be followed with a comma like you can do in Perl (I copied a certfile term, with its trailing comma, and then deleted the term following). With these commas fixed, the server starts up properly.

ejabberdctl register jimc $password -- Erlang crash (in ejabberdctl). This is the domain (virtual host) which is being served. I never found out how to make ejabberdctl perform for me.

The SuSE package creates a special user and group, both named ejabberd. The server runs as this user, as a security measure. Make sure that all necessary files are read/writable by ejabberd. It's easy to create something owned by root with mode 600.

Connect to web admin like this:
Of course my firewall blocks wild side traffic on this port. It does not do https. With http it does basic auth, i.e. plaintext passwords on the net. Give loginID with the domain, e.g., and password. It lets me on. Web admin doesn't seem all that useful; you can create users, but not a lot more. Perhaps this would be more useful on a system that used internal authentication.

For the TLS/SSL certificate I went through several iterations.

When you restart ejabberd you may need to do it twice, or allow some time between starting and stopping, otherwise the 2nd instance won't come up.

So now I have a working XMPP/Jabber server and am able to connect to it from both work and home.

Additional Points

One can put service records in DNS to point the clients at the server, but does Pidgin know about them? Apparently not. I did grep -l _tcp $libes where $libes = the output from ldd. None of them know about this service domain.

I never properly understood about the resource in a XMPP user identity. But see Quick and Dirty HOWTO for Ejabberd on Breezy dated 2006-02-16 by Glarbl_Barbl. What he says about the resource: it can be anything you want. If you use different resources you can connect multiply with the same screen name.