Why
Having a secure chat server of your own is useful for companies, where internal discussion must never leave the corporate network, and very paranoid people, who think the authorities are sniffing their packets. Jabber is the most versatile protocol out there, having lots of features I probably won’t even use. It is possible to execute commands on the server, communicate with googletalk and other XMPP users
When I needed to decide what server software to use, I looked at popularity-contest lists for Debian. Packages “ejabberd” and “jabber” were at the top, of which ejabberd is significantly larger and written in Erlang. I haven’t previously ever used software written in Erlang or seen Erlang code. It seemed to have PAM configuration included, and since that was what I most of all wanted, to authenticate users with local unix account database (/etc/shadow), I chose ejabberd. The web chat called jwchat followed since it also was in apt sources tree and there were some pages about integrating it with ejabberd.
How
Ejabberd and a web client, jwclient, are included in apt:
sudo apt-get install ejabberd jwchat
Modifications to /etc/ejabberd/ejabberd.cfg:
%% Admin user
{acl, admin, {user, "me", "cloudspike.com"}}.
%% Hostname
{hosts, ["cloudspike.com"]}.
%% Change starttls to starttls_required in the line below
{5222, ejabberd_c2s, [ {access, c2s}, {shaper, c2s_shaper},
{max_stanza_size, 65536}, starttls_required, {certfile, "/etc/ejabberd/ejabberd.pem"} ]},
%% http_bind instead of http_poll
{5280, ejabberd_http, [ http_bind, web_admin ]}
%% Comment following line
%%{auth_method, internal}.
%% Uncomment this instead
{auth_method, pam}.
{pam_service, "ejabberd"}.
%% Add the following line in the list under "{modules"
{mod_http_bind, []},
Create /etc/pam.d/ejabberd:
#%PAM-1.0
auth sufficient pam_unix.so likeauth nullok nodelay
account sufficient pam_unix.so
Give “epam” sufficient permissions:
chown root:ejabberd /usr/lib/ejabberd/priv/bin/epam
chmod 4750 /usr/lib/ejabberd/priv/bin/epam
Switch the included certificate to use correct “Common Name”. If you in the e-mail field use the e-mail that the contact person for the domain name has, you get cool points, even though it’s just a self-signed certificate. Let’s do things properly:
sudo su
cd /etc/ejabberd/
mv ejabberd.pem ejabberd.pem.dist
openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout privkey.pem -out ejabberd.pem
Country Name (2 letter code) [AU]:SE
State or Province Name (full name) [Some-State]:Stockholms län
Locality Name (eg, city) []:Stockholm
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Cloudspike
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:cloudspike.com
Email Address []:admin@cloudspike.com
openssl rsa -in privkey.pem -out privkey.pem
cat privkey.pem >> ejabberd.pem
rm privkey.pem; chmod 640 ejabberd.pem; chown :ejabberd ejabberd.pem
Restart ejabberd by invoking stop and then start. The restart command in Ubuntu is too quick for the slow Erlang language and breaks the service. Processes “epmd” and “beam” need to be killed before ejabberd can be started again after such a botch.
sudo /etc/init.d/ejabberd stop
sudo /etc/init.d/ejabberd start
You can access the web administration interface at http://hostname:5280/admin
Edit /etc/jwchat/config.js:
var SITENAME = "cloudspike.com";
The configuration at /etc/apache2/sites-available/jwchat is quite broken. It doesn’t work out of the box, and it looks suspiciously similar to an unsecured proxy. This is how it should be, if mod_ssl is loaded in Apache:
<VirtualHost *:443>
ServerName http://jabber.cloudspike.com
DocumentRoot /usr/share/jwchat/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /usr/share/jwchat/www>
Options Indexes Multiviews FollowSymLinks
AllowOverride None
Order allow,deny
allow from all
</Directory>
AddDefaultCharset UTF-8
ProxyPass /http-bind/ http://cloudspike.com:5280/http-bind/
ProxyPassReverse /http-bind/ http://cloudspike.com:5280/http-bind/
<Proxy *>
Allow from all
</Proxy>
CustomLog /var/log/apache2/jwchat_access.log combined
LogLevel warn
SSLEngine on
SSLCertificateFile /etc/ejabberd/ejabberd.pem
SSLOptions +StdEnvVars
BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
</VirtualHost>
Don’t forget to reload apache with apache2ctl graceful.
Changing hostname
Erlang is quite a strange language, where software is running on nodes which can communicate with each other through built-in processes. That means that it’s easy to build software which can run on clusters, and ejabberd is no exception. What that also means is that it’s really anal about what host it runs on, and you can’t change your hostname willy-nilly. Furthermore, if you mess ejabberd up with a hostname change, the start script for it in init.d will not report any failure, and ejabberd will quit silently without writing any logs, which is a pain to debug.
If you haven’t messed your ejabberd up and want to change the hostname in its configuration:
ejabberdctl backup /tmp/ejabberd-oldhost.backup
# Change hostname here inbetween
ejabberdctl restore /tmp/ejabberd-oldhost.backup
If you have messed it up, you’ll have to completely wipe the /var/lib/ejabberd directory. This will remove all accounts if you use internal authentication (the Mnesia database for Erlang). If you use PAM authentication, your accounts are not affected, but you still lose any configuration made through the web interface.
If you don’t know what is wrong, and ejabberd doesn’t want to start after you’ve killed the “beam” and “epam” processes, try su ejabberd -c "ejabberdctl live" and google from there
Extra Security
It’s probably not so good to have http-bind and the administration interface on the default ports. If you change the http-bind port, don’t forget to change it as well in the proxy settings of jwchat’s apache configuration file.
If you don’t want to talk to other servers, you should comment out s2s functionality in the configuration file to avoid unnecessary traffic.
Inspired by
ejabberd 2.0.5 Installation and Operation Guide
XMPP Standards Foundation - Nice list of server and client software. For the record, I use the Gajim client.