How to Set Up Z-Push ActiveSync For Ubuntu Mail Server
Z-Push is an open-source implementation of the Exchange ActiveSync protocol, which is used to synchronize emails, contacts, calendars, tasks between mobile devices and desktop computers.
This tutorial works on all current Ubuntu releases, including Ubuntu 22.04, 20.04 and 18.04.
Push Email
Normally your email client such as Thunderbird checks your IMAP server periodically to see if there are new emails. There’s a delay since it doesn’t perform the check every second. Once you have configured Z-Push, new emails can be pushed to the end user (MUA) as soon as it arrives at the IMAP server.
Requirement
It’s assumed you have already an Ubuntu mail server up and running. If not, you can use Modoboa to quickly set up a mail server.
If you prefer to set up a mail server from scratch, please read the following tutorial series.
Step 1: Install Z-Push on Ubuntu Mail Server
Log into your Ubuntu mail server and run the following command.
sudo apt install z-push z-push-backend-imap z-push-common
During the following installation, you will be asked to select a web server that should be automatically configured to run z-push. There are two options available: Apache
and Lighttpd
.
If you use Nginx web server, then simply press the Tab
key and Enter
to skip the selection.
If you select Apache web server, then it will add two config files:
/etc/apache2/conf-available/z-push.conf
/etc/apache2/conf-available/z-push-autodiscover.conf
And they will be enabled under the /etc/apache2/conf-enabled/
directory.
In this tutorial, I only show you how to set up Z-Push with IMAP backend to synchronize email. If you also want to sync calendar, tasks, contacts, then you need to install other backends.
sudo apt install z-push-backend-combined z-push-backend-caldav z-push-backend-carddav z-push-backend-kopano
Now we need to configure Z-Push autodiscover.
sudo nano /etc/z-push/autodiscover.conf.php
Find the time zone setting.
define('TIMEZONE', '');
Enter your time zone like below. You can find your time zone on the php.net website.
define('TIMEZONE', 'America/New_York');
Next, find the following line.
define('USE_FULLEMAIL_FOR_LOGIN', false);
Change false
to true
to use full email address for login.
define('USE_FULLEMAIL_FOR_LOGIN', true);
Then, find the backend provider setting.
define('BACKEND_PROVIDER', '')
Enable the IMAP backend.
define('BACKEND_PROVIDER', 'BackendIMAP');
Save and close the file. Edit the z-push.conf.php
file.
sudo nano /etc/z-push/z-push.conf.php
Find the time zone setting.
define('TIMEZONE', '');
Enter your time zone like below.
define('TIMEZONE', 'America/New_York');
Find the backend provider setting.
define('BACKEND_PROVIDER', '');
Enable the IMAP backend.
define('BACKEND_PROVIDER', 'BackendIMAP');
Save and close the file.
Edit the imap.conf.php
file.
sudo nano /etc/z-push/imap.conf.php
Find the BackendIMAP settings.
// Defines the server to which we want to connect define('IMAP_SERVER', 'localhost'); // connecting to default port (143) define('IMAP_PORT', 143); // best cross-platform compatibility (see http://php.net/imap_open for options) define('IMAP_OPTIONS', '/notls/norsh');
We need to enable TLS encryption.
// Defines the server to which we want to connect define('IMAP_SERVER', 'mail.example.com'); // connecting to default port (143) define('IMAP_PORT', 993); // best cross-platform compatibility (see http://php.net/imap_open for options) define('IMAP_OPTIONS', '/ssl');
Next, find the following line.
define('IMAP_SMTP_METHOD', 'mail')
Set the IMAP_SMTP_METHOD
to smtp
.
define('IMAP_SMTP_METHOD', 'smtp')
Find the following line.
$imap_smtp_params = array();
Add your SMTP server settings.
$imap_smtp_params = array('host' => 'tcp://mail.example.com', 'port' => 587, 'auth' => true, 'username' => 'imap_username', 'password' => 'imap_password');
Find the following line.
define('IMAP_FOLDER_CONFIGURED', false);
Change false
to true
.
define('IMAP_FOLDER_CONFIGURED', true);
Save and close the file.
Step 2: Install PHP Extensions
Z-Push currently isn’t compatible with PHP 8. Run the following command to install PHP7.4.
sudo apt install software-properties-common sudo add-apt-repository ppa:ondrej/php sudo apt update sudo apt install php-soap php7.4-common php7.4-soap php7.4-fpm php7.4-imap php7.4-mbstring
You might have heard that PHP7.4 is no longer supported by upstream PHP developers. Don’t worry, you will still get bug fixes and security updates from the above PPA.
If you use Apache, then you need to configure it to use PHP-FPM.
Disable PHP7 module.
sudo a2dismod php7.4
Disable prefork MPM module.
sudo a2dismod mpm_prefork
Enable Event MPM, Fast_CGI and setenvif module.
sudo a2enmod mpm_event proxy_fcgi setenvif
Set PHP-FPM as Apache’s PHP handler using the following command, which will enable /etc/apache2/conf-available/php7.4-fpm .conf
file.
sudo a2enconf php7.4-fpm
Restart Apache for the changes to take effect.
sudo systemctl restart apache2
Step 3: Configure Web Server
Nginx
Create a virtual host file.
sudo nano /etc/nginx/conf.d/z-push.conf
Add the following lines to this file. Don’t forget to create a DNS A record for the sub-domain autodiscover.examle.com
. Of course, you need to use your real domain.
server {
listen 80;
listen [::]:80;
server_name autodiscover.example.com;
access_log /var/log/nginx/z-push.access;
error_log /var/log/nginx/z-push.error;
location ~* /AutoDiscover/AutoDiscover.xml {
alias /usr/share/z-push/autodiscover/autodiscover.php;
include /etc/nginx/fastcgi.conf;
fastcgi_read_timeout 3660;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
location ~* /Microsoft-Server-ActiveSync {
alias /usr/share/z-push/index.php;
include /etc/nginx/fastcgi.conf;
fastcgi_read_timeout 3660;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
}
Save and close the file. Then Test Nginx configuration.
sudo nginx -t
If the test is successful, reload Nginx.
sudo systemctl reload nginx
Apache
Create a virtual host file.
sudo nano /etc/apache2/sites-availabe/z-push.conf
Add the following lines.
<VirtualHost *:80>
ServerName autodiscover.example.com
<IfModule mod_alias.c>
Alias /Microsoft-Server-ActiveSync /usr/share/z-push/index.php
</IfModule>
<Directory /usr/share/z-push>
# Don't list a directory index, follow symlinks (maybe state dir is somewhere linked)
DirectoryIndex index.php
Options -Indexes +FollowSymLinks
# Security
# Don't allow .htaccess Overrides, disallow access to files
AllowOverride none
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
<Files "config.php">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</Files>
</Directory>
<IfModule mod_alias.c>
Alias /AutoDiscover/AutoDiscover.xml "/usr/share/z-push/autodiscover/autodiscover.php"
Alias /Autodiscover/Autodiscover.xml "/usr/share/z-push/autodiscover/autodiscover.php"
Alias /autodiscover/autodiscover.xml "/usr/share/z-push/autodiscover/autodiscover.php"
</IfModule>
Include /etc/apache2/conf-available/php7.4-fpm.conf
</VirtualHost>
Enable this virtual host.
sudo a2ensite z-push.conf
Restart Apache.
sudo systemctl restart apache2
Step 4: Enable HTTPS
We can enable HTTPS by installing a free TLS certificate issued from Let’s Encrypt. Run the following command to install Let’s Encrypt client (certbot) on Ubuntu 22.04/20.04 server.
sudo apt install certbot
If you use Nginx, then you also need to install the Certbot Nginx plugin.
sudo apt install python3-certbot-nginx
Next, run the following command to obtain and install TLS certificate.
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d autodiscover.example.com
If you use Apache, install the Certbot Apache plugin.
sudo apt install python3-certbot-apache
And run this command to obtain and install TLS certificate.
sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d autodiscover.example.com
Where
--nginx
: Use the nginx plugin.--apache
: Use the Apache plugin.--agree-tos
: Agree to terms of service.--redirect
: Force HTTPS by 301 redirect.--hsts
: Add the Strict-Transport-Security header to every HTTP response. Forcing browser to always use TLS for the domain. Defends against SSL/TLS Stripping.--staple-ocsp
: Enables OCSP Stapling. A valid OCSP response is stapled to the certificate that the server offers during TLS.
The certificate should now be obtained and automatically installed.
Restart your web server.
sudo systemctl restart nginx
or
sudo systemctl restart apache2
Now go to https://autodiscover.example.com/Microsoft-Server-ActiveSync
. You will see an authentication dialog. Log in with your email account credential. If you can’t sign in, then you have a problem. You should check the Z-Push error log (/var/log/z-push/z-push-error.log
).
Step 5: Enable Push Email on Mobile Devices
I have an iPhone, so I will show you how to do it on iPhone.
Go to Settings -> Mail -> Accounts -> Add account. Select Microsoft Exchange as the account type. Then enter your email address and a description. You will be asked if you want Microsoft to discover your account information. Select Configure Manually, then you need to enter your account password.
Then you will need to enter your email address and password again. You can see that the Server and Domain fields are optional. Enter autodiscover.example.com
in the server field.
Click the Next button. If everything is good, your account information should be verified successfully. You will have the option to sync mail, contacts calendars, reminders, and notes. This tutorial only configured IMAP backend in Z-Push, so I select mail only.
By default, only emails in the previous 30 days are synchronized. If you want to sync all emails, go to Settings -> Mail, select your mail account, and change the Mail Days to Sync settings.
Troubleshooting
The Connection to the Server Failed
If you encounter the Cannot Get Mail: The connection to the server failed
error on iOS, it’s probably because you use an incompatible PHP version for Z-Push.
Unable to Verify Account Information
If you encounter the unable to verify account information when trying to add the mail account on iOS, and the /var/log/z-push/z-push-error.log
file reveals that it doesn’t use your full email address to login, then edit the Dovecot 10-auth.conf
file.
sudo nano /etc/dovecot/conf.d/10-auth.conf
Find the following line.
# auth_default_realm =
Uncomment it and add your domain here, like this:
auth_default_realm = linuxbabe.com
This way, Dovecot will automatically append the @domain part for the login email. Save and close the file. Then restart Dovecot.
sudo systemctl restart dovecot
Checking Server Logs
- Z-Push logs under the
/var/log/z-push/
directory. - Apache log:
/var/log/apache2/z-push_error.log
. - Nginx log:
/var/log/nginx/z-push.error
.
Wrapping Up
I hope this tutorial helped you set up Z-Push ActiveSync for your Ubuntu mail server. As always, if you found this post useful, then subscribe to our free newsletter to get more useful tutorials 🙂
Will Z-Push-ActiveSync work with PHP 8.1 instead of PHP 7.4?
No.
Z-Push 2.7.0 has now been released and it supports PHP8, however this package version has not yet made it to Ubuntu 22, as of the time of writing it is on 2.6.0 and that only supports 7.4.
Will work on Debian?
Compatible with the article How to host multiple mail domains in PostfixAdmin on Ubuntu or how can I add more domains?
So I need to configure one general domain in Z-Push and then configure multiple domains from nginx / apache because localhost won’t work?
hi Xiao
I have a couple of messages which causes loop that’s why z-push ignore them. These message doesn’t show in outlook.
IMAP works fine. I cannot find any usable message in the log. It is in WBXML deatils, but there’s no error messages.
Do you have any useful suggetion?
Thanks
Thank you for the great guide.
Only one problem I found, the php7.4-xml package is missing.
Can be solved by:
Without this package, you get these errors in the error log at
:
Thanks for the guide.
I have followed the guide and only get the following error. I have tried everything. Please help!
[#unknown] AuthenticationRequiredException: Access denied. Please send authorisation information – code: 0 – file: /usr/share/z-push/index.php:56
…
[ INFO] [[email protected]] cmd=” memory=’1.49 MiB/2.00 MiB’ time=’0.98s’ devType=” devId=” getUser=’[email protected]’ from=’83.37.234.4′ idle=’0s’ version=’2.5.1-1′ method=’GET’ httpcode=’200′
Any suggestion?. Sorry for my bad English and best regards.
Sorry, I paste wrong line. The error is this:
FatalException: Requested the Z-Push URL without the required GET parameters – code: 0 – file: /usr/share/z-push/index.php:71