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.
Server is intended to be started by inetd. Link is dead.
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 library mainly for providing jabberd2 with scripting capability. Useless for us.
Looks like a "summer of code" project. Kind of sparse in the docs.
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 http://code.sixapart.com/svn/djabberd/trunk/ 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.
Groupware, like Exchange or Horde, including IM service. Much more than we need.
Apple iChat is intended for MacOS-X. But where do you get the sources? Features:
your org's directory servicefor auth and identity.
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.
See jabberd2. jabberd14 is a separate fork of the predecessor code.
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.
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:
- 5222
- Main client port
- 5223
- Obsolete secure jabber port (we don't support this)
- 5269
- Server to server port (we don't have any)
- (various)
- Can interact with outside transports (we don't)
- 5280
- 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.
- 4369
- 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:
- inetrc
- Not touched, just a definition of /etc/resolv.conf.
- ejabberdctl.cfg
- Loads startup options when starting the daemon. Not touched.
- ejabberd.cfg
- 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:
{hosts, ["cft.ca.us"]}. -- Set your domain(s).
{certfile, "/etc/ssl/private/cft.pem"}, starttls, . . . -- In the stanza beginning {5222, ejabberd_c2s, [ . . . I uncommented the line for use of TLS and provided my domain certificate (see below for the format it wants).
{5223, ejabberd_c2s, [ . . . -- We are not going to support the obsolete "always on" TLS port, so I commented out this whole stanza.
%%{5269, ejabberd_s2s_in, [ . . . -- This is for server to server chatter. We have no other servers, so I left this commented out.
{5280, ejabberd_http, [ . . . -- In this stanza
I removed http_poll which we have no client for, and added
{certfile, "/etc/ssl/hostcerts/otter.crt"}, tls
, but
even so web_admin does http (no TLS) and uses Basic authentication,
i.e. plain-text passwords on the net. Hiss, boo. See below
for further tales of woe in this stanza, having to do with misplaced
commas.
%% {auth_method, internal}. -- Commented out.
{auth_method, external}.
{extauth_program, "/etc/ejabberd/extauth_sasl.pl"}. --
I uncommented the external auth method, and wrote a Perl program to
authenticate with the host operating system via saslauthd which
then uses PAM. There is a patch for ejabberd to use PAM directly,
but SuSE does not have it, and I think it would not work anyway
because PAM needs root privilege and for obvious security reasons
ejabberd runs as a special user.
{acl, admin, {user, "jimc", "cft.ca.us"}}. -- You need to create at least one user, and then edit ejabberd.cfg to give it administrative privilege. A pro-forma line is in the provided file which must be removed or changed giving your own screen name and domain.
/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 cft.ca.us $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: http://otter.mine.nu:5280/admin/
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. jimc@cft.ca.us, 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.
The unencrypted secret keys on my system are mode 640 group hostcerts, so the various services that run as user can be put in that group to be able to read the key. ejabberd needs to be added to the group too.
It wants a concatenated key and cert file; it doesn't have separate files like OpenSSL does. They must be in PEM format.
Web browsers using HTTPS expect to see a host cert for the name that they used to contact the host. When I provided that cert for ejabberd, the client (Pidgin) complained that it was looking for a cert for the domain, but got one for some irrelevant host, which possibly was an impostor.
This actually makes sense: the domain can be served by several hosts, which coordinate on the server-to-server port, and the client won't know which server it will get. When I provided a concatenated key and cert for the domain, the client was satisfied that the cert was for the right Subject -- but it was signed by an unknown certificate authority.
This is a crock in the client. It turns out that Pidgin uses libpurple which not only has its own private SSL implementation, but its own private collection of CA certs. Fortunately you can order Pidgin to accept the cert, and it will shut up in the future (not good; the cert might get revoked; the client should validate it every time). OpenSuSE/Novell bug 430379 has been filed about this issue.
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.
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.