Using Jabberd as a Private Instant Messaging Service

Van Emery - August, 2003


Have you ever thought about using a private Instant Messaging (IM) service for your own organization, family, or friends? A service with no ads, no fees, no intrusive messages from strangers; a service that does not require you to use a proprietary operating system? In short, an IM system that puts YOU in charge?

Well, such a service/protocol is called Jabber. You can use it as a completely private system, with encrypted client connections. You can also set it up so that your IM service can talk to any other Jabber system in the world, much like SMTP e-mail. Here are the features that attracted me to Jabber:

Another advantage of the Jabber system is that it is easily extensible for custom applications. For example, it can allow messaging between applications or devices, not just people!

In this HOWTO, I will go step-by-step through the process of building a private/organizational Jabber server on Red Hat Linux. Most of the instructions should work on other distributions, but I have not tested any others.

Why did I write this? Although the Jabber.Org web site has excellent documentation, it does not give you a step-by-step guide to setting up a private Jabber server that runs as a service and has reasonable security defaults. I wrote this primarily as a reference manual for myself. If you have any suggestions or corrections, please e-mail me here:

Getting the Code

Most of the software is available at, but I have placed it here for your convenience. All of the files are source code except for the daemontools package, which is a Linux RPM for the x86 architecture. If you are running a non-x86 architecture or you are using an OS other than GNU/Linux, you may want to download the code elsewhere.

Component File + Size Notes
Jabber Sever V1.4.2 jabber-1.4.2.tar.gz (674K) gzipped tarball, basic server only
Multiuser Conference Module mu-conference-0.5.2.tar.gz (46K) gzipped tarball, for chat rooms
Jabber User Directory Module jud-0.5.tar.gz (5.3K) gzipped tarball, for local user directory
Daemontools Package daemontools-0.70-5.i686.rpm (58K) RPM package, helps run jabberd as a service
Scripts and Config Files vanjabfiles.tar.gz (7.5K) gzipped tarball, all scripts and configs



My testing and production environment:


Step-by-Step Installation Instructions

  1. Unpack and compile jabber-1.4.2.tar
    [root@im Downloads]# cp jabber-1.4.2.tar.gz /usr/local
    [root@im Downloads]# cd /usr/local
    [root@im local]# gunzip jabber-1.4.2.tar.gz
    [root@im local]# tar xvf jabber-1.4.2.tar
    [root@im local]# mv jabber-1.4.2 jabber
    [root@im local]# rm jabber-1.4.2.tar
    [root@im local]# cd jabber
    Read the README file!
    [root@im jabber]# ./configure --enable-ssl
    Running Jabber Configure
    Searching for SSL...            Found.
    Getting pth settings..../configure: line 1: pth-config: command not found
    ./configure: line 1: pth-config: command not found
    ./configure: line 1: pth-config: command not found
    creating pth_acmac.h
    creating pth_acdef.h
    Now please type `make' to compile. Good luck.
    Setting Build Parameters...     Done.
    Generating Settings Script...   Done.
    You may now type 'make' to build your new Jabber system.
    [root@im jabber]# make
  2. Now, let us create a user named "jabber" and some directories with the proper permissions. You will note that we first make sure that UID 400 is not in use. Since the user "jabber" only exists for running jabberd, we are giving it a UID < 500.

    [root@im jabber]# grep :400: /etc/passwd
    [root@im jabber]# useradd -u 400 -M -d /usr/local/jabber jabber
    [root@im jabber]# mkdir --mode 0770 /etc/jabberd
    [root@im jabber]# mkdir --mode 0770 /var/run/jabberd
    [root@im jabber]# mkdir --mode 0770 /var/log/jabberd
    [root@im jabber]# chown jabber.jabber /etc/jabberd
    [root@im jabber]# chown jabber.jabber /var/run/jabberd
    [root@im jabber]# chown jabber.jabber /var/log/jabberd
  3. Now, let us unpack, compile, and install the multiuser conference component...
    [root@im Downloads]# cp mu-conference-0.5.2.tar.gz /usr/local/jabber
    [root@im Downloads]# cd /usr/local/jabber
    [root@im jabber]# gunzip mu-conference-0.5.2.tar.gz
    [root@im jabber]# tar -xvf mu-conference-0.5.2.tar
    [root@im jabber]# rm mu-conference-0.5.2.tar
    [root@im jabber]# cd mu-conf*
    Read the README file!
    [root@im mu-conference-0.5.2]# make
  4. Now, let us unpack, compile, and install the JUD component...
    [root@im Downloads]# cp jud-0.5.tar.gz /usr/local/jabber
    [root@im Downloads]# cd /usr/local/jabber
    [root@im jabber]# gunzip jud-0.5.tar.gz
    [root@im jabber]# tar -xvf jud-0.5.tar
    [root@im jabber]# mv jud-ansi-c jud-0.5
    [root@im jabber]# rm jud-0.5.tar
    [root@im jabber]# cd jud-0.5
    Read the README file!
    [root@im jud-0.5]# make
  5. Now, let us take care of some permissions and some file/directory tasks (don't forget to use your FQDN instead of "")...
    [root@im jabber]# mkdir /usr/local/jabber/spool/
    [root@im jabber]# cd /usr/local/
    [root@im local]# chown -R jabber.jabber /usr/local/jabber
    [root@im local]# chmod 0770 /usr/local/jabber
  6. Now, let us install the daemontools package...
    [root@im Downloads]# rpm -ivh daemontools-0.70-5.i686.rpm
    warning: daemontools-0.70-5.i686.rpm: V3 DSA signature: NOKEY, key ID f9651d5a
    Preparing...                ########################################### [100%]
       1:daemontools            ########################################### [100%]
    Execute "/etc/rc.d/init.d/svscan" to start svscan daemon.
    [root@im Downloads]# rpm -q daemontools
  7. Let us add the jabber TCP ports to /etc/services. Open up your favorite text editor and add the following lines to the bottom of the file:
    # Jabber Ports
    jabc            5222/tcp                        # Unencrypted jabber client-to-server
    jabc-ssl        5223/tcp                        # SSL encrypted jabber client-to-server
    jabs2s          5269/tcp                        # Jabber server-to-server
  8. In the box below, we will rename the highly-annotated jabber.xml config file into a file called, and make a copy in /etc/jabberd for reference. We will also copy jabber.xml.c2s and jabber.xml.s2s to /etc/jabberd. We will copy jabber.xml.c2s to jabber.xml. This will be your working config file. We will also make sure that the config files have the appropriate ownership and permissions.

    (If you want to enable server-to-server Jabber links so that users in your Jabber domain can communicate with users in any other Jabber domain, simply copy jabber.xml.s2s to jabber.xml instead.)

    Here are the config files: - Original config file included in the jabber-1.4.2 tarball
    jabber.xml.c2s - My config for a private IM server
    jabber.xml.s2s - My config for an organizational IM server WITH connectivity to the Jabber network

    You will need to right-click and save, specifying the proper file name, because your browser may try to interpret the XML and append .xml to the filename. If you already downloaded the vanjabfiles.tar.gz tarball and gunzipped/untarred it, then you will not need to download them here.

    [root@im Downloads]# cp -v jabber.xml.* /etc/jabberd/
    `jabber.xml.c2s' -> `/etc/jabberd/jabber.xml.c2s'
    `jabber.xml.s2s' -> `/etc/jabberd/jabber.xml.s2s'
    [root@im Downloads]# cd /usr/local/jabber
    [root@im jabber]# mv jabber.xml
    [root@im jabber]# cp -v /etc/jabberd
    `' -> `/etc/jabberd/'
    [root@im jabber]# cd /etc/jabberd
    [root@im jabberd]# cp -v jabber.xml.c2s jabber.xml
    `jabber.xml.c2s' -> `jabber.xml'
    [root@im jabberd]# chown jabber.jabber *
    [root@im jabberd]# chmod 0660 *
    [root@im jabberd]# ls -l
    total 60
    -rw-rw----    1 jabber   jabber       8380 Jul 27 01:48 jabber.xml
    -rw-rw----    1 jabber   jabber       8380 Jul 22 07:27 jabber.xml.c2s
    -rw-rw----    1 jabber   jabber      20667 Jul 19 18:49
    -rw-rw----    1 jabber   jabber       9620 Jul 27 01:48 jabber.xml.s2s
    Note:  My config files are considerably stripped down from the original, which comes with the tarball. The original contains many useful comments that you may need to reference while customizing your configuration. My config files contain only what is needed for a private IM server. One allows server-to-server links (.s2s), and one does not (.c2s)

  9. Now, let's setup the Linux run scripts so that jabberd can be started and stopped automatically, as well as managed like any other server daemon.

    First, grab this script (unless you already grabbed my tarball) and save it in your Download directory:

    Now do the following as root:
    [root@im Downloads]# cp /etc/init.d/jabberd
    [root@im Downloads]# cd /etc/init.d
    [root@im init.d]# chown root.root /etc/init.d/jabberd
    [root@im init.d]# chmod 0750 /etc/init.d/jabberd
    [root@im init.d]# ls -l jabberd
    -rwxr-x---    1 root     root         2983 Jul 17 23:22 jabberd
    [root@im init.d]# chkconfig --add jabberd
    [root@im init.d]# chkconfig --list jabberd
    jabberd         0:off   1:off   2:off    3:on    4:on    5:on    6:off

  10. Now, let's setup automatic log rotation using this config file (also already in my tarball):   jabberd.logrotate

    Global defaults are configured in /etc/logrotate.conf

    Do the following as root:
    [root@im Downloads]# cp jabberd.logrotate /etc/logrotate.d/jabberd
    [root@im Downloads]# cd /etc/logrotate.d
    [root@im logrotate.d]# chown root.root jabberd
    [root@im logrotate.d]# chmod 0660 jabberd
    [root@im logrotate.d]# ls -l jabberd
    -rw-rw----    1 root     root          217 Jul 17 23:35 jabberd

Step-by-Step Configuration Instructions

  1. Edit the /etc/jabberd/jabber.xml file to reflect your particular setup, especially the hostname and IP addresses. There are multiple places where you will have to substitute your own FQDN and IP address for "" and "". Also remember to use your own administrative JIDs instead of "".
  2. Make a TLS/SSL certificate (self-signed) and place it in the /usr/local/jabber directory. MAKE SURE that you use your hostname/FQDN in the Common Name field of the X.509 certificate dialog.
    # cd /usr/local/jabber
    [root@im jabber]# /usr/bin/openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout privkey.pem -out key.pem
    Using configuration from /usr/share/ssl/openssl.cnf
    Generating a 1024 bit RSA private key
    writing new private key to 'privkey.pem'
    Enter PEM pass phrase:
    Verifying password - Enter PEM pass phrase:
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    Country Name (2 letter code) [GB]:TW
    State or Province Name (full name) [Berkshire]:Taipei County
    Locality Name (eg, city) [Newbury]:Nankang
    Organization Name (eg, company) [My Company Ltd]:Jabs, Ltd.
    Organizational Unit Name (eg, section) []:IT Department
    Common Name (eg, your name or your server's hostname) []
    Email Address []
    [root@im jabber]# /usr/bin/openssl rsa -in privkey.pem -out privkey.pem
    read RSA key
    Enter PEM pass phrase:
    writing RSA key
    [root@im jabber]# cat privkey.pem >> key.pem
    [root@im jabber]# rm privkey.pem
    [root@im jabber]# chown jabber.jabber key.pem
    [root@im jabber]# chmod 0400 key.pem
    [root@im jabber]# ls -l key.pem
    -r--------    1 jabber   jabber       2274 Jul 17 16:53 key.pem
  3. Make sure you are logged in as user root (or su - root), then start the server to test...
    [root@im root]# /etc/init.d/jabberd start
    Starting jabberd: jabberd.
    [root@im root]# 20030717T15:45:40: [notice] (-internal): initializing server
    [root@im root]# /etc/init.d/jabberd status
     Status for Jabberd ...
    jabber   26536     1  0 23:45 pts/4    00:00:00 /usr/local/jabber/jabberd/jabber
    Note: There may be a warning about a directory or file that doesn't exist. This is O.K. as long as the server starts up (which can be tested with pgrep -l jabberd or /etc/init.d/jabberd status). The directory or file will be automatically created.
  4. Check to see that the proper TCP ports are listening:
    [jabber@im jabber]$ netstat -ta
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 *:jabc                  *:*                     LISTEN
    tcp        0      0    *:*                     LISTEN
    tcp        0      0 *:5353                  *:*                     LISTEN
    tcp        0      0 *:x11                   *:*                     LISTEN
    tcp        0      0 *:http                  *:*                     LISTEN
    tcp        0      0 mysql:smtp          *:*                     LISTEN
  5. Add three test users, one of which is listed as the server admin in your config file. Three test users will allow you to test login & authentication, presence notifications, instant messaging, JUD, and multi-user conferencing. In order to create test users, follow the instructions in the Administration section below.
  6. Now test the following to make sure your server is running correctly:

Getting Started with Administration

Since user auto-registration is disabled in this configuration, you will need to create user accounts yourself. This could be automated in various ways, such as e-mail request forms, web registration forms, your favorite scripting language, etc. The simple bash scripts below will get you started (they are also included in the vanjabfiles tarball). You can simply modify them to suit your own needs.

Note:  The jabadd and jabdel scripts assume that you are using my configuration templates. The <timeout>0</timeout> directive must be in the <xdb> section of the jabber.xml config file.

If you use the scripts, place them in /usr/local/sbin, change the ownership to root.root, and change the permissions to 0770 on all of the jab* scripts. This way, only root can invoke them. Don't forget to change the $FQDN variable in the script, or it will not work.

To check out some statistics for your Jabber server, use this script:   jabstats

For a quick listing of all user accounts on the server, use this script:   jablist

To backup your config files, user account, and other spool files, use this script:   jabbackup

To add a new user, and optionally add vCard info for that user, use this script:   jabadd

In case you are wondering what the minimum user.xml file is for a new account, I have listed a "skeleton" file below, which would be named myuser.xml:

<password xmlns='jabber:iq:auth' xdbns='jabber:iq:auth'>mypass</password>
<query xmlns='jabber:iq:register' xdbns='jabber:iq:register'>
<password xmlns='jabber:iq:auth'>mypass</password>
<x xmlns='jabber:x:delay' stamp='20030805T15:45:10'>registered</x>

To delete a user, you may simply remove their user.xml file from the proper spool directory, or you can use this script:   jabdel

Note:  If the user is still logged in when you delete them, when they logout, an imcomplete user.xml file will be written in the spool directory. They will not be able to login, but the file will remain. Also, this method of removing a user from your Jabber server does not remove any entries that the user may have had in the JUD. You have been warned...

To change passwords, you can edit the user's user.xml file directly.

Adding permanent conference rooms:

This is best done by logging into the Jabber server with a Jabber client as the configured MUC administrator. Then you can create the conference room and set the topic. With my configuration, regular users cannot create their own multiuser conference rooms. Conference rooms can be destroyed by removing their entry in the rooms.xml file and the associated .xml file in the same directory. Jabberd must then be restarted.

Other administrative tasks:

After reading the Jabberd Administration Guides at Jabber.Org, make sure that the jabberd admin user can set the MOTD and send a message to all users. You should also test publishing user info to the JUD, and searching the JUD.

Here is a link to Ken Wermann's good advice for Jabberd administrators:    Admin Advice

Security Notes

Unresolved Issues

Here is a short list of problems I ran into:

All of these issues may be addressed by the upcoming Jabberd 2 server software.

A Note on Jabber Clients

I have tried a number of Jabber clients for Linux and for Win32. The selection (and ease of installation) of clients is currently better for Windows than for Linux. I have tried a number of clients for Linux, including Gaim, and the only one that I really like is Psi. It has a clean interface, is easy to setup, and works on Linux, Windows, and Mac OS X. There are binary packages available for several popular Linux distros, including Psi v0.9 for Red Hat 9. The Red Hat 9 RPMs include the QSSL libraries for SSL/TLS encryption, which can be a "bear" to find and install properly otherwise. For convenience, I have placed the Red Hat 9 RPMs and the Win32 installer for Psi v0.9 on this server. The Psi web site should be checked for newer software and documentation.

The Psi web site:

Component File + Size Notes
Psi Jabber Client psi-0.9-1.i386.rpm (1.2M) RPM, for RH 9 Linux x86
Psi Icon Sets psi-iconsets-0.1-0.i386.rpm (120K) RPM, for RH 9 Linux x86
QSSL Package qssl-2.0-0.i386.rpm (277K) RPM, RH 9, has SSL/TLS libs
Win32 Client psi-0.9-setup.exe (2.8M) Win32 installer, with SSL

The Jabber client page at Jabber.Org has a complete listing of clients for each OS.

Links to other jabber resources


Setting up your own IM server with jabberd is not difficult, and it allows your organization to control its own instant messaging. In this way, security can be maintained. Hopefully, IM protocols will soon be standardized by the IETF so that IM will become a ubiquitous, distributed service similar to e-mail, but much more immediate and flexible.

Have fun with your Jabber server!

Back to Linux Gouge

Valid HTML 4.01! jabberbutton.png