How to Synchronise Android with Thunderbird.. without Relying on a Trusted Party!
It seems that there is some interest in synchronising a mobile phone with a calendar and an addressbook that are maintained on a PC. The most widely cited solution is to use Gmail, GCalendar - essentially handing all data to Google seems to be the preferred solution. In some cases (e.g., with business data involved) such a solution is not acceptable.
Searching further we find reports of users being happy with how their iPhone syncs well with their MacBook and also their iPad. This seems nice as all data stays in the hands of the user. Drawback of this solution is that this creates a lock-in situation leaving the use no choice over what hardware to buy and what OS to use. Again in a case with company-provided hardware we have no choice over the latter and probably cannot not implement this solution either.
We were convinced that using (mostly) open source software and some (hopefully) cheap hardware it is possible to convince an email client (thunderbird) to synchronise with a mobile phone (any android 2.1).
This is a report (and a manual) for people who consider setting
up their own system (or want to see what it would take). We spent a lot
of time searching for the right information and consequently we go for a
complete description on this page. This has the drawback that we repeat
certain information already given on other pages. We were most careful
in clearly indicating where the content comes from. We welcome feedback
and questions (email: patrik bla
bichsel@gmx bla net
, where you replace the bla
with a . ) if you get stuck using our instructions - clearly, we
cannot provide any guaratee that the instructions will work, neither we
can guarantee that we will respond to any request for information.
Harware Requirements
We don't need much but we do need:
- A server: we used an old laptop (IBM ThinkPad X40)
- A computer with an email client (thunderbird).
- A mobile phone running Android (preferrably version 2.1 or later)
We might use a new machine such as a Zotac ZBOX or a Mac mini as our server. If this is the case, we might have to update the drivers but we still need to go for the Ubuntu LTS release as Zentyal releases around LTS only.
Setup of the Server
We decided to install Ubuntu Server (32-bit edition/64-bit depending on the age of the hardware) and afterwards install Zentyal server to have a nice and tidy way of setting the main configuration.
Let's get started..
- Download Ubuntu server 10.04 LTS (required for Zentyal!)
- Install it.. (We choose to install OpenSSH because we want to manage the server using SSH later on. Maybe we choose other components (like Tomcat) that are not managed by Zentyal.)
- Following the instructions of the Zentyal
Installation guide we first add the repository containing Zentyal by
adding the following lines to
/etc/apt/sources.list
. To do so we open the file with our favourite editor (e.g., nano):sudo nano /etc/apt/sources.list
Then add the following lines at the bottom of the file.# Zentyal repository deb http://ppa.launchpad.net/zentyal/2.0/ubuntu lucid main # Zarafa (Groupware) repository deb http://archive.canonical.com/ubuntu lucid partner
- We need to add the key for the repositories by executing:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 10E239FF
- Finally we update, upgrade and reboot.
sudo apt-get update sudo apt-get upgrade sudo reboot
Configuration of Zentyal
We suggest the use of Zentyal as it makes several basic server configurations very easy to setup. For example, using Zentyal we can easily setup a CA and start issuing certificates (which we need for using SSL connections).
Let us start by installing the basic Zentyal packages together with the networking packages required for having configuring the server as our access point (AP). When installing the DHCP package there will be a number of other packages that Zentyal will install. One of them is the dyndns package, which will ask for several configuration settings. If your server is behind a router you can ignore these settings.
sudo apt-get install zentyal sudo reboot
During the installation we have to set the HTTPS port of the administration interface. We do not choose the standard HTTPS port (443) as we want to access the groupware on the standard HTTPS port. We stick for now with the default port (as changing it now did not work for us) and we'll change it later using the Web frontend.
If you only want to set up an access point, installing Zentyal
seems to be too much of an overhead. However if you want to synchronise
your android phone with thunderbird, then you will need the Zarafa
groupware later on. So we'll install Zarafa already. Assuming that your
server has the IP 192.168.0.2
we can connect
to:
https://192.168.0.2/
Using the Web frontend we install the Zarafa Gateway modules. In addition, we install the Zarafa groupware module, which can be found in
. We select and install the groupware (Zarafa) module as well as the DHCP module.There is not much that we change from the default configuration. One thing that we change is the port where the management console is listening. We go to
and set the port to 445 such that the Zarafa instance will be able to listen on the standard HTTPS port. From now on we have to connect to the Web frontend using:https://192.168.0.2:445/
Let us summarise some important configurations of Zentyal.
- Backup: Set the backup location to some remote host (it's duplicity, so everything is encrypted). A full backup with some basic settings takes about 350MB.
- Logging: Set the logging (purge logs, etc.) to appropriate values. The default behaviour is not to purge any log file.
- Events: Configure events warning from specific problems (e.g., high disk usage).
Setup of an Access Point (AP)
If we want to use the server as an access point, we have to configure the network correctly. The reason for doing so might be that you don't have a WiFi router and still want to connect the mobile phone to the Internet using a (free) WiFi connection.
One word about the network topology might be appropriate here. We
use two different networks, one for the wired infrastructure where the
router is the gateway (and the DHCP server), and another network for the
wireless infrastructure. Let us assume that the wired infrastructure
uses the network 192.168.0.0/24
with the
gateway having the address 192.168.0.1
. The
wireless AP uses IP 192.168.1.1
, with the
network 192.168.1.0/24
. The AP serves as DHCP
server and uses WPA-PSK to secure the wireless channel. Thus, the
configuration of the AP will look as follows:
- Method: Static
- IP: 192.168.1.1
- Netmask: 255.255.255.0
We now need to do the following:
- Forward IP packets between the wireless and wired networks (through the AP).
- Masquerade the traffic (from the AP to the wired infrastructure).
- Configure the AP (e.g., IP, DHCP, encryption).
Let's get started..
- We first enable the packet forwarding between the wireless and
wired network.
sudo nano /etc/sysctl.conf
Now we have to uncomment the following linenet.ipv4.ip_forward = 1
optionalOptionally we can also forward IPv6 packets by uncommenting:net.ipv6.conf.all.forwarding = 1
- Coming to enabling masquerading. We have the goal that neither
restarting the server nor restarting the firewall module will disables
masquerading. To attain this goal we follow the instructions from the Zentyal
developper page and enable a simple script that will run after the
firewall module is restarted. Let us edit the file
/etc/ebox/hooks/firewall.postservice
and add acustom rule.sudo nano /etc/ebox/hooks/firewall.postservice
We make it a script by adding the following lines.#add custom rules here iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
alternative setupFollowing the description from Ubuntu Documentation we can implement the IP forwarding and masquerading using the ufw rules. For completeness reasons we repeat the instructions here.
The rules files located in
/etc/ufw/*.rules
are a great place to add legacy iptables rules used without ufw, and rules that are more network gateway or bridge related.The rules are split into two different files, rules that should be executed before ufw command line rules, and rules that are executed after ufw command line rules.
- Firstly, packet forwarding needs to be enabled in ufw. We adjust two configuration files, in
/etc/default/ufw
we change theDEFAULT_FORWARD_POLICY
to"ACCEPT"
:sudo nano /etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
Then we edit/etc/ufw/sysctl.conf
and uncomment the forwarding of IPv4 packets:sudo nano /etc/ufw/sysctl.conf
net/ipv4/ip_forward=1
optionalSimilarly, for IPv6 forwarding we uncomment:net/ipv6/conf/default/forwarding=1
- Secondly, we will add rules to the
/etc/ufw/before.rules
file. The default rules only configure the filter table, and to enable masquerading we will configure a nat table. We add the following to the top of the file just after the header comments or at the bottom of the file (after theCOMMIT
for the filter):sudo nano /etc/ufw/before.rules
# nat Table rules *nat :POSTROUTING ACCEPT [0:0] # Forward traffic from eth1 through eth0. -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE # don't delete the 'COMMIT' line or these nat table rules won't be processed COMMIT
- Firstly, packet forwarding needs to be enabled in ufw. We adjust two configuration files, in
- Finally, we come to the IP configuration of the AP. You can
establish the configuration using the ifconfig,
iwconfig, wpa_supplicant,
etc. commands manually. As mentioned before, we will use the Zentyal
infrastructure to set the basic configuration. For the advanced
wireless settings we'll use hostapd (hostapd
documentation).
sudo apt-get install hostapd sudo /etc/init.d/hostapd stop
optionalSetting the configuration file of hostapd might not be extremely staightforward. Let us provide a short list of commands that help in detecting the hardware and the drivers associated with the hardware. You can skip this part if you just want to go along with the hope that our settings work on your machine too.lspci | grep net lspci -nnk | grep -i net -A2 iw list iwlist chan sudo iwlist scan lsmod dmesg
nl80211
driver. Let's start with the hostapd configuration to figure out if everything works. We'll edit the hostapd configuration file/etc/hostapd/hostapd.conf
:sudo nano /etc/hostapd/hostapd.conf
interface=wlan0 driver=nl80211 ssid=yourSSID hw_mode=b channel=3 max_num_sta=3 macaddr_acl=0 accept_mac_file=/etc/hostapd/hostapd.accept ap_max_inactivity=3000 wpa=1 wpa_passphrase=some secret that you will have to type when connecting to the network wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP CCMP wpa_group_rekey=600 wpa_strict_rekey=1 wpa_gmk_rekey=86400 wpa_ptk_rekey=600
alternative setupIf you use newer hardware with a 802.11n WiFi card you should rather use the following values:hw_mode=g channel=11 max_num_sta=3 macaddr_acl=1 accept_mac_file=/etc/hostapd/hostapd.accept ap_max_inactivity=3000 ieee80211n=1 ht_capab=? (use the commands from above to detect the right settings)
/etc/hostapd.accept
and add all the MAC addresses of the devices we allow. Then we can check if the configuration is correct an fire up hostapd.sudo nano /etc/hostapd.accept sudo hostapd /etc/hostapd/hostapd.conf
optionalIf you get any errors such as the description from our Zotac tutorial might help.192.168.0.2
you can connect with (remember that we have chosen a port different from the usual HTTPS port)https://192.168.0.2:445/
Using the GUI you can start the DHCP module. In addition, we have to adjust the configuration of the wireless interface. We can do this be navigating to . We set the method ofwlan0
to static and configure its IP to be192.168.1.1
. Note that you can adapt the choice of the networks used for both wired and wireless configuration. You can ignore themon.wlan0
interface (it is created by hostapd for monitoring purposes). Now your wireless should be accessible..
Before celebrating we have to make the hostapd deamon start on startup of the system. We can do this by changing uncommenting the appropriate lines in/etc/default/hostapd
.sudo nano /etc/default/hostapd
RUN_DEAMON="yes" DEAMON_CONF="/etc/hostapd/hostapd.conf" DEAMON_OPTS="-d"
Let's restart and enjoy the wireless access..sudo reboot
Setup of a CA
To allow for secure communication, we need to create a CA and then issue certificates. In addition we will have to import the CA-cetificate on the client side to make all certificates that we issue trustworthy.
Zentyal offers support when it comes to this process such that creating a CA is done with a few clicks. We have to do two things:
- Setup a certification authority (CA)
- Create a certificate for
thunderbird.android.dyndns.com
After we created the certificate we go to hacks to change the certificate for some module.
and set the certificate to be used to the one we just created. We use the certificate for all the services. Possibly we have to use the trick described underFinally, we have to download the certificates to the clients.
- Firstly, we import the certificates onto the Android phone. We can import elements using an application from the phone company or an SD card (if available).
- Secondly, import them into Thunderbird to make it accept them when needed. Note that when the certificate is added to the Thunderbird list of certificates, we might have to add exceptions for the ports 443, 993 and 8443 (assuming that we used the standard ports).
Setup of Zarafa
Note that you have to setup a CA and use the right certificates for the different modules. If we have done so, we allow secure access to the Zarafa Web frontend and configure Zentyal as follows:
- Web Server: Enable HTTPS access (use any port)
Synchronise the Addressbook
This is probably the most important task as we want to use the Thunderbird addressbook to initialise the addresses on the Android phone. During operation the synchronisation is a little less important as there are far fewer changes to the addressbook than to the calendar.
Unfortunately, we did not find an open source solution that allows to synchronise Zarafa with Thunderbird. The same situation is actually the case for synchronising Zarafa and Android. However, there is reasonably priced software that does the job. We will use:
- RoadSync to synchronise Zarafa with the Android phone, and
- Z-sync to synchronise Thunderbird with Zarafa
Let us have a look how we can make those guys synchronise our addresses. We proceed in three steps: (1) Setup the phone to sync with Zarafa, (2) setup the server side of the Z-Sync plugin, and (3) setup thunderbird to use Z-Sync.
-
Let us start with the Android synchronisation where we use the RoadSync application (we know, open source would be better.. but hey, this works at least!). As we want to have our server accessible from the road, we establish a dynamic DNS domain that we forward to the server. You might use www.dyndns.com or another service. Let us assume that we have reserved the domain
thunderbird.android.dyndns.com
.Before being able to connect to the server (actually the Zarafa groupware running on the server), we have to create a user. We navigate to
and create a user. In the RoadSnc configuration we only need to enter the hostname (thunderbird.android.dyndns.com
), the username and the corresponding password. Now we check if the synchronisation works.optionalAs described on the Zarafa Wiki you might have to change the provisioning to make the synchronisation work.
We may need to disable provisioning, unfortunately this will also disable the ability to wipe your phone remotely. The location of theconfig.php
depends on where you installed Z-Push. We start looking in/etc/z-push/config.php
.sudo nano /etc/z-push/config.php
In the file we changePROVISIONING
to false andLOOSE_PROVISIONING
to true.define('PROVISIONING', false); define('LOOSE_PROVISIONING', true);
To enable secure exchange of information we enable SSL. To be able to do so, we have to copy the certificate to the phone as described in the CA setup.
-
After registering with Z-Sync we get access to the code. Now we need to copy the server components (basically the folder
z-sync
) to a directory accessible to the web server on our server. Let us suggest that we use/var/www/
. If we have the folder on another host, we'll use scp to copy it to the server.scp -r z-sync_1.3.6/z-sync/ admin@thunderbird.android.dyndns.info:/home/admin/z-sync/
Now we log in to the server and copy it to the target directory.
ssh admin@thunderbird.android.dyndns.info sudo mv z-sync/ /var/www/
optionalAs we have not yet configured file sharing between the server and the network, we copy the contents onto an USB stick. To mount the stick we use
sudo mkdir /media/usb sudo mount /dev/sdb1 /media/usb
Then we copy the folder to the root of the web server.
sudo cp -R /media/usb/z-sync /var/www/
As indicated on the installation page, we make the subfolders accessible to the web server.
sudo chown www-data:\ /var/www/z-sync/logs sudo chown www-data:\ /var/www/z-sync/syncdata
Out of curiosity we have a look at the configuration file
config.php
and change things if necessary.sudo nano /var/www/z-sync/config.php
The synchronisation of extensive addressbooks with more than 1000 entries may take longer then 30 seconds. Thus, we may adjust the "max_execution_time" in the
/etc/php5/apache2/php.ini
to 120.sudo nano /etc/php5/apache2/php.ini
max_execution_time = 120
- Now we need to get the client (thunderbird) to use the Z-Sync
plugin. We install the plugin by going to the Thunderbird menu
z-sync.xpi
to install the extension. Then we enter the URI of our serverhttps://thunderbird.android.dyndns.com/
(if you have copied it to a subfolder of the/var/www/
folder, don't forget to append this here!). Note that the Add-on will appendz-sync
to your URI! Then we hit the button and hope the extension does not complain.
. There we click the install
button and navigate to the
Synchronise the Calendar
This task is twofold as we have a server that is authoritative about the data, we need to synchronise the local client (Thunderbird) with the server as well as the Android phone.
- We decribed the Android part already in the addressbook synchronisation part.
- The server configuration is explained on the Zarafa
Wiki. Note that we need to change the Zentyal stub, which is located at
/usr/share/ebox/stubs/zarafa/ical.cfg.mas
. We set the following values:sudo nano /usr/share/ebox/stubs/zarafa/ical.cfg.mas
icals_enable = yes ssl_private_key_file = /var/lib/ebox/CA/private/thunderbird.android.dyndns.com.pem ssl_certificate_file = /var/lib/ebox/CA/certs/3948A19F61447E.pem
Note that the certificate file uses the finderprint of the certificate as there might be several (revoked) certificates for the same URI.optionalIf we want to test the configuration the we just created we can overwrite the configuration file and start the ical service.sudo cp /usr/share/ebox/stubs/zarafa/ical.cfg.mas /etc/zarafa/ical.cfg sudo /etc/init.d/zarafa-ical start
Possibly we have to check the log...sudo tail /var/log/zarafa/ical.log
- Now you can access the calendar using Thunderbird and the
Lightning add-on using the CalDAV protocol the URI
https://thunderbird.android.dyndns.com:8443/caldav/user1
.
Alternatively, we can use the iCal version (which is not recommended but might offer better caching possiblities) using the URIhttps://thunderbird.android.dyndns.com:8443/ical/user1
To make Thunderbird accept the secure connection to our host, we have to add the certificate to its lists of trusted certificates. To do so we go in the Preferences of Thunderbird to the Advanced tab. Here we have a look at the certificates and add the certificate from the server.
Tipps, Tricks and Workarounds
- Enabling the HTTPS port (listening SSL port) in the workaround
from newton. If you prefer changing a JavaScript file teporarily on the
server you edit the
table-helper.js
file.sudo nano /usr/share/ebox/www/js/table-helper.js
Now we need to identify which certificate we need to change. To do this, we load the Certificate Services page and look at the source code. In this code we search for certificate associated with the Web Server (i.e., there should be a line like <div id='Certificates_enable_cert4803_loading'></div> after <span>Web Server</span>). We add the following lines at the beginning of thechangeView()
function.var id = 'cert4803';
This will make the function change the certificate of the web server no matter on which edit button we click. Thus, we reload the page in the management console and click on the edit symbol of any service. This will allow us to change the certificate used for the web server.
module will disallow chaning the
certificate used by the web server in the tab. If you are a JavaScript
guru, you can follow the - Given that we are using old hardware, space may be an issue.
So we should configure the logging behaviour such that they do not fill
the scarce space. We should consider that some log files are required.
A list of required logging directories (not necessarily complete!):
/var/log/ebox/ /var/log/redis/ /var/log/apache2/ /var/log/postgresql/ /var/log/zarafa/ /var/log/apt/
as well as required logfiles that are required:/var/log/ebox/ebox.log /var/log/redis/redis-server.log /var/log/apache2/error.log
If we delete log files we make sure never to delete those.
Importing Data
Just to make you not too enthusiastic. Importing the calendar did
not work for us when using an *.ics
file
exported from a Thunderbird client. We got the following reply:
As we did not have so many events in the future, we decided to add them manually to the new calendar instead of trying to fix this issue.
If we have an *.ics
file from a Zarafa
server (e.g., a backup of our calendar or when we move to new hardware),
we can follow the description from the Zarafa
Wiki. We'll need curl for that:
sudo apt-get curl
In addition we need to make sure that the Zarafa-ical gateway is running (follow this to get it running), that we have a Zarafa user (we'll call her user) as well as a Zarafa administrator (we'll call her zarafaAdmin). We create those users with the Zentyal Web frontend.
Let us assume that we have a calendar.ics
file (on a machine different from the server). We start by sending the
file to the server. Note that we authenticate using the admin
user and we copy the file to her home directory. Thus, from the other
machine we execute:
scp calendar.ics admin@thunderbird.android.dyndns.info:/home/admin/calendar.ics
Now we connect to the server using ssh
and then simply need to curl it to the running Zarafa-ical
gateway. So we make sure that the server is running! Note that we will
use the zarafaAdmin (which we cofigured using the Zentyal
Web frontend) to upload the calendar to the user's calendar. The
-k
switch is to avoid certificate checking (which would
fail due to using a self-signed certificate).
ssh admin@thunderbird.android.dyndns.info
curl -k -u zarafaAdmin:adminPW -T calendar.ics https://localhost:8443/ical/user
Dont't forget to configure the Zentyal firewall to allow traffic from the internal network to Zentyal! Then you can check access by connecting to:
https://thunderbird.android.dyndns.info:8443/ical/user