Thank you for reading this post, don't forget to subscribe!
1. Преднастройка системы
Общие настройки
Задаем правильное имя серверу — это важный шаг, так как большинство антиспам систем выполняют проверки, обращаясь к серверу по имени в ожидании ответа.
vi /etc/hostname
relay.test.ru
* необходимо указать FQDN-имя, которое будет доступно из глобальной сети. В данном примере указано relay.test.ru.
После вводим такую команду:
hostname relay.test.ru
Устанавливаем служебные пакеты (они понадобятся в процессе настройки сервера):
yum install ntpdate wget
* ntpdate для возможности синхронизировать время на сервере; wget — клиент для загрузки файлов.
Задаем временную зону (в данном примере московское время):
cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
Синхронизируем время:
ntpdate ru.pool.ntp.org
Обновляем систему:
yum update
Настройка безопасности
Заранее открываем порты на брандмауэре с помощью firewalld:
firewall-cmd --permanent --add-port=25/tcp --add-port=80/tcp --add-port=110/tcp --add-port=143/tcp --add-port=443/tcp --add-port=465/tcp --add-port=587/tcp --add-port=993/tcp --add-port=995/tcp
firewall-cmd --reload
* где мы откроем следующие порты:
- 25 — стандартный SMTP через STARTTLS;
- 80 — HTTP для порталов Postfixadmin и Roundcube;
- 110 — стандартный POP3 через STARTTLS;
- 143 — стандартный IMAP через STARTTLS;
- 443 — защищенный HTTPS для порталов Postfixadmin и Roundcube;
- 465 — защищенный SMTP через SSL/TLS;
- 587 — защищенный SMTP через STARTTLS;
- 993 — защищенный IMAP через SSL/TLS;
- 995 — защищенный POP3 через SSL/TLS.
В CentOS также может использоваться утилита iptables — в таком случае команды будут следующие:
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 465 -j ACCEPT
iptables -A INPUT -p tcp --dport 587 -j ACCEPT
iptables -A INPUT -p tcp --dport 993 -j ACCEPT
iptables -A INPUT -p tcp --dport 995 -j ACCEPT
После сохраняем правила любым из описанных способов:
Способ 1. iptables-save
Сохраняем правила в файл:
iptables-save > /etc/iptables.rules
Открываем настройки сети:
vi /etc/network/interfaces
и добавляем строку:
pre-up iptables-restore < /etc/iptables.rules
Способ 2. iptables-persistent
Ставим пакет iptables-persistent:
apt-get install iptables-persistent
Для сохранения правил вводим команду:
netfilter-persistent save
Способ 3. service iptables
Работает в старых версиях Linux:
service iptables save
Или необходима установка пакета:
yum install iptables-services
apt-get install iptables-services
* первая команда для CentOS, вторая — для Ubuntu.
В CentOS
В качестве штатной программы управления брандмауэром используется firewall-cmd.
Если необходимо пользоваться iptables, устанавливаем пакет с утилитой:
yum install iptables-services
Отключаем firewalld:
systemctl stop firewalld
systemctl disable firewalld
Разрешаем и запускаем iptables:
systemctl enable iptables
systemctl start iptables
В Ubuntu
Для управления брандмауэром теперь используется ufw.
Для работы с iptables, устанавливаем следующий пакет:
apt-get install iptables-persistent
Отключаем ufw:
ufw disable
2. Настройка веб-сервера: NGINX + PHP + MariaDB
Система управления PostfixAdmin работает как веб-приложение, разработанное на PHP, а информацию хранит в базе данных. В нашем примере будет использоваться веб-сервер на NGINX, а база данных — MariaDB.
Установка NGINX
Добавляем репозиторий с нужным пакетом:
vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
Устанавливаем nginx:
yum install nginx
Разрешаем автозапуск сервиса и запускаем его:
systemctl enable nginx
systemctl start nginx
Проверяем работоспособность веб-сервера, обратившись к нему в браузере по IP-адресу. Если видим заголовок «Welcome to nginx!», NGINX настроен верно.
PHP + PHP-FPM + NGINX
Устанавливаем php и php-fpm:
yum install php php-fpm
Настраиваем NGINX:
vi /etc/nginx/conf.d/default.conf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
server { listen 80 default_server; set $root_path /usr/share/nginx/html; location / { root $root_path; index index.php index.hml; } location ~ \.php$ { fastcgi_pass unix:/var/run/php-fpm/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name; include fastcgi_params; fastcgi_param DOCUMENT_ROOT $root_path; } } |
[/codesyntax]
* где /usr/share/nginx/html — каталог для размещения портала управления Postfix.
Настраиваем PHP-FPM:
vi /etc/php-fpm.d/www.conf
listen = /var/run/php-fpm/php5-fpm.sock
* здесь мы поменяли строку 127.0.0.1:9000.
Запускаем сервисы:
systemctl enable php-fpm
systemctl start php-fpm
systemctl restart nginx
* если в процессе перезапуска nginx выскочит ошибка nginx: [emerg] a duplicate default server, необходимо найти настройку виртуального домена, в которой также указана опция default_server — опцию нужно убрать. Или можно самостоятельно настроить другой виртуальный домен.
Для проверки, создаем индексный файл в директории сайта со следующим содержимым:
vi /usr/share/nginx/html/index.php
<?php phpinfo(); ?>
Открываем сайт в браузере по его IP-адресу. На открывшейся странице мы должны увидеть подробную информацию по php.
MariaDB
Устанавливаем сервер баз данных следующей командой:
yum install mariadb mariadb-server
Включаем автозапуск сервиса и запускаем его:
systemctl enable mariadb
systemctl start mariadb
Задаем пароль для пользователя sql root:
mysqladmin -u root password
3. Установка и настройка PostfixAdmin
Устанавливаем репозиторий epel:
yum install epel-release
Устанавливаем дополнительные компоненты для PHP:
yum install php-mysql php-mbstring php-imap
Для применения установленных пакетов, перезапускаем обработчик скриптов:
systemctl restart php-fpm
Скачиваем PostfixAdmin:
wget https://sourceforge.net/projects/postfixadmin/files/latest/download -O postfixadmin.tar.gz
В директории сайтов nginx создаем каталог для postfixadmin и распаковываем в него архив:
mkdir /usr/share/nginx/html/postfixadmin
tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1
Создаем каталог templates_c внутри папки портала (без него не запустится установка):
mkdir /usr/share/nginx/html/postfixadmin/templates_c
Задаем права на каталог:
chown -R apache:apache /usr/share/nginx/html/postfixadmin
* несмотря на то, что мы используем веб-сервер nginx, php-fpm по умолчанию, запускается от пользователя apache.
Создаем базу данных postfix и учетную запись в mariadb:
mysql -u root -p
CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
* где postfix — имя базы.
GRANT ALL ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'postfix123';
* где postfix — имя учетной записи; postfix123 — пароль; localhost разрешает подключение только с локального сервера.
Выходим из командной оболочки MariaDB:
\q
Создаем конфигурационный файл postfixadmin:
vi /usr/share/nginx/html/postfixadmin/config.local.php
* в предыдущих версиях использовался файл config.inc.php. В новых версиях его не рекомендуется править, а использовать config.local.php, который переопределяет настройки.
И редактируем следующее:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
<?php $CONF['configured'] = true; $CONF['default_language'] = 'ru'; $CONF['database_password'] = 'postfix123'; $CONF['emailcheck_resolve_domain']='NO'; ?> |
[/codesyntax]
* где configured говорит приложению, что администратор закончил его конфигурирование; default_language — используемый язык по умолчанию; database_password — пароль для базы данных, который мы задали на предыдущем шаге; emailcheck_resolve_domain — задает необходимость проверки домена при создании ящиков и псевдонимов.
Запускаем браузер и вводим адрес http://<IP-адрес сервера>/postfixadmin/public/setup.php
Начнется процесс проверки конфигурации и установки портала PostfixAdmin. После ее окончания вводим дважды пароль и генерируем хэш:
После перезагрузки страницы копируем хэш:
Открываем конфигурационный файл:
vi /usr/share/nginx/html/postfixadmin/config.local.php
И добавляем строчку:
…
$CONF['setup_password'] = '7a8e14…c26';
* где '7a8e14…c26' — скопированный хэш.
После, на той же странице, где показан хэш, добавляем суперпользователя PostfixAdmin:
* где Setup password — пароль, который мы ввели на предыдущей странице; Пароль — новый пароль для создаваемой учетной записи.
В итоге мы увидим следующее:
И переходим в браузере на страницу http://<IP-адрес сервера>/postfixadmin/public/
Вводим логин и пароль для созданного пользователя.
Готово.
4. Настройка Postfix
По умолчанию, Postfix уже установлен в CentOS 7. Но если встретится сервер без него, выполним установку простой командой:
yum install postfix
Создаем учетную запись, от которой мы будем работать с каталогом виртуальных почтовых ящиков:
groupadd -g 1024 vmail
useradd -d /home/mail -g 1024 -u 1024 vmail -m
* сначала мы создаем группу vmail и guid 1024, после — пользователя vmail с uid 1024 и домашней директорией /home/mail. Обратите внимание, что в некоторых системах идентификатор группы и пользователя 1024 может быть занят. В таком случае необходимо создать другой, а в данной инструкции ниже заменить все 1024 на альтернативный.
Теперь открываем на редактирование конфигурационный файл почтового сервера:
vi /etc/postfix/main.cf
И редактируем следующие строки:
myorigin = $mydomain
* данная настройка указывает, какой домен подставлять отправителю, если он не указан в заголовке FROM.
mydestination = localhost.$mydomain, localhost, localhost.localdomain
* указываем, для каких доменов принимаем входящую почту.
local_recipient_maps = unix:passwd.byname $alias_maps
* указываем, откуда брать список локальных пользователей.
mynetworks = 127.0.0.0/8
* разрешаем отправлять сообщения локальному серверу.
alias_maps = hash:/etc/aliases
* указываем, откуда брать список алиасов.
inet_interfaces = all
* необходимо убедиться, что postfix будет слушать на всех необходимых интерфейсах, в данном случае, на всех (all). Также можно задать варианты loopback-only (127.0.0.1) или конкретный IP-адрес интерфейса.
inet_protocols = all
* данный параметр задаст протокол для работы postfix. В данном примере на всех (all). Также можно задать значения ipv4 или ipv6.
Если имя сервера отличается от имени, по которому сервер будет зарегистрирован в DNS, задаем опцию:
myhostname = mx01.test.ru
Теперь в конец конфигурационного файла допишем следующее:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
virtual_mailbox_base = /home/mail virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf virtual_minimum_uid = 1024 virtual_uid_maps = static:1024 virtual_gid_maps = static:1024 virtual_transport = dovecot dovecot_destination_recipient_limit = 1 smtpd_sasl_auth_enable = yes smtpd_sasl_exceptions_networks = $mynetworks smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_tls_cert_file = /etc/ssl/mail/public.pem smtpd_tls_key_file = /etc/ssl/mail/private.key smtpd_use_tls = yes smtpd_tls_auth_only = yes smtpd_helo_required = yes |
[/codesyntax]
* где:
- virtual_mailbox_base — базовый путь хранения почтовых ящиков в системе UNIX.
- virtual_alias_maps — формат и путь хранения алиасов для виртуальных пользователей.
- virtual_mailbox_domains — формат и путь хранения доменов виртуальных пользователей.
- virtual_mailbox_maps — формат и путь хранения почтовых ящиков для виртуальных пользователей.
- virtual_minimum_uid — с какого номера присваивать идентификаторы пользователям.
- virtual_uid_maps — идентификатор пользователя, от которого записываются сообщения.
- virtual_gid_maps — идентификатор группы, от которой записываются сообщения.
- virtual_transport — задает доставщика сообщений.
- dovecot_destination_recipient_limit — передача сообщений от Postfix в Dovecot выполняется по заданному количеству (в нашем примере, по 1 шт.).
- smtpd_sasl_auth_enable — разрешает sasl аутентификацию.
- smtpd_sasl_exceptions_networks — исключение сетей от использования шифрования.
- smtpd_sasl_security_options — дополнительные опции настройки sasl.
- broken_sasl_auth_clients — эту опцию прописываем для клиентов MS Outlook.
- smtpd_sasl_type — указывает тип аутентификации.
- smtpd_sasl_path — путь до временных файлов обмена информацией с Dovecot. Указывается либо абсолютный путь, либо относительный queue_directory (по умолчанию /var/spool/postfix). Итого, полный путь — /var/spool/postfix/private/auth.
- smtpd_tls_cert_file — полный путь до публичного сертификата.
- smtpd_tls_key_file — полный путь до приватного сертификата.
- smtpd_use_tls — указывает клиентам на наличие поддержки TLS.
- smtpd_tls_auth_only — использовать только TLS.
- smtpd_helo_required — требовать начинать сессию с приветствия.
Создаем файл с настройками обращения к базе с алиасами:
vi /etc/postfix/mysql_virtual_alias_maps.cf
[codesyntax lang="php"]
1 2 3 4 5 |
user = postfix password = postfix123 hosts = localhost dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = '1' |
[/codesyntax]
* где user и password — логин и пароль для подключения к MySQL; hosts — имя сервера баз данных (в нашем случае, локальный сервер); dbname — имя базы данных; query — шаблон запроса к данным.
Создаем файл с инструкцией получения данных по виртуальным доменам:
vi /etc/postfix/mysql_virtual_domains_maps.cf
[codesyntax lang="php"]
1 2 3 4 5 |
user = postfix password = postfix123 hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%u' |
[/codesyntax]
И файл с почтовыми ящиками:
vi /etc/postfix/mysql_virtual_mailbox_maps.cf
[codesyntax lang="php"]
1 2 3 4 5 |
user = postfix password = postfix123 hosts = localhost dbname = postfix query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1' |
[/codesyntax]
Открываем файл master.cf и дописываем в самый конец:
vi /etc/postfix/master.cf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
submission inet n - n - - smtpd -o smtpd_tls_security_level=may -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=/var/spool/postfix/private/auth -o smtpd_sasl_security_options=noanonymous -o smtpd_sasl_local_domain=$myhostname smtps inet n - n - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -d ${recipient} |
[/codesyntax]
* необходимо убедиться, что в содержимом файла нет других раскомментированных опций для submission, smtps и dovecot (по умолчанию, их нет). В данном случае, мы настроили работу postfix на портах 25, 465 и 587. В файле master.cf мы настраиваем работу вспомогательных сервисов для Postfix. Описание каждого сервиса начинается с новой строки без отступа. Затем идут настройки для сервиса и параметры запуска. Для примера, рассмотрим первую добавленную строку —
submission inet n - n - - smtpd:
- submission — имя сервиса. Возможно использование заранее определенных в postfix служб или создание своих. В данном примере submission для подключения MUA по порту 587 при отправке почты.
- inet — тип обслуживания. Возможны варианты inet (сокет TCP/IP), unix (потоковый сокет), unix-dgram (сокет дейтаграммы), fifo (именованный канал очереди), pass (потоковый сокет UNIX-домена).
- первый "n" — является ли сервис частным и должен быть ограниченным. Возможны варианты y или n. Для типа обслуживания inet может быть только n.
- первый "-" — работает ли служба с правами root. Возможны варианты y, n и -. Прочерк означает неприменимость данного параметра к конкретному сервису.
- второй "n" — должна ли служба работать в окружении chroot. Возможны варианты y или n.
- второй "-" — через какое время в секундах пробудить службу, если она неактивна.
- третий "-" — максимальное количество одновременно выполняемых процессов, которые может запустить данный сервис.
- smtpd — выполняемая команда.
* после команды идут аргументы ее запуска. Они могут переопределять параметры, заданные в main.cf. Каждый аргумент записывается с новой строки и начинается с двух пробелов. В данном примере мы используем слудующие аргументы:
- smtpd_tls_security_level — задает уровень безопасности с применением TLS. В данном примере may говорит о возможности его использования.
- smtpd_sasl_auth_enable — разрешает sasl аутентификацию.
- smtpd_sasl_type — указывает тип аутентификации.
- smtpd_sasl_path — путь до временных файлов обмена информацией с сервером хранения почты (в нашем случае Dovecot). Указывается либо абсолютный путь, либо относительный queue_directory.
- smtpd_sasl_security_options — дополнительные опции настройки sasl.
- smtpd_sasl_local_domain — добавить домен для пользователей, которые проходят smtp-аутентификацию.
- syslog_name — префикс названия службы при занесении ее в системный журнал.
- smtpd_tls_wrappermode — запускать ли службу в нестандартном режиме (для поддержки TLS).
- smtpd_client_restrictions — настройки ограничения клиентских соединений. В данном примере разрешить только авторизованных.
Перезапустим postfix:
systemctl restart postfix
5. Настройка Dovecot
Устанавливаем Dovecot с компонентом для работы с СУБД:
yum install dovecot dovecot-mysql
Настраиваем способ хранения сообщений:
vi /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/home/mail/%d/%u/
* в данном примере сообщения будут храниться в продвинутом формате maildir в каталоге /home/mail/<почтовый домен>/<логин пользователя>.
Настраиваем слушателя для аутентификации:
vi /etc/dovecot/conf.d/10-master.conf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 |
service auth { unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } unix_listener auth-userdb { mode = 0600 user = vmail group = vmail } } |
[/codesyntax]
* в данном примере мы настраиваем сервис для аутентификации и создаем два прослушивателя: /var/spool/postfix/private/auth — для возможности постфиксом использовать авторизацию через Dovecot (обращаем внимание, что /var/spool/postfix/private/auth — это тот же private/auth, который был прописан нами в postfix); auth-userdb — сокет для авторизации через dovecot-lda. Опция mode задает права на сокет, например, 666 позволит любому пользователю к нему подключиться; user и group задает пользователя и группу владельцев на сокет.
Настраиваем аутентификацию в Dovecot:
vi /etc/dovecot/conf.d/10-auth.conf
[codesyntax lang="php"]
1 2 |
#!include auth-system.conf.ext !include auth-sql.conf.ext |
[/codesyntax]
* в данном случае мы просто комментируем обычную аутентификацию и снимаем комментарий для использования sql-аутентификации.
Настраиваем использование шифрования:
vi /etc/dovecot/conf.d/10-ssl.conf
[codesyntax lang="php"]
1 2 3 |
ssl = required ssl_cert = </etc/ssl/mail/public.pem ssl_key = </etc/ssl/mail/private.key |
[/codesyntax]
* ssl = required укажет dovecot требовать от клиентов использования шифрования; ssl_cert — путь до открытого сертификата (также нами указывался в postfix); ssl_key — путь к закрытому ключу.
Настроим автоматическое создание каталогов при первом подключении пользователя к ящику:
vi /etc/dovecot/conf.d/15-lda.conf
lda_mailbox_autocreate = yes
Настраиваем подключение к нашей базе данных:
vi /etc/dovecot/conf.d/auth-sql.conf.ext
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
passdb { … args = /etc/dovecot/dovecot-sql.conf.ext } userdb { … args = /etc/dovecot/dovecot-sql.conf.ext } |
[/codesyntax]
* в данном примере мы указали на файл, в котором будут находиться настройки для получения пользователей и паролей из базы данных. Данная настройка является настройкой по умолчанию и, в большинстве случаев, ее не нужно менять без необходимости указать свой путь.
Создаем файл с настройками работы с mysql:
vi /etc/dovecot/dovecot-sql.conf.ext
[codesyntax lang="php"]
1 2 3 4 5 6 |
driver = mysql connect = host=localhost dbname=postfix user=postfix password=postfix123 default_pass_scheme = MD5-CRYPT password_query = SELECT password FROM mailbox WHERE username = '%u' user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u' user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u' |
[/codesyntax]
* в данном примере мы настроили запрос на получение данных из базы mysql (mariadb). password_query — запрос на получение пароля из таблицы mailbox; user_query — запрос на получение данных пользователя (домашняя почтовая директория, идентификатор 1024 (идентификатор созданного нами ранее пользователя vmail).
И, напоследок, настраиваем интерфейс, на котором будет слушать dovecot:
vi /etc/dovecot/dovecot.conf
listen = *
* по умолчанию, dovecot слушает также на ipv6 (listen = *, ::). Если на сервере не используется 6-я версия протокола TCP/IP, в логах dovecot появятся ошибки:
master: Error: service(imap-login): listen(::, 143) failed: Address family not supported by protocol
master: Error: service(imap-login): listen(::, 993) failed: Address family not supported by protocol
Генерируем сертификаты безопасности
Создаем каталог, в котором разместим сертификаты:
mkdir -p /etc/ssl/mail
И сгенерируем их следующей командой:
openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=relay.test.ru"
* сертификат сгенерирован на 1461 день, ключи subj могут быть произвольными, CN необходимо указать в соответствии с именем сервера, по которому мы будем подключаться к почте.
* если мы хотим использовать сертификат, который будет проходить все проверки безопасности, его нужно купить или запросить у Let's Encrypt. (РАССМОТРИМ ПОЛУЧЕНИЕ СЕРТИФИКАТА В САМОМ НИЗУ СТАТЬИ)
Запускаем dovecot:
systemctl enable dovecot
systemctl start dovecot
6. Создаем первый почтовый ящик и проверяем работу сервера
В браузере вводим в адресной строке путь до Postfixadmin — http://<IP-адрес сервера>/postfixadmin/public/.
Вводим логин и пароль от административной учетной записи, которую мы создали на шаге 3. Перед нами появится страница управления учетными записями.
Переходим в Список доменов - Новый домен:
Заполняем формы и нажимаем по Добавить домен:
Теперь переходим в Обзор - Создать ящик:
Вводим данные нового пользователя и нажимаем по Создать ящик:
Теперь можно подключиться к серверу с помощью любой почтовой программы, например, Mozilla Thunderbird.
Параметры для подключения:
- Сервер: имя сервера или его IP-адрес (не желательно, так как сертификат выдается по доменному имени).
- IMAP: 143 STARTTLS или 993 SSL/TLS
- POP3: 110 STARTTLS или 995 SSL/TLS
- SMTP: 25 STARTTLS или 465 SSL/TLS или 587 STARTTLS
* для корректной работы сервера на портах 993, 995, 465 (SSL/TLS) необходим правильный сертификат (для нашего домена и выпущенный доверенным центром сертификации).
7. Устанавливаем и настраиваем Roundcube Webmail
На официальном сайте заходим на страницу загрузки Roundcube. Смотрим ссылку на последнюю стабильную версию продукта (LTS):
Используем ссылку, чтобы загрузить архив программы:
wget https://github.com/roundcube/roundcubemail/releases/download/1.1.12/roundcubemail-1.1.12-complete.tar.gz
Создаем каталог, где будут размещаться файлы портала:
mkdir /usr/share/nginx/html/webmail
И распаковываем скачанный архив:
tar -C /usr/share/nginx/html/webmail -xvf roundcubemail-*.tar.gz --strip-components 1
Копируем шаблон конфига:
cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php
И открываем его на редактирование:
vi /usr/share/nginx/html/webmail/config/config.inc.php
$config['db_dsnw'] = 'mysql://roundcube:roundcube123@localhost/roundcubemail';
$config['enable_installer'] = true;
* первую строку мы редактируем, а вторую добавляем. В первой строке roundcube:roundcube123 — логин и пароль для доступа к базе данных; localhost — сервер базы данных; roundcubemail — имя базы данных. Вторая строка разрешает установку портала.
Также дописываем в конфигурационный файл следующее:
[codesyntax lang="php"]
1 2 3 4 5 |
$config['drafts_mbox'] = 'Drafts'; $config['junk_mbox'] = 'Junk'; $config['sent_mbox'] = 'Sent'; $config['trash_mbox'] = 'Trash'; $config['create_default_folders'] = true; |
[/codesyntax]
* настройка $config['create_default_folders'] = true создает папки по умолчанию, если их нет:
- Drafts — Черновики.
- Junk — СПАМ.
- Sent — Отправленные.
- Trash — Корзина.
* Без данной настройки, если не создавались папки другим клиентом, веб-клиент будет выдавать ошибки при пересещении писем, например, при их удалении.
Задаем владельца apache на папку портала:
chown -R apache:apache /usr/share/nginx/html/webmail
Создаем в MariaDB базу для roundcubemail:
mysql -uroot -p
> CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'roundcube123';
> quit
И загружаем в созданную базу данные:
mysql -uroot -p roundcubemail < /usr/share/nginx/html/webmail/SQL/mysql.initial.sql
Устанавливаем компоненты, необходимые для работы Roundcube:
yum install php-pear php-mcrypt php-intl php-ldap php-pear-Net-SMTP php-pear-Net-IDNA2 php-pear-Mail-Mime
Настроим php:
vi /etc/php.ini
date.timezone = "Europe/Moscow"
* в данном примере мы задаем московское время.
Перезагружаем php-fpm:
systemctl restart php-fpm
Теперь открываем браузер и переходим по адресу http://<IP-адрес сервера>/webmail/installer/. В самом низу нажимаем по кнопке Next. Если кнопка будет неактивна, проверяем, что нет ошибок (NOT OK).
На следующей странице проверяем, что все пункты находятся в состоянии OK. Установка выполнена.
Открываем конфигурационный файл roundcube:
vi /usr/share/nginx/html/webmail/config/config.inc.php
Запрещаем установку портала:
$config['enable_installer'] = false;
После удаляем папку с установочными скриптами:
\rm -R /usr/share/nginx/html/webmail/installer
И заходим в браузере по адресу http://<IP-адрес сервера>/webmail/.
8. Защищаемся от вирусов
Антивирус требует много ресурсов. Будьте готовы, что после его запуска сервер начнет работать медленнее и понадобится добавить ресурсы.
Установка и настройка ClamAV
Устанавливаем антивирус:
yum install clamav clamsmtp clamav-scanner-systemd clamav-update
Добавляем в postfix:
vi /etc/postfix/main.cf
content_filter = scan:[127.0.0.1]:10025
receive_override_options = no_address_mappings
* где content_filter указывает на приложение, которое будет сканировать сообщения; receive_override_options позволяет увидеть оригинальные email адреса писем с вирусами.
Теперь редактируем master.cf:
vi /etc/postfix/master.cf
Дописываем следующее:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
scan unix - - n - 16 smtp -o smtp_send_xforward_command=yes -o smtp_enforce_tls=no 127.0.0.1:10026 inet n - n - 16 smtpd -o content_filter= -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks -o smtpd_helo_restrictions= -o smtpd_client_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks_style=host -o smtpd_authorized_xforward_hosts=127.0.0.0/8 |
[/codesyntax]
* итак, данной настройкой мы создадим два вспомогательных сервиса scan и 127.0.0.1:10026 (сервис без имени, он просто будет слушать на порту 10026 — это порт по умолчанию, на который отправляет сообщение антивирусная программа clam после выполнения проверки). Также, мы используем следующие опции:
- smtp_send_xforward_command — передавать ли в сканирование сообщение с исходными именем клиента и IP-адресом. В данном примере, да.
- smtp_enforce_tls — требовать ли TLS.
- content_filter — приложение для сканирования. В данном примере сканирование отключено.
- receive_override_options переопределяет опции в main.cf. В нашем случае, no_unknown_recipient_checks отключает попытки выяснить, является ли получатель неизвестным; no_header_body_checks отключает проверки заголовков и тала писем.
- пустые значения для smtpd_helo_restrictions, smtpd_client_restrictions, smtpd_sender_restrictions отключают ограничения для данных опций.
- smtpd_recipient_restrictions — контролирует ответ Postfix на SMTP-команду RCPT TO. Здесь мы разрешаем только соединения от узлов, перечисленных в mynetworks.
- mynetworks_style=host указывает postfix, что он должен пересылать почту только с локального компьютера.
- smtpd_authorized_xforward_hosts укажет, какие удаленные клиенты могут использовать XFORWARD. В данном случае локальный компьютер.
Конфигурируем clamsmtpd:
vi /etc/clamsmtpd.conf
ClamAddress: /tmp/clamd.sock
* где ClamAddress указываем на путь к сокетному файлу — он должен совпадать с путем к LocalSocket в конфигурационном файле для clamscan;
Редактируем конфигурационный файл для clamscan:
vi /etc/clamd.d/scan.conf
[codesyntax lang="php"]
1 2 3 4 5 |
#Example ... LocalSocket /tmp/clamd.sock ... User clamsmtp |
[/codesyntax]
* где #Example — закомментированная Example, которая не позволит запустить сканер, пока ее не удалить или закомментировать;LocalSocket — путь до сокетного файла для взаимодействия с clamsmtp; User — пользователь, от которого будет запускаться clamd.
Обновляем антивирусную базу:
freshclam
Теперь разрешаем запуск антивируса:
systemctl enable clamsmtpd
systemctl enable clamd@scan
Запускаем clamscan:
systemctl start clamd@scan
* запуск может занять некоторое время. Если мы получим ошибку Job for clamd.service failed because timeout was exceeded, переходим к ее решению.(оно ниже, пролистай)
И после запускаем clamsmtpd:
systemctl start clamsmtpd
И также перезапускаем postfix:
systemctl restart postfix
Настройка обновлений антивируса
Для настройки автоматического обновления, редактируем cron:
crontab -e
15 3 * * * /bin/freshclam
* в данном примере, каждый день в 03:15 будет запускаться процесс обновления clamav.
Проверка
Для проверки отправляем сообщение со следующим содержимым:
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
Письмо не должно дойти, а в логе должны увидет строку:
Mar 22 15:50:03 mx01 postfix/smtp[6189]: B5BEDCAF3E0: to=<test01@test.local>, relay=127.0.0.1[127.0.0.1]:10025, delay=0.1, delays=0.01/0/0.04/0.04, dsn=2.0.0, status=sent (250 Virus Detected; Discarded Email)
9. Боремся со СПАМом
Проверка контента с помощью Spamassassin
Устанавливаем spamassassin:
yum install spamassassin
Редактируем master.cf:
vi /etc/postfix/master.cf
Для smtp добавляем опцию фильтра:
[codesyntax lang="php"]
1 2 |
smtp inet n - n - - smtpd -o content_filter=spamassassin |
[/codesyntax]
* в данном случае мы добавим к сервису postfix smtp дополнительную опцию content_filter, которая отвечает за запуск фильтрации контента; spamassassin указывает на имя сервиса, который будет запускаться для фильтрации.
И добавить сам сервис для фильтра:
[codesyntax lang="php"]
1 2 |
spamassassin unix - n n - - pipe flags=R user=spamd argv=/usr/bin/spamc -u spamd -e /usr/sbin/sendmail -f $sender $recipient |
[/codesyntax]
* spamassassin — добавляемый сервис фильтрации; /usr/bin/spamc — путь до исполняемого файла спамассасина; spamd — учетная запись, от которой запучкается spamassassin.
Создаем учетную запись spamd:
useradd spamd
Обновляем spamassassin:
sa-update --nogpg --verbose
Разрешаем его запуск и стартуем сервис:
systemctl enable spamassassin
systemctl start spamassassin
Перезапускаем postfix:
systemctl restart postfix
Для автоматического обновления добавим в cron следующее:
crontab -e
30 3 * * * /bin/sa-update
* обновление будет происходить каждый день в 03:30.
Для проверки работы контентного антиспама, отправляем письмо со следующим содержимым:
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
В итоге должно прийти письмо с меткой в теме [SPAM], а в логах мы увидим:
… spamd: identified spam (999.0/5.0) for spamd:1025 in 0.2 seconds, 695 bytes.
… spamd: result: Y 999 - ALL_TRUSTED,GTUBE scantime=0.2,size=695,user=spamd,uid=1025,required_score=5.0,rhost=localhost,raddr=127.0.0.1,rport=57254,mid=<20190328105822.3875FCAFD47@mx01.test.local>,autolearn=no autolearn_force=no
Исходящие письма
Мы настроили антиспам фильтр для smtp-соединения. В основном, он будет отрабатывать для входящей почты. Если нам необходимо также проверять исходящую почту, в master.cf добавляем content_filter для smtps и submission:
vi /etc/postfix/master.cf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
... submission inet n - n - - smtpd -o content_filter=spamassassin ... smtps inet n - n - - smtpd -o content_filter=spamassassin ... |
[/codesyntax]
Перезапускаем postfix:
systemctl restart postfix
Пересылка СПАМа на другой ящик
Все письма со спамом будут отправляться в ящик пользователя с пометкой в теме [SPAM]. Если мы хотим перенаправлять все подобные сообщения на специальный ящик, то необходимо настроить обработку заголовков с перенаправлением сообщений.
Открываем конфигурационный файл Postfix:
vi /etc/postfix/main.cf
Проверяем наличие строки:
header_checks = regexp:/etc/postfix/header_checks
… и если ее нет, то добавляем.
Открываем на редактирование файл:
vi /etc/postfix/header_checks
И добавляем строку:
/^SUBJECT:\s+\[SPAM\]/ REDIRECT spam@test.ru
Проверим, что мы все сделали правильно:
postmap -q "SUBJECT: [SPAM]" regexp:/etc/postfix/header_checks
Мы должны увидеть что-то на подобие:
REDIRECT spam@test.ru
Перезапускаем Postfix:
systemctl restart postfix
Антиспам средствами Postfix
В MTA Postfix встроен свой механизм проверки заголовков входящих сообщений. Правила размещаются в 7 секций, обработка которых выполняется в следующем порядке:
client -> helo -> sender -> relay -> recipient -> data -> end_of_data
Чтобы лучше понять принцип, мы должны знать SMTP-команды при выполнении отправки почты. И так, порядок, следующий:
- Соединение с сервером.
- Команда HELO. Приветствие, в котором отправитель называет свое имя, по которому можно проверить, соответствует ли оно правилам именования и своему IP-адресу.
- MAIL FROM — указывает адрес отправителя. Выполняется для sender и relay.
- RCPT TO — кому отправляем письмо.
- DATA — команда сообщает о готовности отправить письмо с заголовками и текстом.
- END-OF-DATA — отправка письма.
И так, для настройки антиспама в конфигурационный файл main.cf добавляем:
vi /etc/postfix/main.cf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_pipelining permit smtpd_helo_restrictions = permit smtpd_sender_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_sender reject_unknown_sender_domain permit smtpd_relay_restrictions = permit smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_recipient reject_unauth_destination reject_unknown_recipient_domain reject_unverified_recipient permit smtpd_data_restrictions = permit smtpd_end_of_data_restrictions = permit |
[/codesyntax]
* где параметры:
- smtpd_client_restrictions — настройки ограничений при осуществлении клиентских соединений с почтовым сервером.
- smtpd_helo_restrictions — ограничения в контексте клиентской команды HELO.
- smtpd_sender_restrictions — ограничения будут применяться во время выполнения клиентской команды MAIL FROM.
- smtpd_relay_restrictions — ограничения пересылки почты в контексте клиентской команды RCPT TO.
- smtpd_recipient_restrictions — ограничения в контексте клиентской команды RCPT TO после пересылки (smtpd_relay_restrictions).
- smtpd_data_restrictions — ограничения будут применяться во время выполнения команды DATA.
- smtpd_end_of_data_restrictions — ограничения во вреся выполнения команды END-OF-DATA.
… и значения для них:
- permit_mynetworks — разрешает все адреса, перечисленные в настройке mynetworks.
- permit_sasl_authenticated — разрешает запросы всех успешно авторизованных клиентов.
- reject_unauth_pipelining — запрещает отправку писем, которые отправляются заранее (пропуская правильную цепочку сессии SMTP).
- reject_non_fqdn_sender — отклонить соединение, если адрес отправителя указан неправильно (согласно RFC).
- reject_unknown_sender_domain — запрещает запрос, если Postfix не является конечным пунктом назначения для адреса отправителя, а домен MAIL FROM не имеет 1) DNS-записи MX и DNS-записи A или 2) искаженной MX-записи, такой как запись с MX-именем хоста нулевой длины.
- reject_non_fqdn_recipient — запретить соединение, если адрес получателя указан неправильно (согласно RFC).
- reject_unauth_destination — отклонить соединение, если письмо не пересылается согласно правилу relay_domains или сервер не является адресом назначения. Другими словами, запрещает использование нашего сервера в качестве open relay.
- reject_unknown_recipient_domain — отклонить запрос, если Postfix не является конечным пунктом назначения для домена получателя, а домен RCPT TO не имеет 1) DNS-записи MX и DNS-записи A или 2) неверно сформированной MX-записи, такой как запись с именем хоста MX нулевой длины.
- reject_unverified_recipient — отклонить запрос, если известно, что почта на адрес RCPT TO отклоняется или когда адрес получателя не доступен.
- permit — разрешает соединение. Ставим в конец каждого блока ограничений (если ограничения не сработали, то разрешаем).
* это более или менее мягкие правила. Их можно использовать первое время, пока тестируем сервер.
Для усиления защиты добавляем:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 |
smtpd_recipient_restrictions = ... reject_unknown_client_hostname reject_invalid_helo_hostname reject_non_fqdn_helo_hostname reject_unknown_helo_hostname reject_rbl_client bl.spamcop.net reject_rbl_client cbl.abuseat.org reject_rbl_client dul.ru reject_rbl_client dnsbl.abuse.ch permit |
[/codesyntax]
* где:
- reject_unknown_client_hostname — проверяет наличие PRT-записи отправителя и наличие рабочей А-записи в соответствие PTR.
- reject_invalid_helo_hostname — проверяет синтаксис HELO-приветствия.
- reject_non_fqdn_helo_hostname — требует правильного FQDN-имени во время HELO-приветствия.
- reject_unknown_helo_hostname — запрещает представляться именами, для которых нет А-записи или MX.
- reject_rbl_client — проверяет наличие отправителя в черных списках.
* более подробное описание опций для защиты можно найти на странице postfix.org/postconf.5.html.
После внесения всех правок, необходима перезагрузка Postfix:
systemctl restart postfix
10. Отправка почты наружу
Для отправки почты на другие почтовые серверы необходимо правильно сконфигурировать сервер, чтобы письма не попадали в СПАМ. Чтобы это сделать, выполняем инструкции ниже.
Настройки DNS для сервера
Многие почтовые серверы делают запросы в систему доменных имен для проверки легитимности почтового сервера, отправляющего почту. При настройке MTA очень важно правильно добавить необходимые записи в DNS.
1. rDNS. Обратная зона используется для проверки соответствия имени сервера в приветствии с именем, которое возвращает NS сервер при запросе по PTR-записи.
И так, для создания записи в обратной зоне, необходимо написать письмо Интернет провайдеру, к сети которого подключен сервер или хостеру, если почтовый сервер настроен на VPS. IP-адрес нашего сервера должен вести на имя, которым приветствуется наш postfix — можно посмотреть командой:
postconf -n smtpd_banner
Если мы получим пустой ответ, то вводим:
postconf -n myhostname
2. А-запись. Также необходимо, чтобы имя сервера, которым представляется почтовый сервер разрешалось в IP-адрес.
Для этого заходим в консоль управления зоной нашего домена и создаем запись типа А для сопоставления имени сервера с IP-адресом, на котором слушает запросы данный сервер.
Настройки DNS для домена
Для каждого домена, для которого будем отправлять почту создаем записи:
- SPF.
- DMARC.
Настройка DKIM
DKIM настраивается на сервере, а для каждого домена создается специальная запись в DNS.
1. Установка OpenDKIM
Для начала, устанавливаем пакет OpenDKIM. Он выполняет операции шифрования заголовков для DKIM, а также содержит набор утилит для формирования ключей.
Для его установки вводим следующее.
yum install opendkim opendkim-tools
2. Настройка OpenDKIM и Postfix
OpenDKIM
Переносим старый конфигурационный файл opendkim и создаем новый.
mv /etc/opendkim.conf /etc/backup.opendkim.conf
vi /etc/opendkim.conf
И приводим его к следующему виду:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
AutoRestart Yes AutoRestartRate 10/1h Umask 002 Syslog yes SyslogSuccess Yes LogWhy Yes Canonicalization relaxed/simple ExternalIgnoreList refile:/etc/opendkim/TrustedHosts InternalHosts refile:/etc/opendkim/TrustedHosts KeyTable refile:/etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable Mode sv PidFile /var/run/opendkim/opendkim.pid SignatureAlgorithm rsa-sha256 UserID opendkim:opendkim Socket inet:12301@localhost |
[/codesyntax]
* все параметры можно оставить, как в данном примере, за исключением Socket — можно указать любой другой порт, вместо 12301.
Создаем файл доверенных узлов. В него пока войдут имя локального хоста (localhost) и его IP-адрес, которые будут приняты, как доверенные и подписаны:
vi /etc/opendkim/TrustedHosts
И вносим следующее:
127.0.0.1
localhost
* в данный файл мы заносим все IP-адреса и сети почтовых серверов, которые могут использовать наш сервер как почтовый релей. Таким образом, если в вашей системе используется подобная конфигурация, в файл TrustedHosts мы должны добавить адреса данных почтовых серверов.
Открываем файл /etc/default/opendkim:
vi /etc/default/opendkim
… его либо не должно быть, либо он должен быть пустой, либо проверяем строку с настройкой SOCKET и приводим ее к виду:
SOCKET=inet:12301@localhost
Запускаем службу opendkim.
systemctl enable opendkim
systemctl start opendkim
Postfix
Открываем конфигурационный файл.
vi /etc/postfix/main.cf
Добавляем или редактируем:
[codesyntax lang="php"]
1 2 3 4 |
milter_protocol = 2 milter_default_action = accept smtpd_milters = inet:localhost:12301 non_smtpd_milters = inet:localhost:12301 |
[/codesyntax]
* если smtpd_milters и non_smtpd_milters присутствуют в конфигурационном файле, то приведенные в данном примере значения нужно дописать к имеющимся.
** 12301 — порт работы opendkim, который был задан в opendkim.conf.
Перезапускаем Postfix:
service postfix restart
или:
systemctl restart postfix
3. Создание сертификата и настройка домена
Для создания сертификата можно воспользоваться бесплатным онлайн инструментом на сайте dkimcore.org. Однако, в данном примере, мы воспользуемся opendkim-genkey и сформируем его самостоятельно. Мы будем работать с доменом test.ru (Вам необходимо его заменить своим).
И так, создаем каталог для размещения ключей домена:
mkdir -p /etc/opendkim/test.ru
И генерируем их следующей командой:
opendkim-genkey -D /etc/opendkim/test.ru/ --domain test.ru --selector relay
* где test.ru — домен, с которого будет отправляться почта: relay — имя селектора (селектор — это строковый идентификатор, он может быть любым).
В папке /etc/opendkim/test.ru должно появиться два файла с расширениями .private и .txt. Первый — закрытый ключ (храним его у себя на сервере), второй — готовая txt-запись для DNS.
Задаем группу владельца opendkim для созданных ключей:
chown :opendkim /etc/opendkim/test.ru/*
Если система выдаст ошибку, что группы opendkim не существует (chown: opendkim: illegal group name), необходимо сначала создать учетную запись.
Задаем права для группы владельца:
chmod g+rw /etc/opendkim/test.ru/*
Создадим пользователя opendkim.
useradd opendkim -m -s /sbin/nologin
После разрешаем чтение группе владельцу:
chmod g+r /etc/opendkim/test.ru/*
Открываем созданный нами ранее TrustedHosts:
vi /etc/opendkim/TrustedHosts
И добавим следующее:
…
*.test.ru
* где test.ru — почтовый домен.
Создаем таблицу KeyTable. В ней хранится список соответствий между селекторами, доменами и файлами с закрытыми ключами. Формат записей:
<селектор>._domainkey.<домен> <домен>:<селектор>:<путь к закрытому ключу>
vi /etc/opendkim/KeyTable
И в соответствии с форматом приводим его к нужному виду:
relay._domainkey.test.ru test.ru:relay:/etc/opendkim/test.ru/relay.private
И напоследок, создаем SigningTable. В данной таблице хранятся соответствия между определенными email-адресами и записями в KeyTable.
vi /etc/opendkim/SigningTable
И приводим к такому виду:
*@test.ru relay._domainkey.test.ru
4. Настройка DNS
Смотрим содержимое файла txt, который был сформирован при генерировании сертификата для домена:
cat /etc/opendkim/test.ru/relay.txt
* где test.ru — домен, для которого производилась настройка.
И используя данное содержимое, в панели управления нашим DNS создаем TXT-запись следующего формата:
relay._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqG…rhyaj8OcbwIDAQAB"
* где relay — название нашего селектора MIGfMA0GCSqG…rhyaj8OcbwIDAQAB — сокращенная запись открытого ключа (она длиннее).
Дополнительные необязательные записи
_domainkey IN TXT "o=~; r=postmaster@test.ru"
* где o=~ означает, что не все сообщения подписываются для домена (o=- — говорит, что все письма используют DKIM).
_adsp._domainkey IN TXT "dkim=all"
* all запрещает принимать письма от домена без цифровой подписи. Другие варианты: discardable — блокировать сообщения на стороне получателя, unknown — по умолчанию (такую запись создавать не обязательно).
5. Проверка
Отправляем письмо
Отправляем электронное сообщение на различные почтовые системы — mail.ru, gmail.com, yandex.ru.
Способов отправки несколько, например, можно выполнить следующие команды.
yum install mailx
* данная команда установит утилиту для отправки почты из командной строки, если ее нет.
echo "Test DKIM" | mail -s "Testing DKIM" -S smtp="localhost:25" -S from="postmaster@test.ru" -S return-path="postmaster@test.ru" master@test.ru
* где postmaster@test.ru — почтовый ящик, от которого отправляется письмо (напомню, в данном примере подпись создается для домена test.ru), master@test.ru — должен быть Ваш адрес почты, на который придет письмо.
Второй способ — настроить почтовый клиент, который будет отправлять почту через настроенный нами сервер.
Проверяем заголовки
Открываем наше письмо и смотрим заголовки (в mail.ru: Еще - Служебные заголовки).
Среди них мы должны увидеть следующую строчку:
dkim=pass header.d=test.ru
Проверка домена на базе DKIM настроена успешно.
Добавление новых записей dkim
Разберем процесс добавления дополнительных записей dkim. Чтобы работать было удобнее и быстрее, в консоли создадим переменную, значением которой должен быть наш домен:
DKIM_DOMAIN=domain.zone
* где вместо domain.zone ставим наш домен.
Создаем каталог для размещения ключей домена:
mkdir -p /etc/opendkim/$DKIM_DOMAIN
Генерируем ключ:
opendkim-genkey -D /etc/opendkim/$DKIM_DOMAIN/ --domain $DKIM_DOMAIN --selector relay
Задаем нужные права:
chown :opendkim /etc/opendkim/$DKIM_DOMAIN/*
chmod g+rw /etc/opendkim/$DKIM_DOMAIN/*
Смотрим содержимое файла txt:
cat /etc/opendkim/$DKIM_DOMAIN/relay.txt
… и используя данное содержимое, в панели управления нашим DNS создаем TXT-запись.
Добавляем соответствующие настройки в файлы TrustedHosts, KeyTable, SigningTable:
echo "*.$DKIM_DOMAIN" >> /etc/opendkim/TrustedHosts
echo "relay._domainkey.$DKIM_DOMAIN $DKIM_DOMAIN:relay:/etc/opendkim/$DKIM_DOMAIN/relay.private" >> /etc/opendkim/KeyTable
echo "*@$DKIM_DOMAIN relay._domainkey.$DKIM_DOMAIN" >> /etc/opendkim/SigningTable
Перезапускаем службу.
systemctl reload opendkim
Готово.
Что дальше
Чтобы отправка сообщений стала еще надежнее, сделайте следующее:
- Убедитесь, что для домена отправки существует правильная запись SPF. Данная запись прописывается как TXT-запись в системе DNS и говорит, с каких почтовых серверов может быть отправлена почта для домена.
- Настройте DMARC. Это политики, которые говорят почтовому серверу, что нужно делать с письмами. Требует настроенных SPF и DKIM.
Решение проблем
Большинство трудностей решается чтением логов. Для opendkim они будут попадать в общий log-файл почты. Включить его непрерывный просмотр можно следующей командой.
tail -f /var/log/maillog
Также, очень часто, проблемы возникают из-за неправильной настройки прав на ключи. Нужно иметь ввиду, что некоторые системы, из соображений безопасности, выдают ошибку, если на файлы выданы слишком широкие права на чтение. То есть, если разрешить читать файлы всем (chmod 644), система будет возвращать ошибку. Если в логах видим «error loading key», скорее всего, проблема с правами. Внимательно выполните повторно рекомендации 2-о пункта данной инструкции.
Еще одно часто появляющееся сообщение — «opendkim no signing table match for». Оно говорит, что для домена, от которого отправляется почта, нет соответствий в файле SigningTable. Либо была допущена опечатка, либо, на самом деле, для домена отправки не нужно использовать DKIM.
Возможные проблемы
1. Job for clamd.service failed because timeout was exceeded
Появляется при попытке запустить службу clamd.
Причина: сервис стартует так долго, что время, которое отведено на его запук заканчивается.
Решение: увеличиваем время, в течение которого может стартовать сервис. Для этого открываем файл настройки юнита systemd для clamd:
vi /usr/lib/systemd/system/clamd.service
В раздел [Service] добавляем:
[codesyntax lang="php"]
1 2 3 4 5 6 |
... [Service] ... TimeoutSec=900 ... |
[/codesyntax]
Перечитываем юнит:
systemctl daemon-reload
Снова пробуем запустить clamscan:
systemctl start clamd@scan
==============================================
Условия получения бесплатного сертификата от Let's Encrypt
Прежде чем начать, необходимо знать о некоторых нюансах получения сертификата Let's Encrypt:
- При запросе выполняется проверка домена. Для этого необходимо:
- либо создать TXT-запись в DNS.
- либо поднять веб-сервер, далее в его корне создается каталог .well-known, а в нем файл с произвольным названием. После корневой центр отправляет запрос серверу на загрузку данного файла и, в случае успеха, выдает сертификаты для указанного доменного имени.
- SSL-сертификат выдается на 90 дней, поэтому необходимо по расписанию запускать команду на автоматическое продление ключа. Когда проходит 60 дней после начала использования нового сертификата, центр Let's Encrypt может выдать новый.
- Если выполнять запрос для домена 3 уровня и выше, он должен пройти DNS проверку на всех уровнях. Например, домен layer3.layer2.com должен отвечать на запросы как для layer3.layer2.com, так и для layer2.com.
Проверка домена
Как было сказано выше, для получения бесплатного сертификата, Let's Encrypt должен удостовериться, что мы являемся владельцем домена. Свое право на его владение мы можем подтвердить, создав специальную TXT-запись или настроив веб-сервис, который будет отвечать на запросы.
Пример простого конфигурационного файла для NGINX:
[codesyntax lang="php"]
1 2 3 4 5 |
server { listen 80; server_name test.ru; root /usr/share/nginx/html; } |
[/codesyntax]
* где test.ru — домен, для которого работает сайт и для которого мы будем запрашивать сертификат; /usr/share/nginx/html — путь по умолчанию для nginx.
Если сервер уже используется для сайта, в секцию server добавляем:
[codesyntax lang="php"]
1 2 3 4 |
location ~ /.well-known { root /usr/share/nginx/html; allow all; } |
[/codesyntax]
* данными строчками мы говорим, что для всех запросов после /.well-known необходимо отдавать скрипты из каталога /usr/share/nginx/html; allow all предоставляет доступ всем.
При необходимости выполнять проверку и использовать rewrite/return, добавляем что-то подобное:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
... location ~ /.well-known { root /usr/share/nginx/html; allow all; } if ($uri !~ /.well-known){ rewrite ^ https://…; } |
[/codesyntax]
После проверяем конфигурацию и перезапускаем nginx:
nginx -t
service nginx reload
С помощью записи в DNS
Данный метод проще, но он позволит настроить автоматическое продление сертификата только для некоторых DNS, для которых есть отдельные certbot-плагины. Поэтому данный способ, в большинстве случаев, будет удобен для проведения тестов.
У нас должна быть возможность управления записями в DNS. На данном этапе достаточно просто зайти в панель управления DNS и перейти к этапу получения сертификата (ниже по тексту). Если домен новый и был только-что делегирован на DNS, возможно, придется подождать, пока он не станет доступен для всех серверов DNS в глобальной сети.
Установка утилиты для получения сертификата
Certbot для Linux
а) на CentOS 8:
dnf --enablerepo=PowerTools install certbot
б) на CentOS 7:
yum install certbot
в) на Ubuntu 16.04 и выше:
apt-get install certbot
г) на CentOS 6 или Ubuntu 14.04:
Создадим каталог, в котором будет храниться утилита и переходим в него:
mkdir /opt/certbot
cd /opt/certbot
Загружаем утилиту и разрешаем ее запуск:
wget https://dl.eff.org/certbot-auto
chmod a+x ./certbot-auto
Для удобства, делаем симлинк:
ln -s /opt/certbot/certbot-auto /opt/certbot/certbot
* при первом запуске certbot он автоматически предложит доустановить необходимые зависимости.
Первое получение сертификата
1. Если мы подтверждаем право на домен при помощи веб-сервера, выполняем такую команду:
certbot certonly --webroot --agree-tos --email postmaster@test.ru --webroot-path /usr/share/nginx/html/ -d test.ru -d www.test.ru
* на системах CentOS 6 или Ubuntu 14.04 вместо certbot прописываем полный путь до установленного пакета — /opt/certbot/certbot.
* где для двух команд:
- certonly — запрос нового сертификата;
- manual — проверка домена вручную.
- preferred-challenges — указывает метод проверки домена.
- webroot — проверка будет выполняться на основе запроса к корню сайта;
- agree-tos — даем согласие на лицензионное соглашение;
- email — почтовый адрес администратора домена;
- webroot-path — каталог в системе Linux, который является корневым для сайта;
- d — перечисление доменов, для которых запрашиваем сертификат.
После успешного выполнения команды, сертификаты будут созданы в каталоге /etc/letsencrypt/archive/test.ru, а также симлинки на них в каталоге /etc/letsencrypt/live/test.ru. При настройке приложений, стоит указывать пути до симлинков, так как при обновлении файлы в первом каталоге будут меняться, во втором — нет. Публичный ключ будет с именем cert.pem, а приватный — privkey.pem.
2. При подтверждении права на домен с TXT-записью:
certbot certonly --manual --agree-tos --email postmaster@test.ru --preferred-challenges=dns -d test.ru -d www.test.ru
На запрос подтверждения отвечаем Y — система выдаст что-то на подобие:
Please deploy a DNS TXT record under the name
_acme-challenge.test.ru with the following value:
W2SC9b88y2j2oUjhxVgS7Bphph9g5PqhkBq9KiWkLTm
Once this is deployed,
* Данное сообщение говорит, что мы должны создать TXT-запись _acme-challenge.test.ru со значением W2SC9b88y2j2oUjhxVgS7Bphph9g5PqhkBq9KiWkLTm.
Создаем соответствующую запись в панели управления DNS, и в консоли сервера нажимаем Enter для продолжения. Если, как в данном примере, мы запрашиваем сертификат для нескольких узлов, повторяем действия.
Автоматическое продление
Смотрим полный путь до скрипта certbot:
which certbot
Открываем на редактирование cron и добавляем следующее:
crontab -e
0 0 * * 1,4 /bin/certbot renew
* в данном примере проверка и продление сертификата будет выполняться по понедельникам и четвергам (1,4) в 00:00. /bin/certbot — путь, который мне выдала команда which certbot.
Команда certbot renew проверяет для всех наших сертификатов срок окончания, и если осталось менее 30 дней, запрашивает новый, сохраняет его в каталоге /etc/letsencrypt/archive/<домен> и обновляет симлинк.
Стоит иметь ввиду, что многие приложения, использующие сертификат, потребуют перезапуска, чтобы перечитать его. Поэтому хорошей идеей будет не просто обновлять сертификат, но и перезапускать сервис, который использует сертификат. Например, для NGINX:
0 0 * * 1,4 /bin/certbot renew && systemctl reload nginx
Wildcard
С марта 2018 года появилась возможность получить бесплатный сертификат на все поддомены, например, mail.test.ru, test.test.ru, admin.test.ru (*.test.ru).
Особенности получения Wildcard от Let's Encrypt:
- Подтвердить право использования доменом можно только с помощью DNS — таким образом, затрудняется процесс автоматического продления. Нужно использовать плагины, которые позволяют автоматически создавать нужную запись на DNS, но они доступны далеко не для всех поставщиков услуг DNS. В противном случае, обновлять Wildcard нужно вручную.
Также, некоторые панели управления хостингом, например ISP Manager с версии 5 могут управлять процессом получения Wildcard от Let's Encrypt с возможностью автоматического продления (но необходимо, чтобы домен обслуживался на данном хостинге). - Время действия сертификата также ограничено 3 месяцами.
Certbot
Необходимо, чтобы версия утилиты certbot была 0.22.0 и выше. Проверить текущую версию можно командой:
certbot --version
… если версия ниже, обновляем ее командами:
а) для CentOS / Red Hat:
yum update certbot
б) для Ubuntu / Debian:
apt-get install --only-upgrade certbot
Процесс получения
Процесс очень похож на процесс получения сертификата с подтверждением домена в DNS.
Вводим команду:
certbot certonly --manual --agree-tos --email master@test.ru --server https://acme-v02.api.letsencrypt.org/directory --preferred-challenges=dns -d test.ru -d *.test.ru
* обратим внимание на 2 детали: 1) мы добавили опцию server, чтобы указать, на каком сервере Let's Encrypt должна проходить проверка DNS; 2) мы получаем сертификат как для *.test.ru, так и самого test.ru, так как первое не включает второго.
… система попросит создать TXT-запись в DNS, который обслуживает наш домен:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.test.ru with the following value:
DN8ovKFJ0leLQV9ofZ81mYKxojwIaed5g6f0bXZCYiI
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* в данном примере система попросила создать TXT-запись _acme-challenge.test.ru со значением DN8ovKFJ0leLQV9ofZ81mYKxojwIaed5g6f0bXZCYiI.
Заходим в панель управления DNS и создаем нужную запись. Если у нас свой сервер DNS, например, bind, то строка будет такой:
; TXT
_acme-challenge IN TXT DN8ovKFJ0leLQV9ofZ81mYKxojwIaed5g6f0bXZCYiI
Не торопимся нажимать Enter — после настройки DNS нужно немного времени (пару минут), чтобы настройка применилась. Проверить появление записи можно командой с рабочего компьютера:
nslookup -type=txt _acme-challenge.test.ru 8.8.8.8
Как только видим, что настройки применились, нажимаем Enter — если это наш первый запрос Wildcard для данного домена, то система нас попросит создать еще одну запись — повторяем процедуру, создав в DNS вторую запись TXT.
Если все сделали правильно, то увидим:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/test.ru/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/test.ru/privkey.pem
Your cert will expire on 2019-09-05. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
… сертификат получен.