{"id":91,"date":"2011-10-10T09:16:56","date_gmt":"2011-10-09T20:16:56","guid":{"rendered":"http:\/\/www.templesoft.co.nz\/blog\/?p=91"},"modified":"2026-04-08T08:19:30","modified_gmt":"2026-04-07T20:19:30","slug":"building-a-xmpp-jabber-server","status":"publish","type":"post","link":"https:\/\/templesoft.co.nz\/journal\/?p=91","title":{"rendered":"Building a XMPP (Jabber) server."},"content":{"rendered":"<h2>Setting up an XMPP server<\/h2>\n<h3>&#8220;XMPP by any other name would&#8230;&#8221;<\/h3>\n<p style=\"text-align: justify;\">We recently had a chat (pun not intended) amongst the team to discuss some of the ways we could cut costs during these financially challenged times. One area identified was around inter-office calling charges. We have three stores: one in Onehunga (local), one in Tawa (national) and one in Hamilton (national). All of which are subject to charges when they call us here at head office (and vice versa).<\/p>\n<p style=\"text-align: justify;\">We use <a href=\"http:\/\/www.fonality.com\/hud\/\">Fonality&#8217;s HUD client<\/a> here at head office (actually <a href=\"http:\/\/www.hudlite.org\/\">HUDlite<\/a> to be exact because it&#8217;s free) for call management, presence management and IM.<\/p>\n<p style=\"text-align: justify;\">So a thought was born that maybe we could link the remote sites to the HUDLite server on our VoIP system, and they could IM rather than calling. But alas, it all seemed a little too hard and we could foresee a few problems, so we opted instead to make our own Jabber server (using the <a href=\"http:\/\/xmpp.org\/\">XMPP<\/a> protocol) and give the sites access to that.<\/p>\n<p style=\"text-align: justify;\">This turned out to be a great compromise. Now staff at the remote sites IM rather than calling &#8211; they can see if the person they want to talk to is available and can get answers immediately. Even better, what would have been a calling cost is absorbed as part of our data charges.<\/p>\n<h3 style=\"text-align: justify;\">So how did I do it?<\/h3>\n<p style=\"text-align: justify;\">I already knew I was going to use Ubuntu server for this project, but I had to decide between Jabber or IRC (why? because those were the two mentioned in the Ubuntu server guide&#8230;*snigger*). For reasons like clients, setup, the name (I do like Jabber over IRC) I went with Jabber, or to be more precise an XMPP server.<\/p>\n<p style=\"text-align: justify;\">The start was a basic build using Ubuntu 10.04 LTS (there are newer versions at the time of writing this but I prefer their Long Term Support version &#8211; until the next one does&#8230;). Near the end of the install (when prompted if you want additional software installed) I selected OpenSSH server so I can log in remotely to administer the system and install the components &#8211; it&#8217;s handy if you need to copy-and-paste.<\/p>\n<p style=\"text-align: justify;\">After the first reboot make sure that <strong>universe<\/strong> and <strong>multiverse<\/strong> are present in the <strong>sources.list<\/strong> file (add them if they are not&#8230;)<\/p>\n<pre style=\"text-align: justify;\">sudo vi \/etc\/apt\/sources.list<\/pre>\n<p style=\"text-align: justify;\">Once that&#8217;s done, I make sure everything is up-to-date<\/p>\n<pre style=\"text-align: justify;\">sudo aptitude update\r\nsudo aptitude safe-upgrade<\/pre>\n<p style=\"text-align: justify;\">Then one more reboot for good luck and we&#8217;re on our way.<\/p>\n<pre style=\"text-align: justify;\">sudo shutdown -r now<\/pre>\n<h2>Basic install<\/h2>\n<p style=\"text-align: justify;\">The XMPP server can support a number of db backends. By default it uses MySQL so that was how I left it for our server. Preliminary testing was unsuccessfully using the &#8220;Berkeley DB&#8221; as the user authentication database, however jabberd2 can be configured to use LDAP, MySQL, Postgresql, etc.<\/p>\n<p style=\"text-align: justify;\">For this HOW-TO we&#8217;ll be using MySQL, so&#8230;<\/p>\n<pre style=\"text-align: justify;\">sudo aptitude install mysql-server<\/pre>\n<p style=\"text-align: justify;\">When prompted, type in a password for the MySQL &#8216;<strong>root<\/strong>&#8216; user and note it down for use later.<\/p>\n<p style=\"text-align: justify;\">Now we install the engine of our communication server: <strong>jabberd2<\/strong>&#8230;<\/p>\n<pre style=\"text-align: justify;\">sudo aptitude install jabberd2<\/pre>\n<p style=\"text-align: justify;\">Once installed we may as well stop the services since they&#8217;re not configured properly yet.<\/p>\n<pre style=\"text-align: justify;\">sudo \/etc\/init.d\/jabberd2 stop<\/pre>\n<h3 style=\"text-align: justify;\">Configuring MySQL<\/h3>\n<p style=\"text-align: justify;\">The <strong>jabberd2<\/strong> package has a script to do all the setup work for you.<\/p>\n<pre style=\"text-align: justify;\">sudo gzip -d \/usr\/share\/doc\/jabberd2\/db-setup.mysql.gz<\/pre>\n<p style=\"text-align: justify;\">Log into MySQL as the &#8220;<strong>root<\/strong>&#8221; user and execute the script.<\/p>\n<pre style=\"text-align: justify;\">mysql -u root -p\r\n\r\n<span style=\"color: #0000ff;\">mysql&gt;<strong>SOURCE<\/strong> \/usr\/share\/doc\/jabberd2\/db-setup.mysql<\/span>\r\n<span style=\"color: #0000ff;\">mysql&gt;<strong>GRANT<\/strong> select,insert,delete,update <strong>ON<\/strong> jabberd2.* to jabberd2@localhost <strong>IDENTIFIED<\/strong> by '<span style=\"color: #ff0000;\"><em><strong>password<\/strong><\/em><\/span>';<\/span>\r\n<span style=\"color: #0000ff;\">mysql&gt;<strong>quit<\/strong><\/span><\/pre>\n<p style=\"text-align: justify;\">Replace the <em>password<\/em> above with one of your own choice.<\/p>\n<h3 style=\"text-align: justify;\">Configuring jabberd2<\/h3>\n<p style=\"text-align: justify;\">The <strong>sm.xml<\/strong> file configures the session manager component of <strong>jabberd2<\/strong>. The session manager acts as a layer between the router and the externally available components. We need to configure a few settings like id, and database connection details.<\/p>\n<pre style=\"text-align: justify;\">sudo vi \/etc\/jabberd2\/sm.xml<\/pre>\n<p style=\"text-align: justify;\">Change\/update the following tags:<\/p>\n<pre style=\"text-align: justify;\"><span style=\"color: #339966;\">&lt;id&gt;<em><strong>your.domain.com<\/strong><\/em>&lt;\/id&gt;<\/span>\r\n<span style=\"color: #339966;\">&lt;driver&gt;<strong>mysql<\/strong>&lt;\/driver&gt;<\/span>\r\n<span style=\"color: #339966;\">&lt;user&gt;<em><strong>jabberd2<\/strong><\/em>&lt;\/user&gt;<\/span>\r\n<span style=\"color: #339966;\">&lt;pass&gt;<em><strong>password<\/strong><\/em>&lt;\/pass&gt;<\/span><\/pre>\n<p style=\"text-align: justify;\">Now we edit the <strong>c2s.xml<\/strong> file. This configures the client-to-server component of the <strong>jabberd2<\/strong> server. The <strong>c2s<\/strong> component handles communications with Jabber clients, and the settings in <strong>c2s.xml<\/strong> are primarily concerned with client communication.<\/p>\n<p style=\"text-align: justify;\">IT&#8217;S DESCISION TIME: <strong>Do you want to have encrypted connections<\/strong>? Your choice effects the settings in the first part of the <strong>c2s.xml<\/strong> file.<\/p>\n<h4 style=\"text-align: justify;\">YES, I would like encrypted connections&#8230;<\/h4>\n<p style=\"text-align: justify;\">The first step of this process is to create either a self-signed certificate or obtain one from a certificate authority.<\/p>\n<p style=\"text-align: justify;\">Once you&#8217;ve created your certificate, you can copy it into <span style=\"color: #339966;\"><strong>\/etc\/jabberd2\/<\/strong><em>your.domain.com<\/em><strong>.pem<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">Now we edit the <strong>c2s.xml<\/strong> file.<\/p>\n<pre style=\"text-align: justify;\">sudo vi \/etc\/jabberd2\/c2s.xml<\/pre>\n<p style=\"text-align: justify;\">part way down add\/update the following lines<\/p>\n<pre style=\"text-align: justify;\"><span style=\"color: #339966;\">&lt;id <strong>register-enable='true'<\/strong> pemfile='<strong>\/etc\/jabberd2\/<em>your.domain.com<\/em>.pem<\/strong>'&gt;<\/span>\r\n<span style=\"color: #339966;\">    <em><strong>your.domain.com<\/strong><\/em><\/span>\r\n<span style=\"color: #339966;\">&lt;\/id&gt;<\/span><\/pre>\n<p style=\"text-align: justify;\">This setting will allow users to be <strong>automatically created<\/strong>, and will use the defined certificate for encryption.<\/p>\n<h4 style=\"text-align: justify;\">NO, I don&#8217;t want encrypted connections&#8230;<\/h4>\n<pre style=\"text-align: justify;\">sudo vi \/etc\/jabberd2\/c2s.xml<\/pre>\n<p style=\"text-align: justify;\">part way down add\/update the following lines<\/p>\n<pre style=\"text-align: justify;\"><span style=\"color: #339966;\">&lt;id <strong>register-enable='true'<\/strong>&gt;<em><strong>your.domain.com<\/strong><\/em>&lt;\/id&gt;<\/span><\/pre>\n<h4 style=\"text-align: justify;\">Other changes regardless of connection type<\/h4>\n<p style=\"text-align: justify;\">Continue editing the <strong>c2s.xml<\/strong> file<\/p>\n<pre style=\"text-align: justify;\"><span style=\"color: #339966;\">&lt;module&gt;<strong>mysql<\/strong>&lt;\/module&gt;<\/span>\r\n\r\n<span style=\"color: #339966;\">&lt;user&gt;<strong>jabberd2<\/strong>&lt;\/user&gt;<\/span>\r\n<span style=\"color: #339966;\">&lt;pass&gt;<span style=\"color: #ff0000;\"><em><strong>password<\/strong><\/em><\/span>&lt;\/pass&gt;<\/span><\/pre>\n<p style=\"text-align: justify;\">By default, <strong>jabberd2<\/strong> looks for the MySQL sock in the <strong>\/tmp directory<\/strong>. We can create a link to the actual MySQL sock file in <strong>\/var\/run\/mysqld<\/strong>, but the &#8220;<strong>tmp<\/strong>&#8221; directory is emptied during each reboot. The easy fix for me was to alter the jabberd2 boot script so the symbolic link was created as jabberd2 was started.<\/p>\n<pre style=\"text-align: justify;\">sudo vi \/etc\/init.d\/jabberd2<\/pre>\n<p style=\"text-align: justify;\">add this line near the top with the other variable declarations<\/p>\n<pre style=\"text-align: justify;\"><span style=\"color: #339966;\">LINK2MYSQLSOCK=\"\/tmp\/mysql.sock\"<\/span><\/pre>\n<p style=\"text-align: justify;\">then just before the section that executes the &#8216;<strong>start<\/strong>&#8216; options add&#8230;<\/p>\n<pre style=\"text-align: justify;\"><span style=\"color: #339966;\">if [ ! -e \"${LINK2MYSQLSOCK}\" ]; then\r\n    echo -n \"Recreating Jabber's lost MySQL socket link...\\n\"\r\n    ln -s \/var\/run\/mysqld\/mysqld.sock \/tmp\/mysql.sock\r\nfi<\/span><\/pre>\n<p style=\"text-align: justify;\">This first checks to see if the sock file is there, and if it&#8217;s not creates the link to the right place for you!<\/p>\n<p style=\"text-align: justify;\">Now start the Jabber server&#8230;<\/p>\n<pre style=\"text-align: justify;\">sudo \/etc\/init.d\/jabberd2 start<\/pre>\n<p style=\"text-align: justify;\">and if we&#8217;ve done everything right, the server should be running ready for clients to connect to.<\/p>\n<h2>The client<\/h2>\n<p style=\"text-align: justify;\">There are a number of clients to choose from regardless of what platform your using. For a list of clients vs. platform you can visit <a href=\"http:\/\/xmpp.org\/xmpp-software\/clients\/\">http:\/\/xmpp.org\/xmpp-software\/clients\/<\/a> and work your way through the list to select one based on your own criteria.<\/p>\n<p style=\"text-align: justify;\">I had the best results with <a href=\"http:\/\/www.miranda-im.org\/\">Miranda<\/a>, <a href=\"http:\/\/pidgin.im\/\">Pidgin<\/a>, <a href=\"http:\/\/oneteam.im\/\">OneTeam<\/a>, <a href=\"http:\/\/live.gnome.org\/Empathy\">Empathy<\/a> (on Linux), <a href=\"http:\/\/www.apple.com\/macosx\/features\/ichat.html\">iChat<\/a> (on Mac OSX), and <a href=\"http:\/\/www.citron-im.com\/\">Citron<\/a>, finally settling for Pidgin to rollout with our organisation on Windows PCs. It was as much about the look and feel as it was about it actually working &#8211; in an ideal world I would have liked a Windows version of &#8220;iChat&#8221; because i love the look and feel as well as the chat bubbles.<\/p>\n<h3 style=\"text-align: justify;\">A note on &#8220;Resource names&#8221;<\/h3>\n<p style=\"text-align: justify;\">In Jabber you are able to log in several client programs simultaneously. You don&#8217;t need to have different Jabber accounts for different locations (e.g. work and home). You can chat in one location, then go to another, log in again with the same <strong>JID<\/strong> and the previous Jabber client will not go offline.<\/p>\n<p style=\"text-align: justify;\">This is because Jabber has a thing called &#8220;resources&#8221;. When you log in, you are usually asked for for the &#8220;Resource Name&#8221;. Some programs like to use their program names as the resource name (e.g. &#8220;iChat&#8221; or &#8220;Miranda&#8221;).<\/p>\n<p style=\"text-align: justify;\">For more information you can visit <a href=\"http:\/\/wiki.xmpp.org\/web\/Jabber_Resources\">here<\/a>.<\/p>\n<h2>Backing up data<\/h2>\n<p style=\"text-align: justify;\">It&#8217;s probably a wise decision to back up the data stored in the MySQL database so that it can be restored if you have to rebuild the server.<\/p>\n<p style=\"text-align: justify;\">For my particular setup, I have a <strong>cron<\/strong> script which dumps the schema and data and Bacula archives it as part of daily site-wide unattended backup procedure.<\/p>\n<p style=\"text-align: justify;\">Fundamentally the steps can be performed manually or via a script. Here&#8217;s what I did.<\/p>\n<pre>sudo mkdir \/var\/spool\/mysql\r\nsudo vi \/var\/lib\/mysql\/jabberd2-backup-db\r\nmysqldump -u root -p<em>password<\/em> -d jabberd2 &gt; \/var\/spool\/mysql\/schema.sql\r\nmysqldump -u root -p<em>password<\/em> -t jabberd2 &gt; \/var\/spool\/mysql\/data.sql\r\nsudo chmod +x \/var\/lib\/mysql\/jabberd2-backup-db<\/pre>\n<p style=\"text-align: justify;\">Now add it to cron, so it can be automated daily (in this case at 01:30 each day)&#8230;<\/p>\n<pre>sudo vi \/etc\/crontab\r\n\r\n<span style=\"color: #339966;\">30 1    * * *   root    \/var\/lib\/mysql\/jabberd2-backup-db<\/span><\/pre>\n<p style=\"text-align: justify;\">and restart cron<\/p>\n<pre style=\"text-align: justify;\">sudo service cron restart<\/pre>\n<div>\n<p style=\"text-align: justify;\">These could also just be entered as manual commands individually&#8230;<\/p>\n<pre>sudo mysqldump -u root -p<em>password<\/em> -d jabberd2 &gt; \/var\/spool\/mysql\/schema.sql\r\nsudo mysqldump -u root -p<em>password<\/em> -t jabberd2 &gt; \/var\/spool\/mysql\/data.sql<\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Setting up an XMPP server &#8220;XMPP by any other name would&#8230;&#8221; We recently had a chat (pun not intended) amongst the team to discuss some of the ways we could cut costs during these financially challenged times. One area identified was around inter-office calling charges. We have three stores: one in Onehunga (local), one in&#8230;  <a class=\"excerpt-read-more\" href=\"https:\/\/templesoft.co.nz\/journal\/?p=91\" title=\"Read Building a XMPP (Jabber) server.\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[78,75,34,22,77,76,33,74],"class_list":["post-91","post","type-post","status-publish","format-standard","hentry","category-technical-resource","tag-c2s-xml","tag-jabber","tag-multiverse","tag-mysql","tag-sm-xml","tag-sources-list","tag-universe","tag-xmpp"],"_links":{"self":[{"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=\/wp\/v2\/posts\/91","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=91"}],"version-history":[{"count":8,"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=\/wp\/v2\/posts\/91\/revisions"}],"predecessor-version":[{"id":172,"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=\/wp\/v2\/posts\/91\/revisions\/172"}],"wp:attachment":[{"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=91"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=91"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/templesoft.co.nz\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=91"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}