In this example we will be upgrading from an older instance of the ejabberd-15.04 XMPP server to the current latest version ejabberd-16.06. Operating system specific packages such as RPM and DEB files were not provided until ejabberd-15.06, so our existing instance was not installed with the RPM file but instead from the binary file, meaning there is no existing ejabberd RPM installed for us to simply upgrade.
While this upgrade is taking place on the same server, these steps can also be used to perform a migration from one server to another with a fresh installation of ejabberd, as the new version will install to a new directory.
If you’re migrating to a new server, when ever we advise to copy a file, instead use something like scp to copy from the local server to the new remote server that you are moving to.
The existing instance of ejabberd-15.04 is currently running from /opt/ejabberd-15.04.
First download the package, as we’re working with a CentOS 7 server here we will get the “Linux x86 64-bits RPM” package file and install it with yum.
yum install ejabberd-16.06-0.x86_64.rpm -y
This has installed to /opt/ejabberd-16.06, however we now need to migrate our existing data from the /opt/ejabberd-15.04 directory.
Migrate The Configuration Files
There are a couple of files that need to be copied over, namely the ejabberd.yml configuration and the server.pem files within the conf directory.
Let’s start with the server.pem file, this contains the existing private key and certificate that are in use.
cp /opt/ejabberd-15.04/conf/server.pem /opt/ejabberd-16.06/conf/server.pem
This is fine to do, as the private key and certificate within the new server.pem are simply a default with the common name of “ejabberd Community Server Test Certificate”. The existing file is copied over so that no security warnings are given to clients when they reconnect to our newly upgraded server.
Next we want to migrate the /opt/ejabberd-15.04/conf/ejabberd.yml configuration file to /opt/ejabberd-16.06/conf/ejabberd.yml, however we cannot simply overwrite the new file like we did before. This is because the newer versions of ejabberd contain new configuration options which did not exist in the older versions of the software, so we therefore need to go through the configuration file and apply various configuration changes to the newer file in the 16.06 version as required.
Some specific configuration elements that I manually copied over included the “hosts:”, “listen:” and “acl:” sections.
Rather than search the whole file manually, you could also make use of the ‘diff’ command to see the differences between the two files, however in my case this was over 400 lines and not all that useful.
diff /opt/ejabberd-15.04/conf/ejabberd.yml /opt/ejabberd-16.06/conf/ejabberd.yml
Migrate The Database
Next we’ll take a backup of the ejabberd database. Note that if you simply try to copy the files within the /opt/ejabberd-15.04/database directory to the new directory it will not work properly, the database must be exported and imported with the ejabberctl tool.
/opt/ejabberd-15.04/bin/ejabberdctl backup ejabberd.backup
It’s important to note that ejabberd needs to be running for this to work properly, otherwise you’ll get the following error message, which simply means that the ejabberd server is not available.
Failed RPC connection to the node [email protected]: nodedown
The backup should have been created in the database directory, at /opt/ejabberd-15.04/database/[email protected]/ejabberd.backup
Confirm that the ejabberd.backup file exists as expected, and then stop the old service from running.
Copy the ejabberd.backup file to the database directory of the new version, /opt/ejabberd-16.06/database/[email protected]/ in our instance.
cp /opt/ejabberd-15.04/database/[email protected]/ejabberd.backup /opt/ejabberd-16.06/database/[email protected]/
Before being able to perform the restore, we must start the new version of ejabberd.
Now the backup can be restored by running ejabberctl from the 16.06 installation.
/opt/ejabberd-16.06/bin/ejabberdctl restore ejabberd.backup
The files within the /opt/ejabberd-16.06/database/[email protected] directory should have the owner and group of ejabberd. This user was configured when we installed the RPM. Our ejabberd-15.04 version was actually running the whole server as the root user, which is very poor security practice. If there was a vulnerability in ejabberd-15.04 then an attacker could potentially gain access to root privileges.
chown -R ejabberd:ejabberd /opt/ejabberd-16.06/database/*
The migration should now be complete, at this point I’m not certain if everything will work properly as we did need to perform some changes after starting ejabberd, so just to be sure we perform a restart.
You should now perform a test connection with a client to the server and confirm that things are working as expected.
Once you have confirmed that everything is working correctly, it should be safe to remove the old installation, which is the /opt/ejabberd-15.04 directory in our example. While it’s not needed, it may be a good idea to maintain a backup of this content just to be safe.
Ejabberd Security Hardening
Based on the security recommendations for ejabberd, we perform some additional changes to increase security. The documentation notes that sensitive data is stored within the following files and should be restricted:
/opt/ejabberd-16.06/conf/ejabberd.yml – This file was set to 644 by default, allowing anyone to read the configuration.
/opt/ejabberd-16.06/logs/ejabberd.log – This file was set to 644 by default, allowing anyone to read detailed logs.
/opt/ejabberd-16.06/.erlang.cookie – This file was actaully already set to 400 by default which should be fine.
As our files are all owned by either the ejabberd or root user and group, we can restrict access by disabling access to other users, as this should not be needed.
chmod 640 /opt/ejabberd-16.06/conf/ejabberd.yml chmod 640 /opt/ejabberd-16.06/logs/ejabberd.log
As shown we have successfully migrated from an older version of ejabberd-15.04. This version was originally installed from the binary installer before RPM packages were provided to the current latest version of ejabberd-16.06. Hopefully upgrades should be easier going forward as the installation/updates are RPM based.
Even with RPM packages, this information should still be useful if you’re migrating an instance of ejabberd from one server to another, as you would be installing the ejabberd RPM fresh on the new server that you wish to migrate to.