Обновление почтового сервера iRedMail с 0.9.5-1 до 0.9.7

iredmail-0.9.7Прошло уже почти два года с момента последнего обновления почтового сервера iRedMail до версии  0.9.5-1. а значит имеет смысл актуализировать нашу почтовую систему до последней на момент выхода статьи версии - 0.9.7. Пошаговый процесс установки iRedMail (MySQL Backend)  и различные проблемы возникающие в процессе обслуживания сервера описаны в главной статье.  В текущей  сборке произошли некоторые  изменения по части безопасности таких компонентов как Postfix, Amavis, Fail2ban + небольшие правки по части интерфейса в том же Roundcube, iRedAPD.

Если ставить новую версию на новый сервер, не OpenLDAP, то можно заметить что в качестве СУБД, вместо MySQL теперь MarinaDB, что на самом деле, абсолютно не страшно, поскольку MarinaDB это клон MySQL с тем же набором команд и инструкций от тех же разработчиков, только более свободный и независимый :)

Итак приступим. Для начала обновим саму ось выполнив всем известный набор команд:

apt-get update && apt-get upgrade

или

aptitude update && aptitude upgrade

Если, что-то пошло не так. У меня например в начале обновления на моем Debian 7 (Wheezy) вылезло информационное окошко PostgreSQL (С чего это вдруг, ведь данный пакет в системе не установлен?!), где в конце для выхода предлагают нажать quit (q), но при нажатии данной клавиши ничего не происходит. Следовательно приходится прерывать процесс при помощи ctrl+c. А вот если обновлять систему при помощи aptitude то нажатие "q" отрабатывает корректно.

Теперь перейдем к обновлению основных компонентов сервера.

Меняем текущий номер версии iRedMail на последнюю, открыв на изменение файлик /etc/iredmail-release

nano /etc/iredmail-release

1) Обновление iRedAPD:

cd /root
wget http://www.iredmail.org/yum/misc/iRedAPD-2.1.tar.bz2
tar xjf iRedAPD*.bz2
cd iRedAPD*/tools/
bash upgrade_iredapd.sh

Скрипт ругнулся на отсутствующий файлик .my.cnf, где записана инфа от подключении к MySQL-серверу. Дадим ему такой файлик и снова запустим скрипт:

nano ~/.my.cnf
[client]
host=localhost
port=3306
user=root
password="<your-password>"
bash upgrade_iredapd.sh

Если видим в конце, что «Upgrade completed», то все ОК, переходим к следующему компоненту.

2) Обновление iRedAdmin:

cd /root/
wget https://dl.iredmail.org/yum/misc/iRedAdmin-0.8.tar.bz2
tar xjf iRedAdmin*.tar.bz2
cd iRedAdmin*/tools/
bash upgrade_iredadmin.sh

3) Обновление Roundcube:

cd /root
wget https://dl.iredmail.org/yum/misc/roundcubemail-1.3.3-complete.tar.gz
tar xf roundcubemail*.tar.gz
cd roundcubemail*
bin/installto.sh /usr/share/apache2/roundcubemail-1.2.2
Нажимаем Yes. Если видим что:
This instance of Roundcube is up-to-date.
Have fun!
All done.

То процесс обновления прошел успешно.

Поправим имя директории roundcubemail на актуальную с правкой ярлыка (smlinks):

cd /usr/share/apache2
rm -i /usr/share/apache2/roundcubemail
mv /usr/share/apache2/roundcubemail-1.2.2 roundcubemail-1.3.3
ln -s roundcubemail-1.3.3 roundcubemail

Убедимся что владелец файла конфигурации /usr/share/apache2/plugins/password/config.inc.php (в новых версиях iRedMail путь к файлу может быть другим) и разрешения выставлены как:

www-data:www-data, 0400;

Если нет поправим командами:

chown www-data:www-data /usr/share/apache2/plugins/password/config.inc.php
chmod 0400 /usr/share/apache2/plugins/password/config.inc.php

Добавим в cron скрипт очистки директории /usr/share/apache2/roundcubemail/temp куда загружаются временные файлы пользователей, в основном это мини изображения вложений, графические элементы подписей. Со временем данная папка может существенно вырасти в размере, выжрав все свободное пространство на диске :)

Открываем на редактирование cron и вставляем туда следующую строчку:

crontab -e -u root
# Roundcube: Удаляем временные файлы.
# По умолчанию файлы хранятся два дня и контролируются в Roundcube параметром: $config['temp_dir_ttl']
2 2 * * * php /usr/share/apache2/roundcubemail/bin/gc.sh >/dev/null

Кстати, параметр "$config['temp_dir_ttl']" не был мной обнаружен в /usr/share/apache2/roundcubemail-1.3.3/config/config.inc.php а вот в самом дистрибутиве он есть, что как бы намекает, что процесс обновления со старой версии на новую не совсем корректно происходит. Хотя ничто не мешает нам его добавить в конфиг:

$config['temp_dir_ttl'] = '48h';

Но тогда не понятно, если существует данный параметр и файлы хранятся два дня, то зачем задание в cron очищающие данную папку или они хранятся где-то еще?! Надо будет понаблюдать! К слову сказать у меня за последние 2 года использования таких файлов  набралось аж 5 мб :)

4) Обновление Apache:

Исправляем уязвимость HTTProxy добавлением параметра в файл /etc/apache2/apache2.conf

RequestHeader unset Proxy early

Перезапускаем Apache командой:

service apache2 restart

4) Изменения в Postfix:

Версия iRedMail-0.9.5-1 и более ранние позволяют доверенным клиентам (указанным в параметре mynetworks) отправлять электронную почту через порт 587 без проверки подлинности smtp, что недостаточно строго и может использоваться спамерами. Для того что бы сконфигурировать механизм отправки почты через 587 порт с проверкой подлинности smtp для всех пользователей, поменяем значения параметра smtpd_client_restrictions в файле /etc/postfix/master.cf.

Открываем master.cf. на редактирование и находим строку:

-o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject

идущую после:

«submission inet n       -       n       -       -       smtpd».

Удаляем permit_mynetworks должно получится:

o smtpd_client_restrictions=permit_sasl_authenticated,reject

Так же в версии iRedMail-0.9.5-1 и более ранних не было поддержки безопасного соединения через TLS, что приводило к тому что другие серверы не могли передавать электронные сообщения через безопасное соединение. Добавим данную поддержку командой:

postconf -e smtpd_tls_security_level='may'

Обновим настройки postfix командой:

postfix reload

Одно неправильное или дополнительное ограничение в файле etc/postfix/helo_access.pcre. Убрать строку:

/(\d{1,3}[\.-]\d{1,3}[\.-]\d{1,3}[\.-]\d{1,3})/ REJECT ACCESS DENIED. Your email was rejected because the sending mail server appears to be on a dynamic IP address that should not be doing direct mail delivery (${1})

и поставить вместо нее следующее регулярное выражение:

^(\d{1,3}[\.-]\d{1,3}[\.-]\d{1,3}[\.-]\d{1,3})$/ REJECT ACCESS DENIED. Your email was rejected because the sending mail server appears to be on a dynamic IP address that should not be doing direct mail delivery (${1})

В моем файле ошибок нет, но такой строки тоже, поэтому просто добавил себе как доп. опцию.

5) Изменения в Amavis:

Добавлены новые правила фильтрации вложений по имени файла, расширению, а так же mime-заголовкам.  К слову данная фича у меня уже была реализована изначально, смотрим первую статью, хотя кое что я все таки у себя подправил.

$banned_namepath_re = new_RE(
    #[qr'T=(rar|arc|arj|zoo|gz|bz2)(,|\t)'xmi => 'DISCARD'],     # Compressed file types
    [qr'T=x-(msdownload|msdos-program|msmetafile)(,|\t)'xmi => 'DISCARD'],
    [qr'T=(hta)(,|\t)'xmi => 'DISCARD'],

    # Dangerous mime types
    [qr'T=(9|386|LeChiffre|aaa|abc|aepl|ani|aru|atm|aut|b64|bat|bhx|bkd|blf|
bll|bmw|boo|bps|bqf|breaking_bad|buk|bup|bxz|cc|ccc|ce0|ceo|cfxxe|chm|cih|
cla|class|cmd|com|cpl|crinf|crjoker|crypt|cryptolocker|cryptowall|ctbl|cxq|
cyw|dbd|delf|dev|dlb|dli|dll|dllx|dom|drv|dx|dxz|dyv|dyz|ecc|exe|exe-ms|exe1|
exe_renamed|exx|ezt|ezz|fag|fjl|fnr|fuj|good|gzquar|hlp|hlw|hqx|hsq|hts|iva|
iws|jar|js|kcd|keybtc@inbox_com|let|lik|lkh|lnk|locky|lok|lol!|lpaq5|magic|
mfu|micro|mim|mjg|mjz|nls|oar|ocx|osa|ozd|pcx|pgm|php2|php3|pid|pif|plc|pr|
pzdc|qit|qrn|r5a|rhk|rna|rsc_tmp|s7p|scr|shs|ska|smm|smtmp|sop|spam|ssy|swf|
sys|tko|tps|tsa|tti|ttt|txs|upa|uu|uue|uzy|vb|vba|vbe|vbs|vbx|vexe|vxd|vzr|
wlpginstall|ws|wsc|wsf|wsh|wss|xdu|xir|xlm|xlv|xnt|xnxx|xtbl|xxe|xxx|xyz|zix|
zvz|zzz)(,|\t)'xmi => 'DISCARD'],
    # Dangerous file name extensions
    [qr'N=.*\.(9|386|LeChiffre|aaa|abc|aepl|ani|aru|atm|aut|b64|bat|bhx|bkd|
blf|bll|bmw|boo|bps|bqf|breaking_bad|buk|bup|bxz|cc|ccc|ce0|ceo|cfxxe|chm|
cih|cla|class|cmd|com|cpl|crinf|crjoker|crypt|cryptolocker|cryptowall|ctbl|
cxq|cyw|dbd|delf|dev|dlb|dli|dll|dllx|dom|drv|dx|dxz|dyv|dyz|ecc|exe|exe-ms|
exe1|exe_renamed|exx|ezt|ezz|fag|fjl|fnr|fuj|good|gzquar|hlp|hlw|hqx|hsq|hts|
iva|iws|jar|js|kcd|keybtc@inbox_com|let|lik|lkh|lnk|locky|lok|lol!|lpaq5|
magic|mfu|micro|mim|mjg|mjz|nls|oar|ocx|osa|ozd|pcx|pgm|php2|php3|pid|pif|
plc|pr|pzdc|qit|qrn|r5a|rhk|rna|rsc_tmp|s7p|scr|shs|ska|smm|smtmp|sop|spam|
ssy|swf|sys|tko|tps|tsa|tti|ttt|txs|upa|uu|uue|uzy|vb|vba|vbe|vbs|vbx|vexe|
vxd|vzr|wlpginstall|ws|wsc|wsf|wsh|wss|xdu|xir|xlm|xlv|xnt|xnxx|xtbl|xxe|
xxx|xyz|zix|zvz|zzz)$'xmi => 'DISCARD'],
);

Вносим изменения в главный конфиг сервиса /etc/amavis/conf.d/50-user и перезапускаем его командой;

service amavis restart

6) Изменения в  Fail2ban:

Улучшаем регулярные выражение фильтра Fail2ban, чтобы поймать больше спама POP3 / IMAP и добавляем правильный фильтр для файла журнала Dovecot:

cd /etc/fail2ban/filter.d/
rm -f dovecot.iredmail.conf roundcube.iredmail.conf
wget https://bitbucket.org/zhb/iredmail/raw/default/iRedMail/samples/fail2ban/filter.d/dovecot.iredmail.conf
wget https://bitbucket.org/zhb/iredmail/raw/default/iRedMail/samples/fail2ban/filter.d/roundcube.iredmail.conf
service fail2ban reload

7) Изменения в Awstat:

В iRedMail-0.9.5-1 и более ранних выпусках, Awstats была неправильно настроена и доступна без аутентификации. Что бы это исправить, открываем конфиг /etc/apache2/conf.d/awstats.conf на редактирование и добавляем две строки:

Require all granted
Require valid-user

8) Изменения в Dovecot:

Фиксим неправильный параметр logrotate для файла журнала Dovecot, из-за которого все файлы журнала Dovecot пусты, в ввиду отсутствия необходимых разрешений для открытия файлов журнала. Что бы поправить, открываем файл /etc/logrotate.d/dovecot на редактирование и удаляем следующую сроку:

create 0600 vmail vmail

9) Обновление phpmyadmin. (опционально)

cd /tmp
cp -a /usr/share/phpmyadmin /tmp
cp /usr/share/phpmyadmin/config.inc.php /tmp
rm -rf /usr/share/phpmyadmin
wget https://files.phpmyadmin.net/phpMyAdmin/4.7.7/phpMyAdmin-4.7.7-all-languages.tar.gz
tar xf /tmp/phpMyAdmin-4.6.4-all-languages.tar.gz -C /usr/share
mv /usr/share/phpMyAdmin-4.6.4-all-languages /usr/share/phpmyadmin
cp /tmp/config.inc.php /usr/share/phpmyadmin
service apache2 restart

10) Изменения в MySQL:

Скорректируем значения (datetime) для некоторых столбцов SQL в базе данных «vmail»:

mysql -uroot -p
USE vmail;

ALTER TABLE admin \
MODIFY passwordlastchange DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE alias \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE alias_domain \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE domain \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE domain_admins \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE mailbox \
MODIFY lastlogindate DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY passwordlastchange DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE recipient_bcc_domain \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE recipient_bcc_user \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

ALTER TABLE sender_bcc_domain \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';
ALTER TABLE sender_bcc_user \
MODIFY created DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01', \
MODIFY modified DATETIME NOT NULL DEFAULT '1970-01-01 01:01:01';

Добавим новые таблицы forwardings и alias_moderators в базу vmail (опционально):

CREATE TABLE IF NOT EXISTS alias_moderators (
id BIGINT(20) UNSIGNED AUTO_INCREMENT,
address VARCHAR(255) NOT NULL DEFAULT '',
moderator VARCHAR(255) NOT NULL DEFAULT '',
domain VARCHAR(255) NOT NULL DEFAULT '',
dest_domain VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (id),
UNIQUE INDEX (address, moderator),
INDEX (domain),
INDEX (dest_domain)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS forwardings (
id BIGINT(20) UNSIGNED AUTO_INCREMENT,
address VARCHAR(255) NOT NULL DEFAULT '',
forwarding VARCHAR(255) NOT NULL DEFAULT '',
domain VARCHAR(255) NOT NULL DEFAULT '',
dest_domain VARCHAR(255) NOT NULL DEFAULT '',
is_list TINYINT(1) NOT NULL DEFAULT 0,
is_forwarding TINYINT(1) NOT NULL DEFAULT 0,
is_alias TINYINT(1) NOT NULL DEFAULT 0,
active TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (id),
UNIQUE INDEX (address, forwarding),
INDEX (domain),
INDEX (dest_domain),
INDEX (is_list),
INDEX (is_alias)
) ENGINE=InnoDB;

Затем закачаем скрипт по миграции пользовательских аккаунтов и запустим его. Данный скрипт делает запрос к MySQL базе «vmail» и производит миграцию (копирование) почтовых акаунтов из основной таблицы mailbox в таблицу псевдонимов — alias:

cd /root/
wget https://bitbucket.org/zhb/iredmail/raw/default/iRedMail/tools/migrate_sql_alias_table.py
python migrate_sql_alias_table.py

Но миграция не происходит т.к. скрипт ругается на отсутствующие поля в таблице alias, а именно: islist, is_alias.

python migrate_sql_alias_table.py
* Read SQL username/password from iRedAdmin config file: /usr/share/apache2/iredadmin/settings.pyc
* Backend: mysql
Traceback (most recent call last):
File "migrate_sql_alias_table.py", line 65, in <module>
records = db.select('alias', what='address,goto,moderators,domain,active,islist,is_alias')
File "/usr/lib/python2.7/dist-packages/web/db.py", line 682, in select
return self.query(qout, processed=True)
File "/usr/lib/python2.7/dist-packages/web/db.py", line 644, in query
self._db_execute(db_cursor, sql_query)
File "/usr/lib/python2.7/dist-packages/web/db.py", line 587, in _db_execute
out = cur.execute(query, params)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Unknown column 'islist' in 'field list'")

Почему данных полей у меня нет, сказать сложно, возможно версия старая или в предыдущих обновлениях что-то где-то не дописал. Тем не менее не сложно добавить эти поля вручную и повторно запустить скрипт:

mysql -uroot -p
USE vmail;
ALTER TABLE `alias` ADD `islist` TINYINT(1) NOT NULL DEFAULT 0;
ALTER TABLE `alias` ADD `is_alias` TINYINT(1) NOT NULL DEFAULT 0;
\q
python migrate_sql_alias_table.py

И вуаля, надпись «Done», говорит о том, что миграция завершилась успешно.

Теперь, сообщим postfix о новых таблицах, выполнив:

cd /etc/postfix/mysql/
perl -pi -e 's#alias\.address#forwardings.address#g' *.cf
perl -pi -e 's#alias\.goto#forwardings.forwarding#g' *.cf
perl -pi -e 's#alias\.active#forwardings.active#g' *.cf
perl -pi -e 's#alias\.domain#forwardings.domain#g' *.cf
perl -pi -e 's#alias,#forwardings,#g' *.cf
service postfix restart

И напоследок грохнем ранее созданные и неиспользуемые столбцы SQL в таблице alias, базе vmail:

mysql -uroot -p
USE vmail;
DELETE FROM alias WHERE islist <> 1;
DELETE FROM alias WHERE address=domain;
ALTER TABLE alias DROP COLUMN goto;
ALTER TABLE alias DROP COLUMN moderators;
ALTER TABLE alias DROP COLUMN islist;
ALTER TABLE alias DROP COLUMN is_alias;
\q

11) Послесловие

Как видим процесс обновления почтового сервера на базе Linux, не самая простая и тривиальная задача, требующая внимательности и глубокого понимания работы всей системы в целом :) Особенно актуально, когда после N-го количества обновлений по инструкции должен быть один результат, а у тебя может быть совершенно другой.  Поэтому при выходе последующих новых версий я решил более не заниматься апгрейдом системы, а сразу переносить конфигурацию со старого сервера на новый, как это было ранее описано в заметке. Возможно так будет быстрее и точнее в плане соответствия конфигурации от разработчиков.

Оставить ответ

Войти с помощью: 

Вы можете использовать эти HTML тэги

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>