Hi guys, I decided to post guide how to setup backup MX server for master MX running with ispconfig3. Without MySql running on it. So let's go on. First we install required packages: Code: # aptitude install php5 php5-cli php5-mysql postfix next we configure postfix as relay: Code: # file /etc/postfix/main.cf myhostname = mx2.example.com mydomain = example.com myorigin = $mydomain inet_interfaces = all mydestination = $myhostname, $mydomain smtpd_banner = $mydomain MX Backup biff = no alias_maps = relay_domains = hash:/etc/postfix/relay_domains relay_recipient_maps = hash:/etc/postfix/relay_recipients queue_run_delay = 200s smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_hostname, reject_rbl_client zen.spamhaus.org smtpd_helo_required = yes disable_vrfy_command = yes smtpd_data_restrictions = reject_unauth_pipelining, permit Create new user in master database and grant SELECT permission for dbispconfig database. them create php script which connects to remote master server and download relay domains and recipient maps. PHP: <?php // file /etc/postfix/map_relay.php $link = mysql_connect('mx1.example.com', 'username', 'password', false, MYSQL_CLIENT_SSL); if(!$link) die; mysql_select_db('dbispconfig', $link); $result = mysql_query('SELECT `domain` FROM `mail_domain` WHERE `active` = "y"'); create_map($result, 'domain', 'relay_domains'); $result = mysql_query('SELECT `source` FROM `mail_forwarding` WHERE `active` = "y"'); create_map($result, 'source', 'relay_recipients'); $result = mysql_query('SELECT `email` FROM `mail_user` WHERE `disabledeliver` = "n"'); create_map($result, 'email', 'relay_recipients', 'a'); function create_map($result, $key, $file, $type = 'w') { if(mysql_num_rows($result) == 0)return false; $content = ''; while($row = mysql_fetch_array($result)) { $content .= $row[$key]."\tOK\n"; } write_file($file, $content, $type); } function write_file($file, $content, $type = 'w') { $handle = fopen($file, $type); fwrite($handle, $content); fclose($handle); return; } Of course, you must change connect settings. You see that I use SSL when connecting to remote db. If you don't need it, simple remove last two args from mysql_connect function. If you want use SSL, them you must configure remote db to use SSL So on remote db config add these lines: Code: # file /etc/mysql/my.cnf ssl-cert=/path/to/server.crt ssl-key=/path/to/server.key and restart mysql server. If you don't know ho to create certs look at this http://docs.google.com/View?id=dhp2k7sw_35gx9b5ffn We test it now Code: # php /etc/postfix/map_relay.php # postmap hash:/etc/postfix/relay_domains # postmap hash:/etc/postfix/relay_recipients # /etc/init.d/postfix restart If all is ok, them we can add it to crontab Code: # crontab -e add this line: (this update maps every hour) Code: 0 * * * * /usr/bin/php /etc/postfix/map_relay.php && postmap hash:/etc/postfix/relay_domains && postmap hash:/etc/postfix/relay_recipients Any enhancements?
yes. I try to make sh script like /usr/local/ispconfig/server.sh, but w/o success. Code: s2:/etc/postfix# ls -la total 120 drwxr-xr-x 2 root root 4096 Jan 16 08:43 . drwxr-xr-x 93 root root 4096 Jan 16 08:44 .. -rw-r--r-- 1 root root 319 Jan 15 19:00 dynamicmaps.cf -rw-r--r-- 1 root root 804 Jan 15 13:15 main.cf -rwxr-x--- 1 root root 970 Jan 16 08:45 map_relay.php -rwxr-x--- 1 root root 236 Jan 16 08:44 map_relay.sh -rw-r--r-- 1 root root 5302 Jan 15 11:31 master.cf -rw-r--r-- 1 root root 0 Jan 9 14:48 mime_header_checks -rw-r--r-- 1 root root 0 Jan 9 14:48 nested_header_checks -rw-r--r-- 1 root root 18992 May 4 2011 postfix-files -rwxr-xr-x 1 root root 8729 May 4 2011 postfix-script -rwxr-xr-x 1 root root 24256 May 4 2011 post-install -rw-r--r-- 1 root root 708 Jan 16 16:02 relay_domains -rw-r--r-- 1 root root 12288 Jan 17 14:00 relay_domains.db -rw-r--r-- 1 root root 1573 Jan 16 16:02 relay_recipients -rw-r--r-- 1 root root 12288 Jan 17 14:00 relay_recipients.db Code: s2:/etc/postfix# cat map_relay.sh #!/bin/sh PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin . /etc/profile /usr/bin/php -q /etc/postfix/map_relay.php postmap hash:/etc/postfix/relay_domains postmap hash:/etc/postfix/relay_recipients I fixed problem by adding absolute path to maps in PHP script To Moderators: Can I edit first post please?
Fixed conf: PHP: <?php // file /etc/postfix/map_relay.php $link = mysql_connect('mx1.example.com', 'username', 'password', false, MYSQL_CLIENT_SSL); if(!$link) die; mysql_select_db('dbispconfig', $link); $result = mysql_query('SELECT `domain` FROM `mail_domain` WHERE `active` = "y"'); create_map($result, 'domain', '/etc/postfix/relay_domains'); $result = mysql_query('SELECT `source` FROM `mail_forwarding` WHERE `active` = "y"'); create_map($result, 'source', '/etc/postfix/relay_recipients'); $result = mysql_query('SELECT `email` FROM `mail_user` WHERE `disabledeliver` = "n"'); create_map($result, 'email', '/etc/postfix/relay_recipients', 'a'); exec('postmap hash:/etc/postfix/relay_domains & postmap hash:/etc/postfix/relay_recipients'); function create_map($result, $key, $file, $type = 'w') { if(mysql_num_rows($result) == 0)return false; $content = ''; while($row = mysql_fetch_array($result)) { $content .= $row[$key]."\tOK\n"; } write_file($file, $content, $type); } function write_file($file, $content, $type = 'w') { $handle = fopen($file, $type); fwrite($handle, $content); fclose($handle); return; } crontab: Code: 0 * * * * /usr/bin/php -q /etc/postfix/map_relay.php
Don't put `$mydomain` in `mydestination` if you want backup your domain too. It took me hours to find it out. Check http://www.postfix.org/STANDARD_CONFIGURATION_README.html#backup to find out more. So, to backup even example.com main.cf should be: Code: # file /etc/postfix/main.cf myhostname = mx2.example.com mydomain = example.com myorigin = $mydomain inet_interfaces = all mydestination = $myhostname smtpd_banner = $mydomain MX Backup biff = no alias_maps = relay_domains = hash:/etc/postfix/relay_domains relay_recipient_maps = hash:/etc/postfix/relay_recipients queue_run_delay = 200s smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_hostname, reject_rbl_client zen.spamhaus.org smtpd_helo_required = yes disable_vrfy_command = yes smtpd_data_restrictions = reject_unauth_pipelining, permit
Fixed PHP script (I add full path to postmap command because cron not found it) : PHP: <?php $link = mysql_connect('s0.ikfsystems.sk', 'map_relay', 'RRhQe8qa4Qhmezeq', false, MYSQL_CLIENT_SSL); if(!$link) die; mysql_select_db('dbispconfig', $link); $result = mysql_query('SELECT `domain` FROM `mail_domain` WHERE `active` = "y"'); create_map($result, 'domain', '/etc/postfix/relay_domains'); $result = mysql_query('SELECT `source` FROM `mail_forwarding` WHERE `active` = "y"'); create_map($result, 'source', '/etc/postfix/relay_recipients'); $result = mysql_query('SELECT `email` FROM `mail_user` WHERE `disabledeliver` = "n"'); create_map($result, 'email', '/etc/postfix/relay_recipients', 'a'); exec('/usr/sbin/postmap hash:/etc/postfix/relay_domains & /usr/sbin/postmap hash:/etc/postfix/relay_recipients'); function create_map($result, $key, $file, $type = 'w') { if(mysql_num_rows($result) == 0)return false; $content = ''; while($row = mysql_fetch_array($result)) { $content .= $row[$key]."\tOK\n"; } write_file($file, $content, $type); } function write_file($file, $content, $type = 'w') { $handle = fopen($file, $type); fwrite($handle, $content); fclose($handle); return; }
Hi, Thanks a lot for this quick tutorial. I have a suggestion to make: Personally, at first, I did not use aliases. Therefore, I ended up with relay_recipients containing the same entries several times, as they just ended up being appended at the end of the file. My understanding is that the relay_recipients file is first overwritten using aliases, and only then will the actual mailboxes be appended. It is better to first look for mailboxes, and only then for the aliases, for the following reasons: - It seems more logical (but I admit that could just be a point of view! ) - A mailbox needs to exist first for an alias to be created - Mailboxes are repeated at the end of the file if no alias is configured in ISPConfig (but we already know that). The code should therefore become: PHP: <?php// file /etc/postfix/map_relay.php $link = mysql_connect('s0.ikfsystems.sk', 'map_relay', 'RRhQe8qa4Qhmezeq', false, MYSQL_CLIENT_SSL);if(!$link) die;mysql_select_db('dbispconfig', $link);$result = mysql_query('SELECT `domain` FROM `mail_domain` WHERE `active` = "y"');create_map($result, 'domain', '/etc/postfix/relay_domains');$result = mysql_query('SELECT `email` FROM `mail_user` WHERE `disabledeliver` = "n"');create_map($result, 'email', '/etc/postfix/relay_recipients');$result = mysql_query('SELECT `source` FROM `mail_forwarding` WHERE `active` = "y"');create_map($result, 'source', '/etc/postfix/relay_recipients', 'a');exec('/usr/sbin/postmap hash:/etc/postfix/relay_domains & /usr/sbin/postmap hash:/etc/postfix/relay_recipients');function create_map($result, $key, $file, $type = 'w'){ if(mysql_num_rows($result) == 0)return false; $content = ''; while($row = mysql_fetch_array($result)) { $content .= $row[$key]."\tOK\n"; } write_file($file, $content, $type);}function write_file($file, $content, $type = 'w'){ $handle = fopen($file, $type); fwrite($handle, $content); fclose($handle); return;} Cheers!