Настройка NGINX для проксирования почты

Thank you for reading this post, don't forget to subscribe!

NGINX мож­но исполь­зо­вать не толь­ко в каче­стве веб-сер­ве­ра или http-proxy, но и для прок­си­ро­ва­ния почты по про­то­ко­лам SMTP, IMAP, POP3. Это поз­во­лит настроить:

  • Еди­ную точ­ку вхо­да для мас­шта­би­ру­е­мой поч­то­вой системы.
  • Балан­си­ров­ку нагруз­ки меж­ду все­ми поч­то­вы­ми серверами.

В дан­ной ста­тье уста­нов­ка выпол­ня­ет­ся на опе­ра­ци­он­ной систе­ме Linux. В каче­стве поч­то­во­го сер­ви­са, на кото­рый пере­да­ют­ся запро­сы мож­но исполь­зо­вать postfix, exim, dovecot, exchange, сбор­ку iredmail и другое.

Принцип работы

NGINX при­ни­ма­ет запро­сы и выпол­ня­ет аутен­ти­фи­ка­цию на веб-сер­ве­ре. В зави­си­мо­сти от резуль­та­та про­вер­ки логи­на и паро­ля, прок­си вер­нет ответ с несколь­ки­ми заголовками.

В слу­чае успеха:

Заго­ло­вок Ответ Опи­са­ние
HTTP/1.0 200 OK Заго­ло­вок от HTTP-сер­ве­ра. Обыч­но, 200. Если заго­ло­вок дру­гой, то про­бле­ма может быть с самим веб-сервером.
Auth-Status OK Резуль­тат про­вер­ки логи­на и пароля.
Auth-Server <host> Поч­то­вый сер­вер (имя сер­ве­ра или его IP-адрес), на кото­рый пере­на­прав­ля­ем запросы.
Auth-Port <port> Порт поч­то­во­го сер­ве­ра, на кото­рый пере­на­прав­ля­ем запросы.

Таким обра­зом, сер­вер и порт поч­то­во­го сер­ве­ра мы опре­де­ля­ем на осно­ве аутен­ти­фи­ка­ции. Это дает мно­го воз­мож­но­стей при соот­вет­ству­ю­щих зна­ни­ях язы­ков программирования.

В слу­чае неудачи:

Заго­ло­вок Ответ Опи­са­ние
HTTP/1.0 200 OK Заго­ло­вок от HTTP-сер­ве­ра. Обыч­но, 200. Если заго­ло­вок дру­гой, то про­бле­ма может быть с самим веб-сервером.
Auth-Status <message> Сооб­ще­ние об ошиб­ке при про­вер­ки пользователя.
Auth-Wait <number> Чис­ло остав­ших­ся попы­ток аутен­ти­фи­ка­ции до закры­тия сессии.

В зави­си­мо­сти от резуль­та­та аутен­ти­фи­ка­ции и заго­лов­ком, кли­ент пере­на­прав­ля­ет­ся на нуж­ный нам поч­то­вый сервер.

Подготовка сервера

Вне­сем неко­то­рые прав­ки в настрой­ки без­опас­но­сти сервера.

SELinux

Отклю­ча­ем SELinux, если исполь­зу­ем CentOS или если исполь­зу­ем дан­ную систе­му без­опас­но­сти на Ubuntu:

vi /etc/selinux/config
SELINUX=disabled
setenforce 0

Брандмауэр

Если исполь­зу­ем firewalld

firewall-cmd --permanent --add-port=25/tcp --add-port=110/tcp --add-port=143/tcp
firewall-cmd --reload

Если исполь­зу­ем iptables

iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 143 -j ACCEPT

apt-get install iptables-persistent
iptables-save > /etc/iptables/rules.v4

* в дан­ном при­ме­ре мы раз­ре­ши­ли SMTP (25), POP3 (110), IMAP (143).

Установка NGINX

В зави­си­мо­сти от опе­ра­ци­он­ной систе­мы, уста­нов­ка NGINX немно­го отличается.

или Linux Centos:

yum install nginx

или Linux Ubuntu:

apt install nginx

Раз­ре­ша­ем авто­за­пуск сер­ви­са и запус­ка­ем его:

systemctl enable nginx
systemctl start nginx

Если в систе­ме уже уста­нов­лен NGINX, про­ве­ря­ем с каки­ми моду­ля­ми он работает:

nginx -V

Мы полу­чим спи­сок опций, с кото­ры­ми собран веб-сер­вер — сре­ди них мы долж­ны уви­деть --with-mail. Если нуж­но­го моду­ля нет, нуж­но обно­вить nginx

Настройка NGINX

Откры­ва­ем кон­фи­гу­ра­ци­он­ный файл nginx и добав­ля­ем опцию mail:

vi /etc/nginx/nginx.conf

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

* где:

  • server_name — имя поч­то­во­го сер­ве­ра, кото­рое будет отоб­ра­жать­ся при SMTP-приветствии.
  • auth_http — веб-сер­вер и URL для запро­са аутентификации.
  • proxy_pass_error_message — раз­ре­ша­ет или запре­ща­ет показ сооб­ще­ния при неудач­ной аутентификации.
  • listen — порт, на кото­ром про­слу­ши­ва­ют­ся запросы.
  • protocol — про­то­кол при­ло­же­ния, для кото­ро­го про­слу­ши­ва­ет­ся соот­вет­ству­ю­щий порт.
  • smtp_auth — доступ­ные мето­ды аутен­ти­фи­ка­ции для SMTP.
  • pop3_auth — доступ­ные мето­ды аутен­ти­фи­ка­ции для POP3.

В сек­ции http - server дописываем:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

* в дан­ном при­ме­ре мы доба­ви­ли пра­ви­ло обра­бот­ки фай­лов php через FastCGI, кото­рый будет рабо­тать на локаль­ном сер­ве­ре, пор­ту 9000. Домаш­няя дирек­то­рия для хра­не­ния скрип­тов — /usr/share/nginx/html.

Пере­за­пус­ка­ем сер­вер nginx:

systemctl restart nginx

Установка и настройка PHP

Для выпол­не­ния аутен­ти­фи­ка­ции с помо­щью PHP, необ­хо­ди­мо уста­но­вить в систе­му сле­ду­ю­щие пакеты.

yum install php php-fpm

Запус­ка­ем PHP-FPM:

systemctl enable php-fpm
systemctl start php-fpm

Аутентификация

Про­вер­ка логи­на и паро­ля выпол­ня­ет­ся скрип­том, путь до кото­ро­го зада­ет­ся опци­ей auth_http. В нашем при­ме­ре, это скрипт на PHP.

При­мер офи­ци­аль­ной заго­тов­ки для скрип­та про­вер­ки логи­на и пароля:

vi /usr/share/nginx/html/auth.php

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

* дан­ный скрипт при­ни­ма­ет любые логин и пароль и пере­на­прав­ля­ет запро­сы на сер­ве­ры 192.168.1.22 и 192.168.1.33. Что­бы задать алго­ритм аутен­ти­фи­ка­ции, редак­ти­ру­ем стро­ки 61 - 64. За воз­врат сер­ве­ров, на кото­рые идет пере­на­прав­ле­ние отве­ча­ют стро­ки 73 - 77 — в дан­ном при­ме­ре если логин начи­на­ет­ся на сим­во­лы "a", "c", "f", "g", то пере­на­прав­ле­ние будет на сер­вер mailhost01, ина­че, на mailhost02. Сопо­став­ле­ние имен сер­ве­ров с IP-адре­са­ми мож­но задать на стро­ках 31, 32, в про­тив­ном слу­чае, обра­ще­ние будет идти по домен­но­му имени.

Настройка почтового сервера

Обмен дан­ны­ми меж­ду NGINX прок­си и поч­то­вым сер­ве­ром идут в откры­том виде. Необ­хо­ди­мо доба­вить в исклю­че­ние воз­мож­ность аутен­ти­фи­ка­ции по меха­низ­му PLAIN. Напри­мер, для настрой­ки dovecot, дела­ем следующее:

vi /etc/dovecot/conf.d/10-auth.conf

Добав­ля­ем строки:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

* в дан­ном при­ме­ре мы раз­ре­ши­ли PLAIN-запро­сы на аутен­ти­фи­ка­цию с сер­ве­ра 192.168.1.11.

Так­же проверяем:

ssl = yes

* если ssl будет иметь зна­че­ние required, про­вер­ка не будет рабо­тать, так как полу­чит­ся, что с одной сто­ро­ны сер­вер раз­ре­ша­ет запро­сы в откры­том виде, но тре­бу­ет шиф­ро­ва­ние ssl.

Пере­за­пус­ка­ем Dovecot сервис:

systemctl restart dovecot

Настройка клиента

Мож­но перей­ти к про­вер­ки настрой­ки наше­го прок­си. Для это­го в настрой­ках кли­ен­та в каче­стве IMAP/POP2/SMTP ука­зы­ва­ем адрес или имя сер­ве­ра nginx, например:

* в дан­ном при­ме­ре поч­то­вый кли­ент настра­и­ва­ет­ся для под­клю­че­ния к сер­ве­ру 192.168.1.11 по откры­тым пор­там 143 (IMAP) и 25 (SMTP).

Шифрование

Теперь настро­им SSL-под­клю­че­ние. Nginx дол­жен быть собран с моду­лем mail_ssl_module — про­ве­ря­ем командой:

nginx -V

При отсут­ствии необ­хо­ди­мо­го моду­ля, пере­со­би­ра­ем nginx. После редак­ти­ру­ем наш кон­фи­гу­ра­ци­он­ный файл:

vi /etc/nginx/nginx.conf

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Гене­ри­ру­ем сертификат:

mkdir -p /etc/ssl/nginx

openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/nginx/public.crt -keyout /etc/ssl/nginx/private.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=test.test.ru/CN=test"

* где /etc/ssl/nginx/ — ката­лог хра­не­ния сер­ти­фи­ка­тов, subj — инди­ви­ду­аль­ные настрой­ки для сертификата.

Пере­за­пус­ка­ем nginx:

systemctl restart nginx

Логирование

Для ана­ли­за оши­бок вклю­ча­ем сохра­не­ние лога в файл:

vi /etc/nginx/nginx.conf

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Пере­за­пус­ка­ем nginx:

systemctl restart nginx

Про­смотр лога запус­ка­ем командой:

tail -f /var/log/nginx/mail_proxy_error

Возможные проблемы

bind() to x.x.x.x:XXX failed (13: Permission denied)Ошиб­ка воз­ни­ка­ем при попыт­ке пере­за­пу­стить служ­бу nginx. При этом, про­вер­ка кон­фи­гу­ра­ци­он­но­го фай­ла коман­дой nginx -t про­хо­дит корректно.

При­чи­на: сра­ба­ты­ва­ет систе­ма без­опас­но­сти SELinux.

Реше­ние: отклю­чить или настро­ить SELinux.