конфигурация полгода отработала в продакшене, проблем не наблюдалось
сертфикат. выпускаем через certbot, рисуем скрипт на автоообновление: /root/scripts/work/certbot.sh
Код: Выделить всё
#!/bin/sh
service nginx stop
certbot renew
chmod 755 /usr/local/etc/letsencrypt/archive
chmod 755 /usr/local/etc/letsencrypt/live
chmod 755 /usr/local/etc/letsencrypt/live/*/*
service nginx start
Код: Выделить всё
rproxy.canada-pindoss.local# crontab -l -u toor
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
MAILTO=""
@weekly sh /root/scripts/work/certbot.sh
конфиг /usr/local/etc/nginx/nginx.conf
Код: Выделить всё
# модуль проксирования почты. пришлось собирать из портов, по дефолту его нет в сборке из пакетов
load_module "/usr/local/libexec/nginx/ngx_mail_module.so";
........
http {
............
# первый виртуалхост
server {
listen 80 default_server;
server_name "";
# location = /basic_status {
# stub_status;
# allow 127.0.0.1;
# allow 10.181.160.0/19;
# deny all;
# }
# php-fpm
location ~ \.php$ {
set $root_path /usr/local/www/nginx;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $root_path;
}
# return 444;
}
..........
}
# проксирование почты
mail {
server_name mx.canada-pindoss.pro;
ssl_certificate /usr/local/etc/letsencrypt/live/mx.canada-pindoss.pro/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/mx.canada-pindoss.pro/privkey.pem;
ssl_session_timeout 5m;
xclient off;
starttls on;
proxy on;
error_log /var/log/nginx/mail_proxy_error.log info;
auth_http localhost/mail.auth.php;
proxy_pass_error_message on;
server {
listen 25;
protocol smtp;
smtp_auth none login plain cram-md5;
proxy_smtp_auth on;
}
server {
listen 465;
protocol smtp;
smtp_auth none login plain cram-md5;
proxy_smtp_auth on;
}
server {
listen 587;
protocol smtp;
smtp_auth none login plain cram-md5;
proxy_smtp_auth on;
}
server {
listen 110;
protocol pop3;
pop3_auth plain apop cram-md5;
}
server {
listen 143;
protocol imap;
}
server {
listen 993 ssl;
protocol imap;
}
}
Код: Выделить всё
hostlist relay_from_hosts = localhost : @ : 127.0.0.0/8 : !192.168.120.20 : 192.168.0.0/16
Код: Выделить всё
<?php
/*
NGINX sends headers as
Auth-User: somuser
Auth-Pass: somepass
On my php app server these are seen as
HTTP_AUTH_USER and HTTP_AUTH_PASS
*/
ob_start();
$Line = "\n" . date('Y-m-d G:i:s') . ": " . $_SERVER['HTTP_CLIENT_IP'] . ", " . $_SERVER["HTTP_AUTH_USER"] . ", " . $_SERVER["HTTP_AUTH_PASS"] . ", " . $_SERVER["HTTP_AUTH_PROTOCOL"];
Logg($Line);
if (!IsSet($_SERVER["HTTP_AUTH_USER"] ) || !IsSet($_SERVER["HTTP_AUTH_PASS"] )){
fail();
//Pass('mx.canada-pindoss.pro',25);
}
#Logg("after IsSet");
$UserName = $_SERVER["HTTP_AUTH_USER"] ;
$UserPassword = $_SERVER["HTTP_AUTH_PASS"] ;
$Protocol = $_SERVER["HTTP_AUTH_PROTOCOL"] ;
//Logg(print_r($_SERVER,true));
// вариант приёма без авторизации
if(!$_SERVER['HTTP_AUTH_USER']){
// [HTTP_AUTH_SMTP_TO] => RCPT TO:<admin@california-pindoss.ca>
Preg_Match('/:\<(.*)\>/', $_SERVER['HTTP_AUTH_SMTP_TO'],$Matches, PREG_OFFSET_CAPTURE);
$UserName = $Matches[1][0];
Logg("non-auth user: " . $UserName);
}
// default backend port
$BackEndPort=110;
if($Protocol == "imap")
$BackEndPort = 143;
if($Protocol == "smtp")
$BackEndPort = 25;
// NGINX likes ip address so if your
// application gives back hostname, convert it to ip address here
$BackEndIP["mx.canada-pindoss.pro"] = "192.168.120.21";
$BackEndIP["canada-pindoss.pro"] = "192.168.120.21";
$BackEndIP["california-pindoss.ca"] = "192.168.120.26";
$BackEndIP["another-pindoss-1-e.ru"] = "192.168.120.26";
$BackEndIP["another-pindoss-2.com"] = "192.168.120.26";
// Authenticate the user or fail
if(!AuthUser($UserName,$UserPassword)){
fail();
exit;
}
//Logg("after AuthUser");
// Get the server for this user if we have reached so far
$UserServer = GetMailServer($UserName);
Logg("after GetMailServer, UserServer = $UserServer");
// Get the ip address of the server
// We are assuming that you backend returns hostname
// We try to get the ip else return what we got back
$ServerIP = (IsSet($BackEndIP[$UserServer]))?$BackEndIP[$UserServer] : $UserServer;
// Pass!
Pass($ServerIP, $BackEndPort);
//Logg("after Pass");
//END
function AuthUser($User,$Pass){
// password characters encoded by nginx:
// " " 0x20h (SPACE)
// "%" 0x25h
// see nginx source: src/core/ngx_string.c:ngx_escape_uri(...)
$Pass = Str_Replace('%20',' ', $Pass);
$Pass = Str_Replace('%25','%', $Pass);
// put your logic here to authen the user to any backend
// you want (datbase, ldap, etc)
// for example, we will just return true;
return true;
}
function GetMailServer($User){
// разбираем логин по @
$Array = Explode('@',$User);
// если домен есть - используем его, если нет - дефолтовый
//Logg("into GetMailServer, " . print_r($Array,true));
if(IsSet($Array[1])){
return $Array[1];
}else{
return "canada-pindoss.pro";
}
}
function Fail(){
Header("Auth-Status: Invalid login or password");
exit;
}
function Pass($Server,$Port){
Header("Auth-Status: OK");
Header("Auth-Server: $Server");
Header("Auth-Port: $Port");
//Logg("Header sent: $Server:$Port");
exit;
}
function Logg($Line){
$File = '/tmp/mail.auth.log';
if(!$fp = fopen($File, 'a')){
echo "Не могу открыть файл ($File)";
exit;
}
if (fwrite($fp, $Line . "\n") === FALSE) {
echo "Не могу произвести запись в файл ($File)";
exit;
}
fclose($fp);
}
?>
/usr/local/etc/fail2ban/jail.d/nginx-dovecot.conf
Код: Выделить всё
#
[nginx-dovecot]
enabled = true
action = bsd-ipfw[table=dovecot]
bantime.increment = false
bantime.overalljails = true
filter = nginx-dovecot
logpath = /var/log/nginx/mail_proxy_error.log
Код: Выделить всё
#
[nginx-exim]
enabled = true
action = bsd-ipfw[table=exim]
bantime.increment = true
bantime.overalljails = true
filter = nginx-exim
logpath = /var/log/nginx/mail_proxy_error.log
Код: Выделить всё
#
[Definition]
failregex = .*Authentication failed.*while reading response from upstream, client: <HOST>, server: 0.0.0.0:(110|143|993),.*
Код: Выделить всё
#
[Definition]
failregex = .*Incorrect authentication data.*while reading response from upstream, client: <HOST>, server: 0.0.0.0:(25|465|587),.*
ну как-то так.
настройка php-fpm пропущена, я не помню как и что там настраивал - но по какой-то первой попавшейся в инете инcтрукции делалось с поправкой на пути FreeBSD