Saturday, June 28, 2008

Customizing Asus AM200g - IV. jabberd configuration

The following is a sequence of trial and errors, one by one, covering the path from the default config file to a working one. It is intended to be a search engine trap for people trying to resolve configuration problems.

$ telnet
Connected to r (
Escape character is '^]'.
BCM96348 ADSL Router
Login: admin
> sh
BusyBox v1.00 (2005.04.12-18:11+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.
# /var/usb/usb_1/bin/jabberd
Not writing pidfile /var/usb/usb_1/var/run/jabberd/ Read-only file system

In my setup, the jabberd ecosystem resides on a readonly filesystem, so the very first thing to do is to copy the etc/jabber.xml file to the vfat partition and make sure the files that need to be dynamically created/modified are there as well.

# mkdir /var/usb/usb_2/jabberd
# cp /var/usb/usb_1/etc/jabber.xml /var/usb/usb_2/jabberd
# /var/usb/usb_1/bin/vim /var/usb/usb_2/jabberd/jabber.xml

If you're not familiar with vi, here's quick help:

To quit without saving type ':q' (colon q Enter)

To save changes and quit type ':wq' (colon w q Enter)

To move around use the arrow keys

To start writing at cursor press 'i'

To get out of the writing mode (so that you can move somewhere else) press 'Esc'

To delete character at cursor press 'x'

The changes I did at first were:


To prevent the message

Not writing pidfile /var/usb/usb_1/var/run/jabberd/ Read-only file system

I changed /var/usb/usb_1/var/run/jabberd/ to /var/usb/usb_2/jabberd/


Next I launched jabberd in debug mode (-D) and pointed it to the alternate config file (-c path/to/file):

# /var/usb/usb_1/bin/jabberd -D -c /var/usb/usb_2/jabberd/jabber.xml
Mon Jan  3 20:31:13 2000 MIO TLS init (GNU TLS)
Mon Jan  3 20:31:14 2000 <log xmlns='jabber:server' type='warn' from='-internal'>
Cannot open /var/usb/usb_1/etc/dhparams.pem for reading dhparams: No such file or directory</log>

The comments in the file say:
<!-- With the <dhparams/> element right inside the <tls/> element,  -->
<!-- you can configure a file containing parameters for Diffie      -->
<!-- Hellmann key exchanges. If this configuration setting is not   -->
<!-- present, jabberd14 will generated these parameters             -->
<!-- automatically on each startup. This takes some time, therefore -->
<!-- you get a faster startup, if this setting is present.          -->

So I commented out <dhparams type='pem'>/var/usb/usb_1/etc/dhparams.pem</dhparams> as I don't know how to make it properly and don't mind waiting a few seconds more at startup. To start a comment, you write "<!--", you close it with "-->".


# /var/usb/usb_1/bin/jabberd -D -c /var/usb/usb_2/jabberd/jabber.xml
Mon Jan  3 20:47:02 2000 using the following query on SQL connection establishment: SET NAMES utf8
Mon Jan  3 20:47:02 2000 <log xmlns='jabber:server' type='alert' from='xdbsql.localhost'>Your xdb_sql is compiled without support
for the selected database driver 'mysql'.</log>
Mon Jan  3 20:47:02 2000 processing handler definition: <handler xmlns='jabber:config:xdb_sql' ns='jabber:iq:last'>
Mon Jan  3 20:47:03 2000 delivering to instance 'elogger.localhost'
Mon Jan  3 20:47:03 2000 DELIVER 3:xdbsql.localhost <log xmlns='jabber:server' type='alert' from='xdbsql.localhost'>Your
xdb_sql is compiled without support for the selected database driver 'mysql'.</log>

Yes, this is true, the daemon was compiled without any sql support. I've followed the steps in README.filespool to setup jabber to store data in files - I definitely don't want to run sql server on the machine. Of course I replaced the <xdb_file>$PREFIX/lib/</xdb_file> with <xdb_file>/var/usb/usb_1/lib/</xdb_file>, and <spool><jabberd:cmdline flag='s'>$PREFIX/var/spool/jabberd</jabberd:cmdline></spool> with <spool><jabberd:cmdline flag='s'>/var/usb/usb_2/jabberd/jabberdspool</jabberd:cmdline></spool> - then made sure the directory exists:
# mkdir /var/usb/usb_2/jabberd/jabberdspool


# /var/usb/usb_1/bin/jabberd -D -c /var/usb/usb_2/jabberd/jabber.xml
Mon Jan  3 21:17:58 2000 <log xmlns='jabber:server' type='alert' from='inject.localhost'>
could not open directory /var/usb/usb_1/var/spool/jabberd/inject.localhost for reading</log>

inject.localhost is a directory, where some other process can put messages. jabberd then automatically sends them. To make it working I changed
<in>/var/usb/usb_1/var/spool/jabberd/inject.localhost</in> to <in>/var/usb/usb_2/jabberd/inject.localhost</in> and created the directory with
# mkdir /var/usb/usb_2/jabberd/inject

# /var/usb/usb_1/bin/jabberd -D -c /var/usb/usb_2/jabberd/jabber.xml
Mon Jan  3 21:33:15 2000 main load check of 1.00 with 4 total threads
Mon Jan  3 21:33:16 2000 0        total users
Mon Jan  3 21:33:17 2000 dialback idle check

hmm, seems to be working ..., time to launch kopete and try registering a user hajma@ It failed, of course. The message I got from Kopete was definitely not helpful: "There was an error in the protocol stream: There was a conflict in the information received." and "Unable to create account on the server. The Jabber ID is probably already in use.". What a nonsense ... a brief look into the konsole shows the infamous "bouncing a routed packet" message:
Mon Jan  3 21:35:40 2000 DELIVER 4: <route xmlns='jabber:server' type='auth'
to='hajma@' from='14@c2s/100E0278'><iq type='set' to='' id='aab0a'>
<query xmlns='jabber:iq:register'>
Mon Jan  3 21:35:40 2000 delivering to instance 'dnsrv.localhost'
Mon Jan  3 21:35:40 2000 delivery failed (Internal Delivery Error)
Mon Jan  3 21:35:40 2000 <log xmlns='jabber:server' type='notice' from=''>bouncing a routed
packet to hajma@ from 14@c2s/100E0278: Internal Delivery Error</log>

In short, to make jabberd working correctly, you have to replace all occurences of 'localhost' by the domain or IP jabberd is listening at. Now I replaced localhost with


# /var/usb/usb_1/bin/jabberd -D -c /var/usb/usb_2/jabberd/jabber.xml

Registering with Kopete again ... This time I only got one error: "Unable to create account on the server. The Jabber ID is probably already in use.". And again it was completely unrelated - in the konsole I found this:
Mon Jan  3 21:50:02 2000 we got a reply for: username
Mon Jan  3 21:50:02 2000 we got a reply for: password
Mon Jan  3 21:50:03 2000 returned err msg: Missing data field: name
<error code='400' type='modify'><bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Missing data field: name</text></error></iq></route>

The stupid thing Kopete completely ignores XEP-0077, does not ask the server what is needed for registration and just sends username and password. To support Kopete, I had to delete
<name/> and <email/> from the <register xmlns="jabber:iq:register" notify="yes"> section.

After this change I am able to register a new user and send messages.
Just to be perfect I also changed /var/usb/usb_1/var/log/jabberd/error.log to /var/usb/usb_2/jabberd/error.log.
Off to the next level!


To have it available from outside world, I replaced with
To open a port in the AM-200g router, issue the following command:

iptables -I INPUT -p tcp -i ppp_8_48_1 --dport 5222 -m state --state NEW -j ACCEPT


The main reason for running own jabber server is more privacy and that is impossible without encryption - let's do it.
To be able to use TLS I had to generate a self-signed certificate. I've used the procedure described at

$ openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout privkey.pem -out key.pem

Generating a 1024 bit RSA private key



writing new private key to 'privkey.pem'

Enter PEM pass phrase:

Verifying - Enter PEM pass phrase:

No comments:

Post a Comment