This how to is a great deal simpler than I remember but it’s easy to miss a trick.
$ sudo apt-get install erlang ejabberd
I thought it was all kosher. Except I couldn’t add users due to ‘undefined RPC endpoint for localhost’. Thinking that these should have been automagically configured I tried to install from source and from processone packages but none were really good enough to easily repeat.
And then i remembered dkpg-reconfigure. Once you’ve installed ejabberd, run this command to configure it at the commandline
$ sudo dpkg-reconfigure ejabberd
1. Please enter the hostname of your Jabber server (in lowercase)
This should be the equivalent to ‘hostname -s’ (e.g. if your jabber server is chat.myhost.com, the host should be chat)
2. The username of an admin account for ejabberd
choose a useful name e.g. admin
Then choose a super complex password
3. The proggie should then gracefully exit to your cli
Now you are ready to administer the server. Open a browser and navigate to http://chat.myhost.com:5280 and you can start configuration. The only oddity i found was that to login you need username+host so if you followed the above example your username would be ‘admin@chat’ and your password as set above.
There isn’t a great deal to do here atm, so just check the access rules over. below are the defaults, the only item of note is ensuring that register is deny,all else any tom, dick or harry could jump on your boxen.
Adding a user
You can, but shouldn’t, use the admin user you created above for chatting etc. Prob better to add a normal user. Switch to cli and use the following command to add a user. You either need to be root, use sudo, or switch to the user ejabberd (‘su – ejabberd’).
$ ejabberdctl register steev chat complex_password
This will register the user ‘steev’ to the ‘chat’ node with ‘complex_password’ as the password.
The point of this exercise is to integrate ejabberd into the existing authentication and authorisation structure we have in place. We have a server ‘maureen’ who provides directory services to the network via Openldap. The LDAP database holds user data for the network and most apps already use this as their authentication database. By enabling ejabberd to use the ldap server we enable users to have one set of credentials for all their apps.
Ejabberd has built in support for LDAP, and in retrospect its straightforward (gotchas tied me up for a few hours). As usual there are a few gotchas tho:
1. LDAP is mounted as read only therefore users have to be added to LDAP using a mechanism other than XMPP.
2. If the user passwords are stored hashed (MD5, SHA etc) in the DIT then ejabberd will complain about failed authentication when in fact it should complain that it cant handle hashed passwords. What this really means is that ejabberd cant handle hashed passwords and so you MUST store your passwords in cleartext in the LDAP DIT if you’re using the built in LDAP interface. See below for more details.
3. If you have created local users (e.g. i created a test local user using: $ ejabberdctl register steev chat password ) and then attempt to authenticate the same user against the LDAP database you get a 409 duplicate username (so delete the users from the admin interface at http://chat:5280/admin)
The rest of it is fairly plain sailing. Here is a copy of my working config
This is a pretty wide open config tho and will allow anything with a uid to be authenticated, the server to server (ejabberd to ldap) is in clear text and therefore so is your ‘complex_password’.
The first step is to be a bit more selective as to where you pull your uids from. I want to let everybody with a unix account have an ejabberd account. All their credentials are already stored in LDAP so all that is necessary is to configure the ldap_filer to only allow credentials that are part of a shadowAccount objectClass. This is already in the cfg file but needs uncommenting
The second step should be to one way hash the password database but i don’t seem to be able to find an option for this. Indeed after scouring the internetwebs it turns out that this isn’t possible using the native LDAP connector – Blimey… with a capital WTF? I do wonder how difficult it could be to write something that can handle MD5 and SHA hashing (its better than nowt – kerberos is hard but MD5 aint) but i don’t think i can seriously recommend storing passwords in clear text in a database. Anywhere. There is a statement here http://www.ejabberd.im/plaintext-passwords-db basically suggesting transport layer security and clear text passwords is appropriate. It will be impossible to achieve PCI compliance or adhere to any industry best practice without implementing a one way hash (preferably with a strong salt) for storing user passwords.
Its certainly left a bad taste in my mouth as i cant think of any reasons (except commercial) for crippling ejabberd installations.
I’m either gonna have to learn Erlang (I tried before for Rabbit MQ, but it was horrible…or i wasn’t concentrating. Doesn’t look insurmountable..in fact Erlang looks awesome…) or perhaps write a script to do some authentication in middleware which seems like the most expedient option but i’m quite annoyed about having to hobble an erlang app with something like a python script. Lets hope we don’t get more than a few thousand users (which we wont, but you get my point). Why hobble a massively scalable system built on a modern language with crappy middleware?
The third step should be to enumerate your system from the outside and identify any ports that may not be needed. e.g. if you have redundant modules opening ports – remove the modules or firewall the system. But for godsakes secure that database!
I intend to work on some kind of middleware for the (lol…I cant believe this – ITS 2010!!!) clear text passwords…or some kind of solution. But on a more positive note this software fkn rocks. So performant and reliable. Truly great. I intend to try and get private SIP going….lets see eh?