This is Chapter 3 from O'Reilly's Programming Jabber, by D.J. Adams. In it, D.J. tells how to obtain, install, configure, and start up a Jabber server of your own with the minimum of fuss. D.J. also writes about Jabber for the O'Reilly Network, including a recent article on Jabber Chatbots. -- Ed.
It's certainly possible to learn about the Jabber protocols and technology and develop solutions using someone else's Jabber server, but for real understanding and control, it's definitely worth setting up one of your own. By installing and configuring a Jabber server, you will gain a valuable insight into how it and its components work together. Understanding how components are controlled and configured allows us to build Jabber solutions in the context of the "big picture."
Contents |
Installations of earlier versions (1.0, 1.2) of the Jabber server were often complex affairs, and while the installation process has become much more straightforward, some people still shrink back from installing and configuring their own. This chapter shows how straightforward it is.
If you already have a server set up, you might want to skip this chapter and go on to Chapter 4, where the configuration and systcode architecture are explained in more detail.
Although the Jabber development platform is Linux, the Jabber server will
compile and run on many flavors of Unix, including FreeBSD, Solaris,
AIX, and IRIX.[1]
Versions of the C compiler and make utility
from the GNU project (at
http://www.gnu.org)
are recommended if you don't already have thcode installed.
The examples shown in this and other chapters are taken from Linux platforms (various Slackware and Red Hat distributions with 2.2 and 2.4 kernel versions); consult your local documentation for equivalent commands on your Unix OS.
The incarnation of the Jabber server at the time of writing is Version 1.4, more specifically 1.4.1. Version 1.4 represents a major advance in the server code and brings increases in performance and reliability over earlier versions. Jabber server Version 1.4.1 is the one we will obtain and install here, and this will be used as the server for the recipes in the rest of this book.
|
Related Reading
|
The Jabber server package can be obtained from the Jabber project site, http://www.jabber.org; the 1.4.1 version is available in the downloads area:
http://download.jabber.org/dists/1.4/final/jabber-1.4.1.tar.gz
The tarball jabber-1.4.1.tar.gz contains everything
that you need to get a Jabber server up and running.[2]
Previous versions of the Jabber server came in multiple
packages; it was necessary to separately obtain and install GNU's portable
threads library (pth) and the asynchronous DNS package
(ADNS), as well as obtaining and installing various
Jabber-specific libraries such as libxode,
libjabber, and libetherx. Now some
of these libraries and packages have become obsolete as far as the Jabber
server is concerned (ADNS and libetherx)
and others have been combined into the main Jabber server tarball.
If you don't want to compile the server yourself, you can also download prebuilt binaries for some of the platforms already mentioned, from http://download.jabber.org.
Once you have downloaded the Jabber server tarball, you need to unpack it, configure the build environment, and compile the server. The general idea is that the Jabber server will be compiled and run from wherever you decide to unpack it; that is, there is no separate "install" step.
For this reason, and because it's also often useful to be able to install
and start up a different version of the Jabber server for testing and
comparisons, create a generic jabber directory somewhere central but
local, for example in /usr/local/:
yak:/usr/local# mkdir jabber
The Jabber server does not need to be and should not be run as root;
so create a new user jabber(group jabber) to be used as the Jabber server administrator
and make that user the owner of the generic Jabber server directory:
yak:/usr/local# groupadd jabber
yak:/usr/local# useradd -g jabber -d /usr/local/jabber jabber
yak:/usr/local# passwd jabber
Changing password for jabber
Enter the new password (minimum of 5, maximum of 127 characters)
Please use a combination of upper and lower case letters and numbers.
New password: ********
Re-enter new password: ********
Password changed.
yak:/usr/local# chown jabber:jabber jabber
yak:/usr/local#
Once you've created the generic Jabber server directory, switch to the new
Jabber server administration user jabber,
unpack the tarball you downloaded, and enter the resulting directory:
yak:/usr/local# su - jabber
yak:~$ tar xzf jabber-1.4.1.tar.gz
yak:~$ cd jabber-1.4.1/
yak:~/jabber-1.4.1$
Examining the contents of the jabber-1.4.1 directory,
we see the following files:
configure (the configuration script)
jabber.xml (the server configuration file)
Makefile (for compiling the Jabber server)
README (some basic instructions)
UPGRADE (information on upgrading from an earlier server version)
as well as a number of directories that contain the source code.
The first step is to run the configure script:
yak:~/jabber-1.4.1$ ./configure
to determine your platform's compiler settings.
If you want SSL support in the Jabber server, run the script with the - -enable-ssl switch:
yak:~/jabber-1.4.1$ ./configure --enable-ssl
If you specified the - -enable-ssl switch, the
configure script looks for your SSL installation
and adds the
appropriate compiler flags. If it doesn't find your SSL installation, it
says so and your Jabber server is compiled withoutSSL support.
Next, it will try to determine whether you have pth
installed and if so will use the pth-config command
to glean the extra compiler options for building the Jabber server.
pth is required, so if it isn'talready installed, it
will be set up within your current jabber-1.4.1 directory
tree (as pth is included in the
jabber-1.4.1.tar.gz tarball) and the appropriate compiler
options added.
If pth is set up during the course of
running configure, you may see a message:
"Now please type 'make' to compile. Good luck.",
which comes at the end of the pth configure procedure;
you can ignore this because there is only one
make step,
for the Jabber server, that must be carried out as we are merely preparing
the pth build environment for binding into the Jabber
Server build.
Finally, after extra platform-specific compiler settings are determined,
a shell script to set the build environment variables is created with the
name platform-settings. This is used in the next step.
Example 3-1 shows typical output from the
configure script.
Running Jabber Configure
========================
Getting pth settings... Done.
Setting Build Parameters... Done.
Generating Settings Script... Done.
You may now type 'make' to build your new Jabber systcode.
|
Once the platform settings have been determined by the configure
script, we are ready to build the Jabber server with
make:
yak:~/jabber-1.4.1$ make
Example 3-2 shows abbreviated typical output from the
make command.
Making all in pthsock
make[1]: Entering directory `/usr/local/jabber/jabber-1.4.1/pthsock'
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -I../jabberd/ -c client.c -o
client.o
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -I../jabberd/ -shared -o pthsoc
k_client.so client.o -L/usr/local/lib -lpth -ldl -lresolv
make[1]: Leaving directory `/usr/local/jabber/jabber-1.4.1/pthsock'
Making all in xdb_file
make[1]: Entering directory `/usr/local/jabber/jabber-1.4.1/xdb_file'
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -I../jabberd -c xdb_file.c -o
xdb_file.o
...
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -DHOME="\"/usr/local/jabber/jab
ber-1.4.1\"" -DCONFIGXML="\"jabber.xml\"" -o jabberd config.o mio.o mio_raw.o mi
o_xml.o mio_ssl.o deliver.o heartbeat.o jabberd.o load.o xdb.o mtq.o static.o lo
g.o lib/expat.o lib/genhash.o lib/hashtable.o lib/jid.o lib/jpacket.o lib/jutil.
o lib/karma.o lib/pool.o lib/pproxy.o lib/rate.o lib/sha.o lib/snprintf.o lib/so
cket.o lib/str.o lib/xmlnode.o lib/xmlparse.o lib/xmlrole.o lib/xmltok.o lib/xst
ream.o lib/xhash.o base/base_connect.o base/base_dynamic.o base/base_exec.o base
/base_stdout.o base/base_accept.o base/base_file.o base/base_format.o base/base_
stderr.o base/base_to.o -Wl,--export-dynamic -L/usr/local/lib -lpth -ldl -lresol
v
make[2]: Leaving directory `/usr/local/jabber/jabber-1.4.1/jabberd'
make[1]: Leaving directory `/usr/local/jabber/jabber-1.4.1/jabberd'
make[1]: Entering directory `/usr/local/jabber/jabber-1.4.1'
make[1]: Nothing to be done for `all-local'.
make[1]: Leaving directory `/usr/local/jabber/jabber-1.4.1'
Running from the Build Environment? You may be wondering where the
make installstep is -- there isn't one. The Jabber server is run from within its build environment. One of the reasons for this is that additional components, such as transports, which may be installed at any time after the basic server installation, must be compiled with reference to various Jabber server header file information. One of the simplest ways of making this happen is to have the source for those components unpacked in a subdirectory within thejabber-1.4.1directory tree, and at compilation time component-level references to header files at the Jabber server level can be made using relative directory names that point back up the directory hierarchy.
The nature and behavior of a Jabber server is controlled by the contents
of a configuration file (with a default name of
jabber.xml), which you will find in the jabber-1.4.1 directory.
As you can probably guess from the filename's extension, the configuration
is formatted in XML, which offers a very powerful way of expressing the
nature and features of your Jabber server and associated services and
components.
Details on how to navigate, interpret, and edit this configuration file are given in Chapter 4; here we will just look at the basic settings that can be modified before you start up the Jabber server.
For an experimental Jabber server (such as for the purposes of this book), there
isn't actually anything you need to change in the
configuration. The
out-of-the-box configuration settings are pretty much what we need in order
to experiment with our recipes later in the book; nevertheless, let's
look at some of the settings you may wish to change right now:
The <host/>
parameter specifies the
Jabber server's hostname. As delivered, the jabber.xmlconfiguration has this set to localhost:
<host><jabberd:cmdline flag="h">localhost</jabberd:cmdline></host>
You can change this to the name of your server hostname; in the case
of our examples, this would be yak.
The localhost setting occurs elsewhere in the
configuration too -- as a literal in the welcome message
that is sent to users after a successful registration with the server. You
may wish to replace this occurrence of localhost;
furthermore, you will find other occurrences, but they are within sections
of the configuration that are commented out in the standard delivered version
of jabber.xml (specifically, administration JIDs
and definitions for various add-on agents and transports; we will
cover these in the next chapter).
One other place that localhost occurs is in the
<update/> section, which is
explained next.
The Jabber server development team offers a facility for servers to check for updated versions of the Jabber server software. The facility is addressed with this configuration setting:
<update><jabberd:cmdline flag="h">localhost</jabberd:cmdline></update>
which causes a versioning module, mod_version,
in the Jabber Session Manager (JSM), to
send a <presence/> packet
(which carries the server version -- in our case, 1.4.1)
from the server to the Jabber ID
jsm@update.jabber.org when the Jabber
server starts up.
If your server is purely internal, and/or behind a firewall, it makes
no sense to have this facility switched on (you can check for updates
to the server on the
http://www.jabber.org web site)
as the <presence/> packet will
never reach its intended destination. You can comment it out like this:
<!--
<update><jabberd:cmdline flag="h">localhost</jabberd:cmdline></update>
-->
The configuration as delivered contains a directive:
<vcard2jud/>
which means that any
vCard data -- a vCard is a virtual "business card" containing
contact information and so on -- that is maintained
by a Jabber client will be automatically passed on to the central user
directory (the Jabber User Directory, or JUD), defined elsewhere in the
jabber.xml as the one at jabber.org, users.jabber.org.
If you've commented out the update notification mechanism because you're
not going to be able to (or want to) reach the servers at jabber.org, then you might as well comment this out
to avoid error messages being sent to Jabber clients when vCard data is
modified:
<!--
<vcard2jud/>
-->
Alternatively, instead of commenting out the
<vcard2jud/>,
you could comment out the definition of the
JUD service in the <browse/>
section:
<!--
<service type="jud" jid="users.jabber.org" name="Jabber User Directory">
<ns>jabber:iq:search</ns>
<ns>jabber:iq:register</ns>
</service>
-->
because the mechanism looks in the
<browse/>
section for a reference to a JUD service; if there isn't one there, no
vCard update will be sent.
NOTE: Some Jabber clients such as Jabber Instant Messenger (JIM) require
vCard information to be entered when registering for a new account, which
means that an attcodept to contact
users.jabber.orgwould be made the first time a user connects.
You may have noticed that the values for each of these two settings
(<host/> and
<update/>)
were wrapped in another tag:
<jabberd:cmdline flag="h">...</jabberd:cmdline>
This means that you can override the setting with a command-line switch
(or "flag"), in this case -h. So, in fact, you don't
even need to modify the jabber.xml configuration
at all, if you specify your hostname when you start the server up (the
welcome message will not be changed, of course).
|
At this stage, we have a Jabber server with enough basic configuration
to be able to start it up and have it do something useful (like accept
client connections). If you're curious about the rest of the configuration
you encountered while editing the jabber.xml file,
you can jump to Chapter 4. Otherwise, let's start
it up!
The basic invocation looks like this:
yak:~/jabber-1.4.1$ ./jabberd/jabberd
but if you haven't bothered to change localhost anywhere
in the configuration (as described earlier), you can use the -h
switch to specify the hostname:
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak
As it stands, there's a directive in the standard
jabber.xml configuration file that specifies that
any server error messages are to be written out to STDERR:
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>error.log</file>
<stderr/>
</log>
So either comment the directive out:
<!--
<stderr/>
-->
Or redirect STDERR to /dev/null:
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak 2>/dev/null
You won't lose the error messages -- as you can see they're also written to the
error.log file.
Assuming you wish to free up the terminal session after starting the server, you can send it to the background:
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak 2>/dev/null &
Once the server is started, you're ready to start up a client and
make a connection. The thing to rcodecodeber at this point, when specifying
which server to connect to, is to use the same hostname as you specified
in the <host/> part of the configuration,
described earlier in "Configuring the Jabber Server."
NOTE: If your client supports the <alias/> mechanism, described in the section "Customer Configuration" in Chapter 4,
this may not be necessary.
To stop the server, just kill the processes, and it will shut down:
yak:~/jabber-1.4.1$ killall jabberd
or:
yak:~/jabber-1.4.1$ kill `cat jabber.pid`
We've seen the -h switch to specify the host when starting the server up. There are other switches available on the command line, too; they are listed in Table 3-1.
|
Switch |
Relating to |
Description |
|---|---|---|
|
-c |
Alternate configuration |
Use this to specify an alternative configuration file
if you don't want to use |
|
-D |
Debugging info |
Specifying this switch will cause (a large amount of) debugging information to be sent to STDERR. |
|
-h |
Hostname |
The hostname of the Jabber server. |
|
-H |
Home folder |
Used to specify "home" folder or directory. |
|
-s |
Spool area |
The directory where the Jabber server stores data via the
|
|
-v |
Show version |
Reports Jabber server version and exits. |
|
-V |
Show version |
Same as -v. |
|
-Z |
Debugging info |
Limits the debugging information to certain "zones" (comma-separated).[3] |
Starting the Jabber server with any unrecognized switches will cause it to show you a list of valid switches:
[yak: ~/jabber-1.4.1]$ ./jabberd/jabberd -badswitch
Usage:
jabberd &
Optional Parameters:
-c configuration file
-D enable debug output
-H location of home folder
-v server version
-V server version
Yes, the list that it shows isn't complete. If the common switch -h were present in the list, we could almost consider the unlisted switches as undocumented, but it isn't present, so we won't.
|
We've already seen a glimpse of the configuration relating to logging of messages in the previous section. As standard, the Jabber server configuration describes two types of logging record and a recipient file for each type:
Error log records are written to error.log in the
current directory, as determined thus:
<log id='elogger'>
<host/>
<logtype/>
<format>%d: [%t] (%h): %s</format>
<file>error.log</file>
<stderr/>
</log>
Statistical log records used for tracking purposes are written to
record.log in the current directory, as determined thus:
<log id='rlogger'>
<host/>
<logtype>record</logtype>
<format>%d %h %s</format>
<file>record.log</file>
</log>
Log records of this type are written when a client connects to the server and when a client disconnects.
Furthermore, we can use the debugging switch (-D) when we start the server and have debugging and trace output written to STDERR.
A number of likely candidates might have prevented your server from starting.
It is not difficult to make errors (typographical or otherwise) in the
server configuration. The first line of defense is to be careful
when editing your jabber.xml file. After that,
the Jabber server isn't going to be too forthcoming with information if
you have broken the well-formedness of the XML:
yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak
Configuration parsing using jabber.xml failed
Help is at hand in the shape of Perl and the XML::Parser module, which
is a wrapper around the XML parser, expat.
Providing you have Perl and the XML::Parser module installed, you can
get expat to give you a clue where the XML is broken:
yak:~/jabber-1.4.1$ perl -MXML::Parser
-e 'XML::Parser->new->parsefile("jabber.xml", ErrorContext => 3)'
not well-formed (invalid token) at line 47, column 35, byte 1750:
be on one line, the server doesn't like it otherwise! :)
-->
<host><jabberd:cmdline flag="h"yak</jabberd:cmdline></host>
==================================^
<!--
This is the custom configuration section for the
at /usr/local/lib/perl5/site_perl/5.6.0/i586-linux/XML/Parser.pm line 185
yak:~/jabber-1.4.1$
This shows us exactly where the problcode is.[4]
In this case, the close-tag symbol (>) had been inadvertently rcodeoved when replacing localhostwith yak.
No XML Is Bad XML! If you don't use the -c switch to specify which configuration file to use, the standard
jabber.xmlis used. If that file can't be found, you getexactly the same erroras if your XML was not well-formed. You've been warned!
Taking the standard jabber.xml configuration,
the Jabber server tries to bind to and listen on two ports: 5222 (for
client connections) and 5269 (for server-to-server connections). If
other processes are listening to these ports, then the Jabber
server can't start and you'll see something like this in the
error log:
20010407T12:11:06: [alert] (-internal): io_select unable to listen
on 5222 [(null)]
20010406T12:11:06: [alert] (-internal): io_select unable to listen
on 5269 [(null)]
If this is the case, use the netstat command
to check the status of the ports:
yak:~/jabber-1.4.1$ netstat -an | grep -E '5222|5269'
tcp 0 0 0.0.0.0:5269 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:5222 0.0.0.0:* LISTEN
If you see entries like this, it means that processes have been bound to
these ports on all IP addresses.[5]
For example, if
0.0.0.0:5222 is being
listened to then you may have another
instance of a Jabber server already running.
On some BSD systcodes, you cannot bind to the "default" null address; the same
error messages will be issued as if the ports were already bound. In the
standard jabber.xml configuration file, a bind
to the null address is specified for each port as standard; you must change this and specify an explicit IP address for each of
the ports in the configuration. That is, instead of:
<ip port="5222"/>
do something like this:
<ip port="5222">127.0.0.1</ip>
[1]In fact, the next patch level version of the Jabber server, 1.4.2, which is available already, has the modifications necessary for it to be compilable under Mac OS X.
[2]If you want the Jabber server to support SSL connections, you will need to have installed an SSL package; see the next chapter for more details.
[3]The "zones" are the filenames that immediately follow the timestamp in the
debug log records, for example, xdb_file or deliver. Specifying one or
more zones will limit debug output to lines that pertain to those zones.
[4] Better highlighting of problcodes in parsing the configuration file is available in Version 1.4.2 of the server. You're told where the configuration is broken or if there were problcodes opening the file.
[5]This "all" relates to the
(null) shown in the unable-to-listen
error messages shown earlier.
DJ Adams is the author of O'Reilly's Programming Jabber book.
O'Reilly & Associates recently released (December 2001) Programming Jabber.
Sample Chapter 5, Jabber Technology Basics, is available free online.
You can also look at the Table of Contents, the Index, and the Full Description of the book.
For more information, or to order the book, click here.
Copyright © 2007 O'Reilly Media, Inc.