Заметки сисадмина
Назад

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

Опубликовано: 18.01.2018
Время на чтение: 33 мин
0
1065

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

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

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

[shell]apt-get update && apt-get upgrade[/shell]
или
[shell]aptitude update && aptitude upgrade[/shell]

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

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

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

[shell]nano /etc/iredmail-release[/shell]

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

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

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

[shell]nano ~/.my.cnf[/shell]

[shell][client]
host=localhost
port=3306
user=root
password="<your-password>"[/shell]

[shell]shell upgrade_iredapd.sh[/shell]

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

2) Обновление iRedAdmin:
[shell]cd /root/
wget https://dl.iredmail.org/yum/misc/iRedAdmin-0.8.tar.bz2
tar xjf iRedAdmin*.tar.bz2
cd iRedAdmin*/tools/
shell upgrade_iredadmin.sh[/shell]

3) Обновление Roundcube:
[shell]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[/shell]

Нажимаем Yes. Если видим что:
[shell]This instance of Roundcube is up-to-date.
Have fun!
All done.[/shell]
То процесс обновления прошел успешно.

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

[shell]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
[/shell]

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

[shell]www-data:www-data, 0400;[/shell]
Если нет поправим командами:
[shell]chown www-data:www-data /usr/share/apache2/plugins/password/config.inc.php
chmod 0400 /usr/share/apache2/plugins/password/config.inc.php[/shell]

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

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

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

[shell]$config['temp_dir_ttl'] = '48h';[/shell]
Но тогда не понятно, если существует данный параметр и файлы хранятся два дня, то зачем задание в cron очищающие данную папку или они хранятся где-то еще?! Надо будет понаблюдать! К слову сказать у меня за последние 2 года использования таких файлов  набралось аж 5 мб :)

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

Исправляем уязвимость HTTProxy добавлением параметра в файл /etc/apache2/apache2.conf
[shell]RequestHeader unset Proxy early[/shell]
Перезапускаем Apache командой:
[shell]service apache2 restart[/shell]

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

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

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

[shell]
submission inet n       -       n       -       -       smtpd.
-o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
[/shell]

Удаляем:

[shell]permit_mynetworks[/shell]
должно получится:
[shell]o smtpd_client_restrictions=permit_sasl_authenticated,reject[/shell] Так же в версии iRedMail-0.9.5-1 и более ранних не было поддержки безопасного соединения через TLS, что приводило к тому что другие серверы не могли передавать электронные сообщения через безопасное соединение. Добавим данную поддержку командой: [shell]postconf -e smtpd_tls_security_level='may'[/shell] Обновим настройки postfix командой: [shell]postfix reload[/shell] Одно неправильное или дополнительное ограничение в файле etc/postfix/helo_access.pcre. Убрать строку:
[shell]/(\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})[/shell]
и поставить вместо нее следующее регулярное выражение:
[shell]^(\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})[/shell]
В моем файле ошибок нет, но такой строки тоже, поэтому просто добавил себе как доп. опцию.

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

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

[shell]
# 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|zoo|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|ev|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'], );[/shell]
Вносим изменения в главный конфиг сервиса /etc/amavis/conf.d/50-user и перезапускаем его командой;
[shell]service amavis restart[/shell]

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

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

[shell]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[/shell] 7) Изменения в Awstat:

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

[shell]Require all granted
Require valid-user[/shell]

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

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

[shell]create 0600 vmail vmail[/shell]

9) Обновление phpmyadmin. (опционально)
[shell]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
[/shell]

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

Скорректируем значения (datetime) для некоторых столбцов SQL в базе данных «vmail»:
[mysql]
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';
[/mysql]

Добавим новые таблицы forwardings,

[mysql]
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]

и alias_moderators в базу vmail (опционально):

[mysql]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;
[/mysql]

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

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

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

[shell]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'")
[/shell]

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

[mysql]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[/mysql]
И повторно запустить скрипт:
[shell]python migrate_sql_alias_table.py[/shell]
И вуаля, надпись "Done", говорит о том, что миграция завершилась успешно.

Теперь, сообщим postfix о новых таблицах, выполнив:
[shell]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
[/shell]
И напоследок грохнем ранее созданные и неиспользуемые столбцы SQL в таблице alias, базе vmail:
[mysql]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
[/mysql]

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

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

, , ,
Поделиться
Похожие записи