Sticky: Secondary MX – SysCP

The following article describes how to setup a secondary Postfix mail exchanger in a syscp environment. All customer data is stored in a MySQL database and therefor the setup focuses on how to replicate the database.

In the future I possible might post my complete mail setup and all components around Postfix, so stay tuned and come back from time to time.

I assume, there is a full configured syscp instance on the master server, from which you want to sync to slave servers. I also assume that your master mailserver uses SSL certs for smtps and submission. If not, please fix this and come back later on.

This setup is tested on Ubuntu dapper drake

Starting on the slave(s) server:

In fact, the setup is nearly identical to the master server, so you need to install all mail related packages that belong to SMTP:

– postfix
– postfix-mysql
– postfix-pcre (only, if it exists on the master)
– amavisd-new
– spamassassin
– razor
– pyzor
– dcc-client
– rulebonjour (only, if it exists on the master)
– mysql-client-5.0
– mysql-server-5.0
– clamav
– clamav-daemon
– clamav-freshclam
– stunnel4

After installing all these packages, please stop all running services, like Debian based systems always start them after installation.

Copy over all configuration files from the master server. Think about user/group settings concerning clamav.

After you have cloned this part of the configuration, change the directory to /etc/postfix and edit the file

  myhostname = mx2.
  mydomain = 
  # maildrop_destination_recipient_limit = 1
  virtual_transport = smtp:mx1.:587

I use submission here (587), because my slave server authenticates against the master via relay_ccert, you may remove the :587 postfix from virtual_transport. I will explain my setup for using certs later on. Now change to /var/lib/mysql and remove all files there. Be sure to be on the _slave_ 😉

On the _master_ side, change to /etc/mysql and edit my.cnf. Look for server-id and uncomment it. Set the value to 1. Now look for log-bin. It should look like this:

  log-bin = /var/log/mysql/mysql-bin.log

Save the file and exit.

Now call

  mysql -u root -p

and enter your password.

You need to grant replication rights to a user, here ’slave‘

  slave@' IDENTIFIED BY 'password';

It is important to run he following command on the _master_ to force read-only access to the database, because we will copy over all files from /var/lib/mysql from the master to the slave.


You _MUST_ _NOT_ leave the mysql prompt now! Otherwise, the server switches to read-write acces back and you probably will corrupt your database. I will tell you later on, when you may close this 🙂

Open a second terminal to your _master_ and change the directory to /var/lib/mysql. Now run

  tar -cvf /tmp/master-snapshot.tar .
  scp /tmp/master-snapshot.tar slave.server:/tmp

On the _slave_ side, (you are in /var/lib/mysql), run

  tar -xvf /tmp/master-snapshot.tar

Now change to /etc/mysql and edit my.cnf. Uncomment server-id and set it to a value other the one from the master server, i.e. set it to 2. You also _must_ comment out the log-bin line. Add the following line just under it:

  relay-log = /var/log/mysql/my_slave_hostnmae-relay-bin

This is needed for logrotate to finish without warnings. From my syslog:

  [Warning] Neither --relay-log nor --relay-log-index were used; so replication
  may break when this MySQL server acts as a slave and has his hostname
  changed!! Please use '--relay-log=vls07-relay-bin' to avoid this problem.

Because we copied over the whole database from the master server, please also copy the file /etc/mysql/debian.cnf from the _master_ to the _slave_, else cron will be unable to do some logrotate.

Now it is time to setup the tunnel. We start at the _master_.

Change to the directory /etc/stunnel and copy stunnel.conf to stunnel.conf.dist (I always do this, if I do changes to the original file).

Now, for easyness, I copied all certfiles from postfix to this directory, i.e.

  cp -a /path/to/certs/{cacert.pem,newcert.pem,newkey.pem} .

Check the permissions on newkey.pem. Should be 400 or 600 (read or read/write for user root).

So, now edit stunnel.conf and change the following:

cert = /etc/stunnel/newcert.pem
key = /etc/stunnel/newkey.pem
CAfile = /etc/stunnel/cacert.pem

accept = 3307
connect = 3306

Please remove all unneccessary [section] blocks. We only want mysqls.

Now you may start stunnel with /etc/init.d/stunnel4 start on the _master_.

On the _slave_ side, we do not have certs, yet. So please create a set of certs with your CA and sign them. You will do the same procedure like on the master server; inside /etc/stunnel:

  cp -a /path/to/certs/{cacert.pem,newcert.pem,newkey.pem} .

And the stunnel.conf should look like this:

cert = /etc/stunnel/newcert.pem
key = /etc/stunnel/newkey.pem
CAfile = /etc/stunnel/cacert.pem

client = yes

accept = 3307
connect = ip.from.master.server:3307

And like before on the master, we now can start stunnel with the same command as shown above. At this point the SSL tunnel should be up:

Back on the _master_ use the terminal, where you still see the mysql> prompt and run the following command:


You should get something like this:

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
| mysql-bin.000022 | 36150 | | |
1 row in set (0.00 sec)

Now switch to you _slave_ terminal and start the mysql server. After that, run the mysql -u root -p command

  MASTER_USER='slave', MASTER_PASSWORD='password',
  MASTER_LOG_FILE='mysql-bin.000022', MASTER_LOG_POS=36150;

  mysql> START SLAVE;


You should read somesomething like:

  Waiting for master to send event
  Has read all relay log; waiting for the slave I/O thread to update it

Now please leave the _slave_ mysql prompt and change to the _master_ mysql prompt. It is time to finish up.

  mysql> QUIT

On the _slave_ server, you _now_ may start postfix, amavis, clamav-daemon and clamav-freshclam. The secondary MX should be ready for take off 😉

I promised to explain the relay_ccert stuff. Here I go:

On the _master_ server, please have a look at /etc/postfix/

Go to the end of the file and look for a section like this (if it does not exist, create it with the following content):

  # Attention! reject_sender_login_mismatch only works with
  # permit_sasl_authenticated
  587     inet    n       -       -       -       -       smtpd
      -o smtpd_enforce_tls=yes
      -o content_filter=
      -o smtpd_sender_restrictions=permit_tls_clientcerts,\

Notice: I tried to keep a width of 80 characters here, so please remove the backslash at the end of smtpd_sender_restrictions and put the lines together. Otherwise you will earn an error.

In file /etc/postfix/

  relay_clientcerts = hash:/etc/postfix/map_relay_ccerts

File /etc/postfix/map_relay_ccerts looks something like this:

  # relay_ccerts
  # Syntax:
  # fingerprint   name
  # Example:
  # D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80
  # See /usr/share/doc/packages/postfix/samples/
  # for more details

  # openssl x509 -in newcert.pem -noout -md5 -fingerprint

The fingerprint should be taken from your _slave_ server with the command shown in the comment: openssl x509 -in newcert.pem -noout -md5 -fingerprint

Now, why using submission with a cert? Easy answer: Your secondary MX has already done all SPAM and RBL checks, why should the Master MX do the same again? As you can see, the submission block has content_filter set to NULL and it forces SSL and a authenticated connection.

So, hopefully I did not miss any important stuff here. Please update your zone files to point even to the secondary MX. After the DNS information is available, you may stop the primary MX and watch the secondary MX log files (simply take any free webmailer and send yourself an email), if anything is doing fine. You should see connection refused information. this is normal. After this, start the postfix application on the master MX again and do a

  sendmail -q

on the secondary MX. The mails should be forwarded to the master MX. That’s all folks.

2 Gedanken zu „Sticky: Secondary MX – SysCP

  1. bjo

    Ansich eine nette Lösung, aber ist die komplette MySQL-Replikation nicht zuviel des Guten, wenn man eigentlich nur die SysCP-Datenbank braucht? Wobei dann die Frage wäre, wie man nur die SysCP-Datenbank syncen kann…

  2. croessner Beitragsautor

    Es gibt da zwei Variablen für die my.cnf:

    replicate-do-db = syscp # for Replicating specific databases


    replicate-ignore-db = db

    Man kann also auch nur eine DB syncen oder angeben, welche nicht mit synchronisiert werden sollen.

Kommentare sind geschlossen.