Setting ejjaberd on Debian Jessie

Setting ejjaberd on Debian Jessie

Hi everybody!
In the last few weeks I've been immersed in, paradoxically, Debian server setups, but not only at work, but also as part of some funny classes at Intitut Obert de Catalunya that deal about Internet Services.
Among several typical examples and exercices, there was a one that, sincerely, was a little bit challenging because I found documentation pretty much outdated (and probably because I'm getting also a little bit outdated :-p)... ejabberd

So, after putting all pieces to together and having fun playing with pidgin, I decided that that would be a nice matter to post about... so, here we go!

Setting the naming services.

XMPP - ejabberd works over domains much as mailing does, but, having not the luxury of things like MX RECORDS, there is where SRV records do the job.
This, of course means that we do have to get our domain up and running, and our server/clients well configured to work on it.
So, for that reason, I'll briefly introduce for the shake of the example my test domain pixapins.lan

As usual, first we setup the hostname

From jessie onwards, we do use hostnamectl command, like so:

hostnamectl set-hostname jabber

 

Now hostname direct resolving

Yet again, /etc/hosts comes into play
The following is the looking of Jessie's default hosts file modified for the example. Here, note my domain associated network subnet was 10.0.200.0/24, being the servers IP address 10.0.200.1

127.0.0.1       localhost.localdomain localhost
10.0.200.1      jabber.pixapins.lan   jabber

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

 

Setting up bind9

Things go hotter now... we needed to set up a fully working Domain Name Service, but... that's a piece of cake!!!
Installing bind9 DNS server and common CLI utilities is as easy as:

apt-get install bind9 dnsutils

 
Then, we do configure, our server at /etc/bind/named.conf.options
Note that I'm setting google DNS public servers (8.8.8.8 and 8.8.4.4) as forwarders, you may change this to your ISP ones or whathever... Out of comments, the file should have a looking like this:

options {
        directory "/var/cache/bind";

       forwarders {
                8.8.8.8;
                8.8.4.4;
        };

        
        dnssec-validation no;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

        allow-query-cache {any; };

        recursion yes;
        allow-recursion { any; };

};

 
Next step is to declare the DNS name zone pixapins.lan and the reverse subnet zone for 10.0.200.0/24.
We need to declare both zones, and the their related records files at /etc/bind/named.conf.local... Among any other zones, the following would have to be added there:

zone "pixapins.lan"{
                type master;
                file "/etc/bind/db.pixapins.lan";
                allow-query {127.0.0.1; 10.0.200.0/24;};
};

zone "200.0.10.in-addr.arpa"{
                type master;
                file "/etc/bind/db.10.0.200.in-addr.arpa";
                allow-query {127.0.0.1; 10.0.200.0/24;};
};

 
And then, we must ensure to create, and fill with correct DNS zone records both /etc/bind/db.pixapins.lan and /etc/bind/db.10.0.200.in-addr.arpa files.

The /etc/bind/db.pixapins.lan zone file has the very basic set of records for the typical domain: SOA, NS, MX and A records, along with xmpp/jabber SRV records.
Note how SRV records point to existing A record...

;
;Zone configuration file for direct resolutions at pixapins.lan.
;
$TTL 1D
pixapins.lan.   IN SOA jabber.pixapins.lan. root.pixapins.lan. (
                2016091810                      ;Serial
                3H                              ;Refresh
                2H                              ;Retry
                4D                              ;Expire
                3D      )                       ;Negative Cache TTL
;

;Nameservers section
pixapins.lan.           IN      NS              jabber.pixapins.lan.

;Mailservers section
pixapins.lan.           IN      MX      1       mail.pixapins.lan.

;Hosts section
jabber  IN      A               10.0.200.1
mail    IN      A               10.0.200.1

;SRV section
_jabber._tcp.pixapins.lan.              IN SRV 5 0 5222 jabber
_xmpp-server._tcp.pixapins.lan. IN SRV 5 0 5269 jabber
_xmpp-client._tcp.pixapins.lan. IN SRV 5 0 5222 jabber

 
The file /etc/bind/db.10.0.200.in-addr.arpa looks like this

;
;Zone configuration file for reverse resolutions at pixapins.lan.
;
$TTL 1D
200.0.10.in-addr.arpa.  IN SOA jabber.pixapins.lan. root.pixapins.lan. (
                2016091801                      ;Serial
                3H                              ;Refresh
                2H                              ;Retry
                4D                              ;Expire
                3D      )                       ;Negative Cache TTL
;

;Nameservers section
200.0.10.in-addr.arpa.  IN      NS              jabber.pixapins.lan.

;PTRs section
1                       IN      PTR             jabber.pixapins.lan.
1                       IN      PTR             mail.pixapins.lan.

 
And that's all about DNS settings...
It is time to restart our DNS server to ensure it reads our config changes:

service bind9 restart

 

Reconfigure name resolving

Now that our server is a fully funtional DNS server, we will ask him to use itself as its DNS server instead of the ones provided by our ISP connection, this means modifying /etc/resolv.conf

domain pixapins.lan
search pixapins.lan
nameserver 127.0.0.1

 

Testing SRV records to work

Before going further, it is a good idea to check that our SRV records and the domain in general is working.
Issue the following command:

dig _jabber._tcp.pixapins.lan srv

 
Here's a console example of how it may look if everything goes well:

root@jabber:~# dig _jabber._tcp.pixapins.lan srv

; <<>> DiG 9.9.5-9+deb8u8-Debian <<>> _jabber._tcp.pixapins.lan srv
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17005
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_jabber._tcp.pixapins.lan.             IN      SRV

;; ANSWER SECTION:
_jabber._tcp.pixapins.lan.      86400   IN      SRV     5 0 5222 jabber.pixapins.lan.

;; AUTHORITY SECTION:
pixapins.lan.           86400   IN      NS      jabber.pixapins.lan.

;; ADDITIONAL SECTION:
jabber.pixapins.lan. 86400 IN   A       10.0.200.1

;; Query time: 3 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Nov 10 20:51:01 CET 2016
;; MSG SIZE  rcvd: 130

 
So, we got bind9 up and running!

Setting XMPP ejjaberd server

One the most shocking things I faced was to discover that the classic /etc/ejabberd/ejabberd.cfg DOES NO LONGER EXIST!!!
Apparently, since it is a monolithic, very long config file, it has been decided by project developers to migrate its format to .yml file format...
The decision isn't probably fresh news, since, as of Jessie release, the change is there, so now, config file is /etc/ejabberd/ejabberd.yml.
I'm a .json format enthusiast, old school .xml is pretty good for me too... but .yml is still somehow too much to me :-P

So, since the config file is quite long, here are the relevant excerpts to look into, and modify. Remember that, everything here onwards takes place somewhere at /etc/ejabberd/ejabberd.yml.
Changed parts are shown in order of aparition:

First section:

###   ================
###   SERVED HOSTNAMES

##
## hosts: Domains served by ejabberd.
## You can define one or several, for example:
## hosts:
##   - "example.net"
##   - "example.com"
##   - "example.org"
##
hosts:
  - "localhost"
  - "pixapins.lan"

 
Second one:

###   ==============
###   AUTHENTICATION

##
## auth_method: Method used to authenticate the users.
## The default method is the internal.
## If you want to use a different method,
## comment this line and enable the correct ones.
##
auth_method: internal

##
## Store the plain passwords or hashed for SCRAM:
## auth_password_format: plain
auth_password_format: scram
##
## Define the FQDN if ejabberd doesn't detect it:
fqdn: "jabber.pixapins.lan"

 
Third one:

###.   ====================
###'   ACCESS CONTROL LISTS
acl:
  ##
  ## The 'admin' ACL grants administrative privileges to XMPP accounts.
  ## You can put here as many accounts as you want.
  ##
  admin:
     user:
         - "admin": "localhost"
         - "admin": "pixapins.lan"

 
That's all changes needed for a very very basic functional domain xmpp service... so, restart the service as usual:

service ejabberd restart

 

Adding user jabber domain accounts

Now comes the funny part... try adding a pair of test users!
If everything is good, you can add users and specify you want them to be part of your domain.
ejabberd comes with a set of CLI management command tools provided with the installation. We will use the ejabberdctl register command.
Syntax is as follows:

ejabberdctl register USERNAME DOMAIN PASSWORD

 
Here's an example on the console:

root@jabber:~# ejabberdctl register testuser1 pixapins.lan secretpassword1
User testuser1@pixapins.lan successfully registered

 
And that's all folks...

Testing it works!

To test it all works, we need to add a pair of user accounts, then register them as accounts on your IM client, and create cross contacts between them... it may sound tricky, but can be easily explained:

Let's say you create testuser1@pixapins.lan and testuser2@pixapins.lan user accounts at the server terminal.
Ok, then add both accounts at your IM client, it should work automagically if your client has connectivity to the server on the same subnet... Accept the certificate, and go on!
Now comes the funny part...
Add a buddy/contact, indicating testuser2 as user name and pixapins.lan as domain, and associate it to testuser1@pixapins.lan account.
Now, inversely, Add a buddy/contact, indicating testuser1 as user name and pixapins.lan as domain, and associate it to testuser2@pixapins.lan account.
Now, you'll have two contacts of your own server at your IM client!!!
Try to start a conversation on either of them... if you chat to contact testuser1@pixapins.lan you'll do from its associated source account testuser2@pixapins.lan, and vice-versa, so, you can chat from one chat to another... weird!