Upgrade iRedMail from 0.8.6 to 0.8.7

ChangeLog

General (All backends should apply these steps)

Update /etc/iredmail-release with iRedMail version number

iRedMail stores the release version in /etc/iredmail-release after installation, it's recommended to update this file after you upgraded iRedMail, so that you can know which version of iRedMail you're running. For example:

# File: /etc/iredmail-release

0.8.7

Upgrade Roundcube webmail to the latest stable release

Please follow Roundcube official tutorial to upgrade Roundcube webmail to the latest stable release immediately: How to upgrade Roundcube

Upgrade iRedAPD (Postfix policy server) to the latest 1.4.3

Please follow below tutorial to upgrade iRedAPD to the latest stable release: How to upgrade iRedAPD-1.4.1 or later versions to iRedAPD-1.4.3

Upgrade iRedAdmin (open source edition) to the latest stable release

Please follow this tutorial to upgrade iRedAdmin open source edition to the latest stable release: Upgrade iRedAdmin to the latest stable release

Upgrade phpMyAdmin to the latest stable release

Please follow this short tutorial to upgrade phpMyAdmin to the latest stable release: http://docs.phpmyadmin.net/en/latest/setup.html#upgrading-from-an-older-version

NOTE: Since phpMyAdmin-4.2.3.0, it enforces the minimum PHP (5.3) and MySQL (5.5) versions.

[OPTIONAL] Allows SMTP SASL authentication ONLY over a TLS-encrypted smtp connection

To allow SMTP SASL authentication ONLY over a TLS-encrypted smtp connection, just change value of parameter smtpd_tls_auth_only to yes, and reload Postfix service.

# postconf -e smtpd_tls_auth_only='yes'
# postfix reload

After this change, you have to update Roundcube config file to use SMTP service over TLS. For example:

# Part of Roundcube config file: config.inc.php

// OLD settings
//$rcmail_config['smtp_server'] = '127.0.0.1';
//$rcmail_config['smtp_port'] = 25;

// NEW settings
$config['smtp_server'] = 'tls://127.0.0.1';                                
$config['smtp_port'] = 587;

[OPTIONAL] Enable LMTP service in Dovecot-2.x

# dovecot --version

Before we go further, there're some questions we have to answer:

Search "dovecot lda vs lmtp" in Google will give you more detailed info and debate.

NOTE: On Debian or Ubuntu, you have to install one addition package before we go further: dovecot-lmtpd.

# apt-get install dovecot-lmtpd
# Part of file: /etc/dovecot/dovecot.conf

protocols = ... lmtp
# Part of file: /etc/dovecot/dovecot.conf

service lmtp {
    user = vmail

    # For higher volume sites, it may be desirable to increase the number of
    # active listener processes. A range of 5 to 20 is probably good for most
    # sites.
    #process_min_avail = 5

    # Logging
    executable = lmtp -L

    # Listening LMTP service on socket file and TCP
    unix_listener /var/spool/postfix/private/dovecot-lmtp {
        user = postfix
        group = postfix
        mode = 0600
    }

    inet_listener lmtp {
        #address = 192.168.0.24 127.0.0.1 ::1
        port = 24
    }
}

protocol lmtp {
    # Plugins
    mail_plugins = quota sieve
    postmaster_address = postmaster

    lmtp_save_to_detail_mailbox = yes
    recipient_delimiter = +

    # Log file
    info_log_path = /var/log/dovecot-lmtp.log
}

NOTE: For OpenBSD users, please replace user = postfix by user = _postfix, and replace group = postfix by group = _postfix.

# touch /var/log/dovecot-lmtp.log
# chown vmail:vmail /var/log/dovecot-lmtp.log
# chmod 0600 /var/log/dovecot-lmtp.log
# Part of file: /etc/logrotate.d/dovecot

/var/log/dovecot.log /var/log/dovecot-lmtp.log {
# Part of file: /etc/newsyslog.conf
/var/log/dovecot-lmtp.log    vmail:vmail   600  7     *    24    Z    /var/run/dovecot/master.pid
# Part of file: /etc/newsyslog.conf

/var/log/dovecot-lmtp.log    vmail:vmail   600  7     *    24    Z "/usr/local/bin/doveadm log reopen"
# ---- On Linux ----
# /etc/init.d/dovecot restart

# ---- On FreeBSD ----
# /usr/local/etc/rc.d/dovecot restart

# ---- On OpenBSD ----
# /etc/rc.d/dovecot restart

That's all. You can now check whether Dovecot is listening on port 24 and created socket file /var/spool/postfix/private/dovecot-lmtp for LMTP service.

# ---- On Linux ----
# netstat -ntlp | grep ':24'
# ls -l /var/spool/postfix/private/dovecot-lmtp

To use LMTP as local mail delivery agent, you can use either lmtp:unix:private/dovecot-lmtp (local socket) or lmtp:inet:127.0.0.1:24 (network listener). Currently, default mail delivery agent is dovecot (Dovecot LDA). For example:

mysql> USE vmail;
mysql> UPDATE domain SET transport='lmtp:unix:private/dovecot-lmtp' WHERE domain='abc.com';

IMPORTANT NOTE: it requires new LDAP value or SQL column for mail users mentioned in this upgrade tutorial (LDAP: enabledService=lmtp, SQL: mailbox.enablelmtp=1), so please finish this upgrade tutorial first, then you're safe to use LMTP.

[OPTIONAL] Fixed issue: Postfix cannot resolve client IP address to DNS name on RHEL/CentOS

This is optional.

On RHEL/CentOS, Postfix is running under chroot, it logs client IP address in log file, but cannot resolve IP to DNS name. You can fix it with below steps:

# ---- For i386 ----
# mkdir /var/spool/postfix/lib/
# cp /lib/*nss* /lib/*reso* /var/spool/postfix/lib/
# postfix reload

# ---- For x86_64 ----
# mkdir /var/spool/postfix/lib64/
# cp /lib64/*nss* /lib64/*reso* /var/spool/postfix/lib64/
# postfix reload

OpenLDAP backend special

Add new LDAP values for existing mail users

We will add one new LDAP attribute/value pair for existing mail users: enabledService=lmtp. It's used by Dovecot LMTP server.

# cd /root/
# wget https://bitbucket.org/zhb/iredmail/raw/default/extra/update/updateLDAPValues_086_to_087.py
# Part of file: updateLDAPValues_086_to_087.py

uri = 'ldap://127.0.0.1:389'
basedn = 'o=domains,dc=example,dc=com'
bind_dn = 'cn=vmailadmin,dc=example,dc=com'
bind_pw = 'passwd'

You can find required LDAP credential in iRedAdmin config file or iRedMail.tips file under your iRedMail installation directory. Using either cn=Manager,dc=xx,dc=xx or cn=vmailadmin,dc=xx,dc=xx as bind dn is ok.

# python updateLDAPValues_086_to_087.py

That's all.

MySQL backend special

Add and remove SQL columns in vmail database

We need 5 new SQL columns in vmail database:

Some existing columns in table vmail.domain are not needed anymore, they will be merged into our new column: domain.settings.

Now connect to SQL server as root user, create new columns, add required indexes for new column alias.islist, and update value of alias.islist for existing accounts:

$ mysql -uroot -p
mysql> USE vmail;
mysql> ALTER TABLE mailbox ADD COLUMN enablelmtp TINYINT(1) NOT NULL DEFAULT 1;
mysql> ALTER TABLE mailbox ADD INDEX (enablelmtp);

mysql> ALTER TABLE mailbox ADD COLUMN settings TEXT;
mysql> ALTER TABLE domain ADD COLUMN settings TEXT;
mysql> ALTER TABLE admin ADD COLUMN settings TEXT;

mysql> ALTER TABLE alias ADD COLUMN islist TINYINT(1) NOT NULL DEFAULT 0;
mysql> ALTER TABLE alias ADD INDEX (islist);
mysql> UPDATE alias SET islist=1 WHERE address NOT IN (SELECT username FROM mailbox);
mysql> UPDATE alias SET islist=0 WHERE address=domain;    -- domain catch-all account

-- Remove old columns and store their value into new column: domain.settings
mysql> UPDATE domain SET settings='';
mysql> UPDATE domain SET settings=CONCAT(settings, IF(defaultlanguage IS NULL OR defaultlanguage='', '', CONCAT('default_language:', defaultlanguage, ';')));
mysql> UPDATE domain SET settings=CONCAT(settings, IF(defaultuserquota IS NULL OR defaultuserquota=0, '', CONCAT('default_user_quota:', defaultuserquota, ';')));
mysql> UPDATE domain SET settings=CONCAT(settings, IF(defaultuseraliases IS NULL OR defaultuseraliases='', '', CONCAT('default_groups:', defaultuseraliases, ';')));
mysql> UPDATE domain SET settings=CONCAT(settings, IF(minpasswordlength IS NULL OR minpasswordlength=0, '', CONCAT('min_passwd_length:', minpasswordlength, ';')));
mysql> UPDATE domain SET settings=CONCAT(settings, IF(maxpasswordlength IS NULL OR maxpasswordlength=0, '', CONCAT('max_passwd_length:', maxpasswordlength, ';')));
mysql> UPDATE domain SET settings=CONCAT(settings, IF(disableddomainprofiles IS NULL OR disableddomainprofiles='', '', CONCAT('disabled_domain_profiles:', disableddomainprofiles, ';')));
mysql> UPDATE domain SET settings=CONCAT(settings, IF(disableduserprofiles IS NULL OR disableduserprofiles='', '', CONCAT('disabled_user_profiles:', disableduserprofiles, ';')));

mysql> ALTER TABLE domain DROP defaultlanguage;
mysql> ALTER TABLE domain DROP defaultuserquota;
mysql> ALTER TABLE domain DROP defaultuseraliases;
mysql> ALTER TABLE domain DROP minpasswordlength;
mysql> ALTER TABLE domain DROP maxpasswordlength;
mysql> ALTER TABLE domain DROP disableddomainprofiles;
mysql> ALTER TABLE domain DROP disableduserprofiles;

PostgreSQL backend special

Add and remove SQL columns in vmail database

We need 5 new SQL columns in vmail database:

Some existing columns in table vmail.domain are not needed anymore, they will be merged into our new column: domain.settings.

Now connect to SQL server as PostgreSQL administrator user, create new columns, add required indexes for new column alias.islist, and update value of alias.islist for existing accounts:

# su - postgres
$ psql -d vmail
sql> ALTER TABLE mailbox ADD COLUMN enablelmtp INT2 NOT NULL DEFAULT 1;
sql> CREATE INDEX idx_mailbox_enablelmtp ON mailbox (enablelmtp);

sql> ALTER TABLE mailbox ADD COLUMN settings TEXT NOT NULL DEFAULT '';
sql> ALTER TABLE domain ADD COLUMN settings TEXT NOT NULL DEFAULT '';
sql> ALTER TABLE admin ADD COLUMN settings TEXT NOT NULL DEFAULT '';

sql> ALTER TABLE alias ADD COLUMN islist INT2 NOT NULL DEFAULT 0;
sql> CREATE INDEX idx_alias_islist ON alias (islist);
sql> UPDATE alias SET islist=1 WHERE address NOT IN (SELECT username FROM mailbox);
sql> UPDATE alias SET islist=0 WHERE address=domain;    -- domain catch-all account

-- Remove old columns and store their value into new column: domain.settings
sql> UPDATE domain SET settings='';
sql> UPDATE domain SET settings=settings || 'default_language:' || defaultlanguage || ';';
sql> UPDATE domain SET settings=settings || 'default_user_quota:' || defaultuserquota || ';';
sql> UPDATE domain SET settings=settings || 'default_groups:' || defaultuseraliases || ';';
sql> UPDATE domain SET settings=settings || 'min_passwd_length:' || minpasswordlength || ';';
sql> UPDATE domain SET settings=settings || 'max_passwd_length:' || maxpasswordlength || ';';
sql> UPDATE domain SET settings=settings || 'disabled_domain_profiles:' || disableddomainprofiles || ';';
sql> UPDATE domain SET settings=settings || 'disabled_user_profiles:' || disableduserprofiles || ';';

sql> ALTER TABLE domain DROP defaultlanguage;
sql> ALTER TABLE domain DROP defaultuserquota;
sql> ALTER TABLE domain DROP defaultuseraliases;
sql> ALTER TABLE domain DROP minpasswordlength;
sql> ALTER TABLE domain DROP maxpasswordlength;
sql> ALTER TABLE domain DROP disableddomainprofiles;
sql> ALTER TABLE domain DROP disableduserprofiles;

Document published under a CC BY-ND 3.0 license. If you found something wrong, please do contact us to fix it.