Тази статия е за това как да настроите съвременен пощенски сървър.
Postfix + Dovecot. SPF + DKIM + rDNS. С IPv6.
С шифроване TSL. С поддръжка на множество домейни - част с истински SSL сертификат.
С антиспам защита и висока антиспам оценка на други пощенски сървъри.
С поддръжка на няколко физически интерфейса.
С OpenVPN, свързването с който е чрез IPv4, и който предоставя IPv6.
Ако не искате да изучавате всички тези технологии, но искате да настроите такъв сървър - тогава тази статия е за вас.
В статията липсват опити да се обяснят всички детайли. Обяснението се отнася до това, което е настроено нестандартно или е важно от гледна точка на потребителя.
Мотивацията да настроя пощенски сървър - моя отдавна мечта. Може да звучи глупаво, но според мен, това е много по-добре, отколкото да мечтая за нова кола от любимата марка.
Мотивацията за настройка на IPv6 - две. IT специалистът трябва постоянно да учи нови технологии, за да оцелее. Искам да внеса своя скромен принос в борбата с цензурата.
Мотивацията за настройка на OpenVPN - само за да работи IPv6 на локалната машина.
Мотивацията за настройка на няколко физически интерфейса - на сървъра имам един интерфейс "бавен, но без лимит", а друг "бърз, но с такса".
Мотивацията за настройка на Bind - моят доставчик предлага нестабилен DNS сървър, а Google понякога също дава проблеми. Искам стабилен DNS сървър за лично ползване.
Мотивацията да напиша статията - черновата беше написана преди 10 месеца и я проверявах два пъти. Ако дори на автора му е необходимо редовно - то има голяма вероятност и на другите да им трябва.
Няма универсално решение за пощенски сървър. Но ще се опитам да напиша нещо като "направете така, а после, когато всичко работи както трябва - изхвърлете излишното".
Имам Colocation сървър от компанията tech.ru. Има възможност да се сравни с OVH, Hetzner, AWS. За решаването на тази задача сътрудничеството именно с tech.ru ще бъде много по-ефективно.
На сървъра е инсталиран Debian 9.
На сървъра има 2 интерфейса `eno1` и `eno2`. Първият е безлимитен, а вторият бърз съответно.
Има 3 статични IP адреса, XX.XX.XX.X0 и XX.XX.XX.X1 и XX.XX.XX.X2 на интерфейса `eno1` и XX.XX.XX.X5 на интерфейса `eno2`.
Има XXXX:XXXX:XXXX:XXXX::/64 пул IPv6 адреси, които са назначени на интерфейс `eno1`, а по моя молба XXXX:XXXX:XXXX:XXXX:1:2::/96 са назначени на `eno2`.
Има три домейна `domain1.com`, `domain2.com`, `domain3.com`. За `domain1.com` и `domain3.com` е наличен SSL сертификат.
Има Google акаунт, който искам да свържа с имейл `vasya.pupkin@domain1.com` (получаване и изпращане на имейли директно от интерфейса на Gmail).
Трябва да има имейл кутия `support@domain2.com`, от която искам да получавам копие на имейлите в Gmail. И рядко да имам възможност да изпратя нещо от името на `support@domain2.com` през уеб интерфейса.
Трябва да има имейл кутия `ivanov@domain3.com`, която ще ползва Иванов от своя iPhone.
Изпращаните имейли трябва да отговарят на всички съвременни изисквания за антиспам.
Трябва да има най-високото ниво на шифроване, предвидено в публичните мрежи.
Трябва да има поддръжка на IPv6 както за изпращане, така и за получаване на имейли.
Трябва да има SpamAssassin, който никога не бива да изтрива имейли. А вместо това да прави bounce, да ги пропуска или да ги изпраща в IMAP папка „Спам“.
Трябва да бъде настроено автообучение на SpamAssassin: ако преместя имейл в папка „Спам“ — да се обучи на това; ако преместя имейл от папка „Спам“ — да се обучи на това. Резултатите от обучението на SpamAssassin — трябва да влияят на попадналите имейли в папка „Спам“.
PHP скриптовете трябва да могат да изпращат имейли от името на всеки домейн на този сървър.
Трябва да има OpenVPN услуга, с възможност за използване на IPv6 на клиент, който няма IPv6.
Първо трябва да настроим интерфейсите и маршрутизацията, включително IPv6.
След това трябва да настроим OpenVPN, който ще се свързва през IPv4 и ще предоставя на клиента статичен реален IPv6 адрес. Този клиент ще има достъп до всички IPv6 услуги на сървера и до всякакви ресурси с IPv6 в интернет.
После ще трябва да настроим Postfix за изпращане на имейли + SPF + DKIM + rDNS и други подобни детайли.
После ще трябва да настроим Dovecot и да настроим многодомейнност.
След това ще трябва да настроим SpamAssassin и да настроим обучението.
В заключение, ще инсталираме Bind.
============= Мулти-интерфейси =============
За настройка на интерфейсите трябва да напишете следното в „/etc/network/interfaces“.
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eno1
iface eno1 inet static
address XX.XX.XX.X0/24
gateway XX.XX.XX.1
dns-nameservers 127.0.0.1 213.248.1.6
post-up ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1t
post-up ip route add default via XX.XX.XX.1 table eno1t
post-up ip rule add table eno1t from XX.XX.XX.X0
post-up ip rule add table eno1t to XX.XX.XX.X0
auto eno1:1
iface eno1:1 inet static
address XX.XX.XX.X1
netmask 255.255.255.0
post-up ip rule add table eno1t from XX.XX.XX.X1
post-up ip rule add table eno1t to XX.XX.XX.X1
post-up ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t
post-down ip route del 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t
auto eno1:2
iface eno1:2 inet static
address XX.XX.XX.X2
netmask 255.255.255.0
post-up ip rule add table eno1t from XX.XX.XX.X2
post-up ip rule add table eno1t to XX.XX.XX.X2
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
gateway XXXX:XXXX:XXXX:XXXX::1
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:2/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:1:1:2/64 dev $IFACE
# The secondary network interface
allow-hotplug eno2
iface eno2 inet static
address XX.XX.XX.X5
netmask 255.255.255.0
post-up ip route add XX.XX.XX.0/24 dev eno2 src XX.XX.XX.X5 table eno2t
post-up ip route add default via XX.XX.XX.1 table eno2t
post-up ip rule add table eno2t from XX.XX.XX.X5
post-up ip rule add table eno2t to XX.XX.XX.X5
post-up ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X5 table eno2t
post-down ip route del 10.8.0.0/24 dev tun0 src XX.XX.XX.X5 table eno2t
iface eno2 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:2::/96
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:2:1:1/64 dev $IFACE
up ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:2:1:2/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:2:1:1/64 dev $IFACE
down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:2:1:2/64 dev $IFACE
# OpenVPN network
iface tun0 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:3::/80Тези настройки могат да се прилагат на всеки сървър в tech.ru (с малко разрешение от поддръжката) и веднага ще заработят както трябва.
Ако имате опит с настройката на подобни неща за Hetzner, OVH — там е различно. По-сложно е.
eno1 — това е името на мрежовата карта #1 (бавна, но безлимитна).
eno2 — това е името на мрежовата карта #2 (бърза, но с тарифен план).
tun0 — това е името на виртуалната мрежова карта от OpenVPN.
XX.XX.XX.X0 — IPv4 #1 на eno1.
XX.XX.XX.X1 — IPv4 #2 на eno1.
XX.XX.XX.X2 — IPv4 #3 на eno1.
XX.XX.XX.X5 — IPv4 #1 на eno2.
XX.XX.XX.1 — IPv4 gateway.
XXXX:XXXX:XXXX:XXXX::/64 — IPv6 за целия сървър.
XXXX:XXXX:XXXX:XXXX:1:2::/96 — IPv6 за eno2, всичко останало влиза в eno1.
XXXX:XXXX:XXXX:XXXX::1 — IPv6 gateway (необходимо е да се посочи IPv6 на свича тук).
dns-nameservers — указани 127.0.0.1 (поради наличието на локален bind) и 213.248.1.6 (това е от tech.ru).
«table eno1t» и «table eno2t» — смисълът на тези route-rule е, че трафикът, влязъл през eno1, ще излиза през него, а трафикът, влязъл през eno2, ще излиза през него. Освен това, сървърните инициативи ще напускат през eno1.
ip route add default via XX.XX.XX.1 table eno1tС тази команда задаваме, че всеки неразбираем трафик, който попада под правило с «table eno1t» — да бъде насочен към интерфейса eno1.
ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1tС тази команда задаваме, че всеки трафик по инициатива на сървъра да бъде насочен към интерфейса eno1.
ip rule add table eno1t from XX.XX.XX.X0
ip rule add table eno1t to XX.XX.XX.X0С тази команда задаваме правилата за маркиране на трафика.
auto eno1:2
iface eno1:2 inet static
address XX.XX.XX.X2
netmask 255.255.255.0
post-up ip rule add table eno1t from XX.XX.XX.X2
post-up ip rule add table eno1t to XX.XX.XX.X2Този блок задава втори IPv4 адрес за интерфейса eno1.
ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t С тази команда задаваме route от клиентите на OpenVPN до локалните IPv4, освен XX.XX.XX.X0.
Защо тази команда е достатъчна за всички IPv4 — все още не разбирам.
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
gateway XXXX:XXXX:XXXX:XXXX::1Тук задаваме адрес за самия интерфейс. Сървърът ще го използва като «изходящ» адрес. Повече няма да се използва.
Защо е указано «:1:1::» толкова сложно? За да работи OpenVPN правилно и само за това. По-подробно по-късно.
Относно gateway — така работи, и толкова. Но за да бъде правилно — тук трябва да се посочи IPv6 на свича, към който е свързан сървърът.
Но защо IPv6 спира да работи, когато правя така? Вероятно това са особености на tech.ru.
ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACEТова е добавяне на IPv6 адреса на интерфейса. Ако трябва сто адреса — значи сто реда в този файл.
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
...
iface eno2 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:2::/96
...
iface tun0 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:3::/80Посочих адресите и подсетите на всички интерфейси, за да е ясно.
eno1 — задължително трябва да бъде "/64" — защото това е целият ни pool от адреси.
tun0 — подсетът трябва задължително да е по-голям от eno1. В противен случай не може да се настрои IPv6 gateway за клиентите на OpenVPN.
eno2 — подсетът трябва задължително да е по-голям от tun0. В противен случай клиентите на OpenVPN няма да могат да достъпят локалните IPv6 адреси.
За по-добра представа избрах стъпка на подсет 16, но при желание може да се направи дори стъпка „1“.
Съответно 64+16 = 80, а 80+16 = 96.За още по-добра представа:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — това са адресите, които трябва да бъдат зададени на конкретни сайтове или услуги на интерфейса eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — това са адресите, които трябва да бъдат зададени на конкретни сайтове или услуги на интерфейса eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — това са адресите, които трябва да бъдат зададени на клиентите на OpenVPN или да се използват като служебни адреси на OpenVPN.
За настройка на мрежата — трябва да има възможност за рестартиране на сървъра.
IPv4 промените се взимат при изпълнение (задължително да се завие в screen — в противен случай тази команда просто ще срине мрежата на сървера):
/etc/init.d/networking restartВ файл "\/etc\/iproute2\/rt_tables" да се добави на края:
100 eno1t
101 eno2t Без това не може да се използват кастомни таблици в файла "\/etc\/network\/interfaces".
Цифрите трябва да са уникални и по-малки от 65535.
IPv6 промените лесно се променят без рестартиране, но за това е нужно да се научат поне три команди:
ip -6 addr ...
ip -6 route ...
ip -6 neigh ...Настройка на "\/etc\/sysctl.conf"
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward = 1
# Do not accept ICMP redirects (prevent MITM attacks)
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Do not send ICMP redirects (we are not a router)
net.ipv4.conf.all.send_redirects = 0
# For receiving ARP replies
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.default.arp_filter = 0
# For sending ARP
net.ipv4.conf.all.arp_announce = 0
net.ipv4.conf.default.arp_announce = 0
# Enable IPv6
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
# IPv6 configuration
net.ipv6.conf.all.autoconf = 1
net.ipv6.conf.all.accept_ra = 0
# For OpenVPN
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1
# For nginx on boot
net.ipv6.ip_nonlocal_bind = 1Това са настройките на "sysctl" на моя сървър. Ще отбележа важното.
net.ipv4.ip_forward = 1Без това OpenVPN изобщо няма да работи.
net.ipv6.ip_nonlocal_bind = 1Всеки, който опита да направи bind IPv6 (например nginx) веднага след като интерфейсът е пуснат — ще получи грешка. Че такъв адрес не е достъпен.
За да се избегне такава ситуация, се прави такава настройка.
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1Без тези настройки IPv6 трафикът от клиента на OpenVPN не излиза в света.
Други настройки или не са свързани с проблема, или не помня защо са.
Но за всеки случай оставям "както е".
За да се вземат промените в този файл без рестартиране на сървъра — трябва да се изпълни команда:
sysctl -pПо-подробно за правилата на "table":
============= OpenVPN =============
OpenVPN IPv4 не работи без iptables.
Моите iptables са такива за VPN:
iptables -A INPUT -p udp -s YY.YY.YY.YY --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -o eno1 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
##iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADE
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -j DROP
iptables -A FORWARD -p udp --dport 1194 -j DROP YY.YY.YY.YY — това е моят статичен IPv4 адрес на локалната машина.
10.8.0.0/24 — IPv4 мрежа за openvpn. IPv4 адреси за клиентите на openvpn.
Последователността на правилата е важна.
iptables -A INPUT -p udp -s YY.YY.YY.YY --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -o eno1 -j ACCEPT
...
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -j DROP
iptables -A FORWARD -p udp --dport 1194 -j DROPТова е ограничение, за да може само аз от статичния си IP да използвам OpenVPN.
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
-- или --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADEЗа пренасочване на IPv4 пакети между клиентите на OpenVPN и интернет — трябва да напишете една от тези команди.
За различни случаи едната от вариантите не е подходяща.
В моя случай и двете команди са подходящи.
След като прегледах документацията, избрах първия вариант, защото консумира по-малко CPU.
За да се запазят всички настройки на iptables след рестарт — трябва да ги запазите на някое място.
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6Такива имена са избрани не случайно. Те се използват от пакета „iptables-persistent“.
apt-get install iptables-persistentИнсталиране на основния пакет OpenVPN:
apt-get install openvpn easy-rsaНека настроим шаблона за сертификатите (добавете своите стойности):
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
ln -s openssl-1.0.0.cnf openssl.cnfНека редактираме настройките на шаблона за сертификати:
mcedit vars...
# Това са стойностите по подразбиране за полетата,
# които ще бъдат поставени в сертификата.
# Не оставяйте никое от тези полета празно.
export KEY_COUNTRY="BG"
export KEY_PROVINCE="Производство"
export KEY_CITY="Град"
export KEY_ORG="Собствено"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"
# X509 Subject Field
export KEY_NAME="сървър"
...Създаваме сървърен сертификат:
cd ~/openvpn-ca
source vars
./clean-all
./build-ca
./build-key-server server
./build-dh
openvpn --genkey --secret keys/ta.keyНека приготвим възможността да създаваме завършващи "client-name.opvn" файлове:
mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
mcedit ~/client-configs/base.conf# Client mode
client
# Interface tunnel type
dev tun
# TCP protocol
proto tcp-client
# Address/Port of VPN server
remote XX.XX.XX.X0 1194
# Don't bind to local port/address
nobind
# Don't need to re-read keys and re-create tun at restart
persist-key
persist-tun
# Remote peer must have a signed certificate
remote-cert-tls server
ns-cert-type server
# Enable compression
comp-lzo
# Custom
ns-cert-type server
tls-auth ta.key 1
cipher DES-EDE3-CBCНека приготвим скрипт, който ще обединява всички файлове в един opvn файл.
mcedit ~/client-configs/make_config.sh
chmod 700 ~/client-configs/make_config.sh#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG}
<(echo -e '<ca>')
${KEY_DIR}/ca.crt
<(echo -e '</ca>n<cert>')
${KEY_DIR}/${1}.crt
<(echo -e '</cert>n<key>')
${KEY_DIR}/${1}.key
<(echo -e '</key>n<tls-auth>')
${KEY_DIR}/ta.key
<(echo -e '</tls-auth>')
> ${OUTPUT_DIR}/${1}.ovpnСъздаваме първия клиент OpenVPN:
cd ~/openvpn-ca
source vars
./build-key client-name
cd ~/client-configs
./make_config.sh client-nameФайлът "~/client-configs/files/client-name.ovpn" изпращаме на устройството на клиента.
За потребителите на iOS ще се нуждаем от трик:
Съдържанието на тега «tls-auth» трябва да е без коментари.
Също така, добавете «key-direction 1» веднага преди тега «tls-auth».
Нека конфигурираме OpenVPN сървъра:
cd ~/openvpn-ca/keys
cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | tee /etc/openvpn/server.conf
mcedit /etc/openvpn/server.conf# Listen port
port 1194
# Protocol
proto tcp-server
# IP tunnel
dev tun0
tun-ipv6
push tun-ipv6
# Master certificate
ca ca.crt
# Server certificate
cert server.crt
# Server private key
key server.key
# Diffie-Hellman parameters
dh dh2048.pem
# Allow clients to communicate with each other
client-to-client
# Client config dir
client-config-dir /etc/openvpn/ccd
# Run client-specific script on connection and disconnection
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/server-clientdisconnect.sh"
# Server mode and client subnets
server 10.8.0.0 255.255.255.0
server-ipv6 XXXX:XXXX:XXXX:XXXX:1:3::/80
topology subnet
# IPv6 routes
push "route-ipv6 XXXX:XXXX:XXXX:XXXX::/64"
push "route-ipv6 2000::/3"
# DNS (for Windows)
# These are OpenDNS
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
# Configure all clients to redirect their default network gateway through the VPN
push "redirect-gateway def1 bypass-dhcp"
push "redirect-gateway ipv6" #For iOS
# Don't need to re-read keys and re-create tun at restart
persist-key
persist-tun
# Ping every 10s. Timeout of 120s.
keepalive 10 120
# Enable compression
comp-lzo
# User and group
user vpn
group vpn
# Log a short status
status openvpn-status.log
# Logging verbosity
##verb 4
# Custom config
tls-auth ta.key 0
cipher DES-EDE3-CBCТова е необходимо, за да зададем статичен адрес на всеки клиент (не е задължително, но аз го използвам):
# Client config dir
client-config-dir /etc/openvpn/ccdНай-сложният и ключов детайл.
За съжаление, OpenVPN все още не може автоматично да настрои IPv6 gateway за клиентите.
Приходи се да го «преправим» ръчно за всеки клиент.
# Run client-specific script on connection and disconnection
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/server-clientdisconnect.sh"Файлът «/etc/openvpn/server-clientconnect.sh»:
#!/bin/sh
# Check client variables
if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
echo "Missing environment variable."
exit 1
fi
# Load server variables
. /etc/openvpn/variables
ipv6=""
# Find out if there is a specific config with fixed IPv6 for this client
if [ -f "/etc/openvpn/ccd/$common_name" ]; then
# Get fixed IPv6 from client config file
ipv6=$(sed -nr 's/^.*ifconfig-ipv6-push[ t]+([0-9a-fA-F:]+).*$/1/p' "/etc/openvpn/ccd/$common_name")
echo $ipv6
fi
# Get IPv6 from IPv4
if [ -z "$ipv6" ]; then
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IPv4 part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
ipv6="$prefix$hexipp"
fi
# Create proxy rule
/sbin/ip -6 neigh add proxy $ipv6 dev eno1Файлът «/etc/openvpn/server-clientdisconnect.sh»:
#!/bin/sh
# Check client variables
if [ -z "$ifconfig_pool_remote_ip" ] || [ -z "$common_name" ]; then
echo "Missing environment variable."
exit 1
fi
# Load server variables
. /etc/openvpn/variables
ipv6=""
# Find out if there is a specific config with fixed IPv6 for this client
if [ -f "/etc/openvpn/ccd/$common_name" ]; then
# Get fixed IPv6 from client config file
ipv6=$(sed -nr 's/^.*ifconfig-ipv6-push[ t]+([0-9a-fA-F:]+).*$/1/p' "/etc/openvpn/ccd/$common_name")
fi
# Get IPv6 from IPv4
if [ -z "$ipv6" ]; then
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IPv4 part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
ipv6="$prefix$hexipp"
fi
# Delete proxy rule
/sbin/ip -6 neigh del proxy $ipv6 dev eno1И двата скрипта използват файла «/etc/openvpn/variables»:
# Subnet
prefix=XXXX:XXXX:XXXX:XXXX:2:
# netmask
prefixlen=112Защо е написано така — не мога да си спомня.
Сега изглежда странно netmask = 112 (тук трябва да е 96).
И префиксът е странен, не отговаря на мрежата tun0.
Но добре, оставям «както е».
cipher DES-EDE3-CBCТова е за любителите — избрах такъв метод на кодиране на връзката.
============= Postfix =============
Инсталиране на основния пакет:
apt-get install postfixПри инсталиране изберете «internet-site».
Моят «/etc/postfix/main.cf» изглежда така:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# добавление .domain — это задача MUA.
append_dot_mydomain = no
readme_directory = no
# См. http://www.postfix.org/COMPATIBILITY_README.html -- по умолчанию 2 для
# новых установок.
compatibility_level = 2
# Параметры TLS
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
smtpd_use_tls=yes
smtpd_tls_auth_only = yes
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1
smtp_tls_security_level = may
smtp_tls_ciphers = export
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_loglevel = 1
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = domain1.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = domain1.com
mydestination = localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
internal_mail_filter_classes = bounce
# Тип хранения
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# Настройки SMTP-Auth
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
#reject_invalid_hostname,
#reject_unknown_recipient_domain,
reject_unauth_destination,
reject_rbl_client sbl.spamhaus.org,
check_policy_service unix:private/policyd-spf
smtpd_helo_restrictions =
#reject_invalid_helo_hostname,
#reject_non_fqdn_helo_hostname,
reject_unknown_helo_hostname
smtpd_client_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_helo_hostname,
permit
# SPF
policyd-spf_time_limit = 3600
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sock
# IP-адрес на домен
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreНека разгледаме подробностите на този конфиг.
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.keyСпоред потребителите на Хабр, този блок съдържа `дезинформация и неверни тези`.Само след 8 години от началото на кариерата си, започнах да разбирам как работи SSL.
Затова ще си позволя смелостта да опиша как да се използва SSL (без да отговарям на въпросите "Как работи това?" и "Защо работи това?").
Основата на съвременното криптиране е създаването на двойка ключове (две много дълги строки от символи).
Единият „ключ“ е частен, а другият ключ е „публичен“. Частният ключ се съхранява много старателно в тайна. Публичният ключ се раздава на всички желаещи.
С помощта на публичния ключ може да се криптира строка текст така, че само притежателят на частния ключ да може да я декриптира.
Е, това е основата на технологията.Стъпка №1 — сайтове с https.
Когато браузерът се свързва с сайта, той научава от уеб сървъра, че сайтът е https и затова заявява публичния ключ.
Уеб сървърът предоставя публичен ключ. Браузърът използва публичния ключ за шифроване на http-заявката и я изпраща.
Съдържанието на http-заявката може да бъде прочетено само от този, който притежава частния ключ, тоест само от сървъра, с който се осъществява връзка.
Http-заявката съдържа поне URI. Така че, ако в страната се опитват да ограничат достъпа не до целия сайт, а до конкретна страница — то за https сайтове това е невъзможно.Стъпка №2 — шифрован отговор.
Уеб сървърът дава отговор, който лесно може да бъде прочетен по пътя.
Решението е изключително просто — браузърът на локално ниво генерира същата двойка частен-публичен ключ за всеки https сайт.
И заедно с заявката за публичния ключ на сайта изпраща своя локален публичен ключ.
Уеб сървърът го запомня и при изпращане на http-отговора шифрова с този публичен ключ конкретния клиент.
Сега http-отговорът може да бъде дешифриран само от притежателя на частния ключ на браузъра на клиента (тоест самия клиент).Стъпка №3 — установяване на защитена връзка по публичния канал.
В пример №2 има уязвимост — нищо не пречи на злонамерените лица да прихващат http-заявката и да редактират информацията за публичния ключ.
По този начин посредникът може прекрасно да види всичкото съдържание на изпратените-получените съобщения, докато не се смени каналът за комуникация.
Справянето с това е изключително просто — достатъчно е да се изпрати публичният ключ на браузъра като съобщение, шифровано с публичния ключ на уеб сървъра.
Уеб сървърът тогава най-напред изпраща отговор от типа „твоят публичен ключ изглежда така“ и шифрова това съобщение с този същия публичен ключ.
Браузърът гледа отговора — ако е получено съобщение „твоят публичен ключ изглежда така“ — то това е 100% гаранция, че този канал за свързване е безопасен.
Колко безопасен е?
Самото създаване на такъв безопасен канал за комуникация става със скорост ping*2. Например 20ms.
Недоброжелателят трябва или предварително да притежава частния ключ на едната страна. Или да подбере частния ключ за няколко милисекунди.
Хакването на един съвременен частен ключ ще отнеме десетилетия на суперкомпютър.Стъпка №4 — публична БД на публични ключове.
Очевидно е, че в цялата тази история съществува възможност за злонамерен човек, който седи на канала за комуникация между клиента и сървъра.
Възможност за клиента да бъде представен като сървър, а сървърът да бъде представен като клиент. И да симулира двойка ключове в двете посоки.
Тогава злоумышленикът ще вижда целия трафик и ще има възможността да "редактира" трафика.
Например, да промени адреса, на който да се изпращат пари, да копира паролата от онлайн банката или да блокира "неугодното" съдържание.
За борба с такива злонамерени лица бе създадена публична база данни с публични ключове за всеки https сайт.
Всеки браузър "знае" за съществуването на около 200 такива бази данни. Това е предварително зададено във всеки браузър.
"Знанието" е подсигурено с публичния ключ на всеки сертификат. Тоест, свързването с конкретен център за сертификация не може да бъде фалшифицирано.Сега имаме просто разбиране как да използваме SSL за https.
Ако се замислите, ще стане ясно как специалните служби могат да пробият тази конструкция. Но това ще им струва чудовищни усилия.
А за организациите, по-малко от АНБ или ЦРУ, практически е невъзможно да се пробие съществуващото ниво на защита, дори за VIP.Още ще добавя за ssh връзките. Там няма публични ключове, какво да правим. Въпросът се решава по два начина.
Вариант ssh с парола:
При първото свързване ssh клиентът трябва да предупреди, че имаме нов публичен ключ от ssh сървъра.
И при последващи връзки, ако се появи предупреждение "нов публичен ключ от ssh сървъра" - това ще означава, че се опитват да ви подслушват.
Или при първото свързване сте били подслушвани, а сега комуникирате със сървъра без посредници.
Собствено, поради факта, че подслушването е лесно, бързо и без усилия, тази атака се използва само в специални случаи за конкретен клиент.Вариант ssh с ключ:
Взимаме флашка, записваме на нея приватния ключ за ssh сървъра (за това има термини и куп нюанси, но пиша безболезнено, а не инструкция за приложение).
Публичният ключ оставяме на машината, където ще бъде ssh клиентът и също го държим в тайна.
Принасяме флашката до сървъра, включваме я, копираме приватния ключ, а флашката изгаряме и разпръскваме пепелта по вятъра (или поне форматираме с запълване на нули).
И това е всичко — след такава операция ще бъде невъзможно да се хакне такова ssh връзка. Разбира се, след 10 години на суперкомпютър може да се прегледа трафика — но това е отделна история.Извинявайте за оффтопика.
И така, сега когато теорията е известна, ще разкажа за потока на създаване на ssl сертификат.
С помощта на «openssl genrsa» създаваме частен ключ и «шаблони» за публичния ключ.
«Шаблоните» изпращаме на трета страна, на която плащаме около $9 за най-простия сертификат.
След няколко часа получаваме от тази трета страна нашия «публичен» ключ и набор от няколко публични ключа.
Защо да плащаме на трета страна за оформяне на моя публичен ключ — това е отделен въпрос, тук няма да го разглеждаме.
Сега е ясно какъв е смисълът на надписа:
smtpd_tls_key_file=\/etc\/ssl\/domain1.com.2018.key В папката «\/etc\/ssl» са събрани всички файлове за ssl въпроси.
domain1.com — името на домейна.
2018 — годината на създаване на ключовете.
«key» — обозначава, че файлът е частен ключ.
И смисълът на този файл:
smtpd_tls_cert_file=\/etc\/ssl\/domain1.com.2018.chained.crt
domain1.com — името на домейна.
2018 — годината на създаване на ключовете.
chained — означава, че тук е верига от публични ключове (първият — нашият публичен и останалите — които са получени от компанията, която е изготвила публичния ключ).
crt — обозначава, че тук е готов сертификат (публичен ключ с технически пояснения).
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1Тази настройка в този случай не се използва, но е написана за пример.
Защото грешка в този параметър ще доведе до изпращане на спам от вашия сървър (без вашето знание).
След това доказвайте на всички, че не сте виновни.
recipient_delimiter = +Много хора не знаят, но това е стандартният символ за разделяне на пощите, и това се поддържа от повечето съвременни пощенски сървъри.
Например, ако имате пощенска кутия «username@gmail.com», опитайте да изпратите на «username+spam@gmail.com» — вижте какво ще стане.
inet_protocols = ipv4Може да е объркващо.
Но не е просто така. Всеки нов домейн — по подразбиране само IPv4, после активирам IPv6 за всеки поотделно.
virtual_transport = lmtp:unix:private\/dovecot-lmtp
virtual_mailbox_domains = mysql:\/etc\/postfix\/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:\/etc\/postfix\/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:\/etc\/postfix\/mysql-virtual-alias-maps.cf Тук задаваме, че цялата входяща поща отива в dovecot.
А правилата за домейн, пощенска кутия, алиас — вижте в БД.
/etc/postfix/mysql-virtual-mailbox-domains.cf
потребител = usermail
парола = mailpassword
хостове = 127.0.0.1
име на база данни = servermail
запитване = SELECT 1 FROM virtual_domains WHERE name='%s'/etc/postfix/mysql-virtual-mailbox-maps.cf
потребител = usermail
парола = mailpassword
хостове = 127.0.0.1
име на база данни = servermail
запитване = SELECT 1 FROM virtual_users WHERE email='%s'/etc/postfix/mysql-virtual-alias-maps.cf
потребител = usermail
парола = mailpassword
хостове = 127.0.0.1
име на база данни = servermail
запитване = SELECT destination FROM virtual_aliases WHERE source='%s'# SMTP-Auth settings
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yesСега postfix знае, че може да приема имейли за по-нататъшно изпращане само след удостоверяване с dovecot.
Наистина не разбирам защо е нужно да се дублира тук. Вече посочихме в „virtual_transport“ всичко необходимо.
Но системата postfix е много стара — вероятно това са спасителни мерки от стари времена.
smtpd_recipient_restrictions =
...
smtpd_helo_restrictions =
...
smtpd_client_restrictions =
...Това се настройва индивидуално за всеки имейл сървър.
Разполагам с 3 имейл сървъра и тези настройки са много различни заради различните изисквания за използване.
Настройките трябва да бъдат извършени внимателно — в противен случай спам ще нахлуе при вас или, още по-лошо — спам ще излиза от вас.
# SPF
policyd-spf_time_limit = 3600Настройка за някакъв плъгин, свързан с проверка на SPF за входящи имейли.
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sockНастройка, която указва, че всички изходящи имейли трябва да бъдат снабдени с DKIM подпис.
# IP address per domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreТова е ключов елемент в маршрутизирането на имейли при изпращане от php скриптове.
Файлът „/etc/postfix/sdd_transport.pcre“:
/^www-domain1@domain1.com$/ domain1:
/^www-domain2@domain1.com$/ domain2:
/^www-domain3@domain1.com$/ domain3:
/@domain1.com$/ domain1:
/@domain2.com$/ domain2:
/@domain3.com$/ domain3:Вляво — регулярни изрази. Вдясно — етикет, с който имейлът е маркиран.
Postfix, в съответствие с етикета, ще вземе предвид още няколко реда конфигурация за конкретния имейл.Как точно ще бъде преконфигуриран postfix за конкретен имейл — ще бъде указано в „master.cf“.
Редовете 4, 5, 6 — те са основни. От името на какъв домейн изпращаме имейл — такъв етикет и поставяме.
Но не винаги в php скриптовете в стария код е указано полето „from“. Тогава на помощ идва потребителското име.Статията и така е обширна — не искам да се отклонявам към настройките на nginx+fpm.
Накратко — за всеки сайт задаваме свой linux-мярка собственик. И съответно, свой fpm-пул.
Fpm-пулът използва всяка версия на php (това е прекрасно, когато на един сървър без проблеми за съседните сайтове може да се използва различна версия на php и дори различен php.ini).
Така че конкретният linux-потребител „www-domain2“ има сайт domain2.com. На този сайт има код за изпращане на имейли без указване на полето от.
Така че дори в такъв случай имейлите ще излизат правилно и никога няма да попаднат в спам.
Моят „/etc/postfix/master.cf“ изглежда така:
...
smtp inet n - y - - smtpd
-o content_filter=spamassassin
...
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
...
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}
...
domain1 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X1
-o smtp_helo_name=domain1.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:1:1
-o syslog_name=postfix-domain1
domain2 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X5
-o smtp_helo_name=domain2.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:2:1:1
-o syslog_name=postfix-domain2
domain3 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X2
-o smtp_helo_name=domain3
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:5:1
-o syslog_name=postfix-domain3 Файлът не е напълно представен — той вече е много голям.
Отбелязах само това, което е променено.
smtp inet n - y - - smtpd
-o content_filter=spamassassin
...
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}Това са настройките, свързани със spamassassin, за него по-късно.
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject Позволяваме свързването с пощенския сървър през порт 587.
За целта е задължително да се авторизирате.
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spfВключваме проверката на SPF.
apt-get install postfix-policyd-spf-pythonЩе инсталираме пакета за по-горе SPF проверки.
domain1 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X1
-o smtp_helo_name=domain1.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:1:1
-o syslog_name=postfix-domain1А това е най-интересното. Това е възможността да се изпращат писма за конкретен домейн с конкретен IPv4/IPv6 адрес.
Прави се това заради rDNS. rDNS е получаване на определен низ по IP адрес.
И за пощата, тази възможност се използва за потвърждаване, че helo наистина съответства на rDNS на адреса, от който е изпратен имейлът.Ако helo не съответства на домейна на пощата, от името на когото е изпратен имейлът — се начисляват спам точки.
Helo не съответства на rDNS — начисляват се много спам точки.
Съответно, за всеки домейн трябва да има свой IP адрес.
За OVH — в конзолата има възможност да се указва rDNS.
За tech.ru — проблемът се решава чрез поддръжката.
За AWS — проблемът се решава чрез поддръжката.
«inet_protocols» и «smtp_bind_address6» — това включва поддръжка на IPv6.
За IPv6 също трябва да се конфигурира rDNS.
«syslog_name» — това е за улесняване на четенето на логовете.
Закупуване на сертификати .
.
============= Dovecot =============
apt-get install dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql dovecot-antispamКонфигуриране на mysql, инсталираме необходимите пакети.
Файл «/etc/dovecot/conf.d/10-auth.conf»
disable_plaintext_auth = yes
auth_mechanisms = plain loginАвторизация само в криптиран вид.
Файл «/etc/dovecot/conf.d/10-mail.conf»
mail_location = maildir:/var/mail/vhosts/%d/%nТук посочваме местоположението за съхранение на писмата.
Искам те да се съхраняват в файлове и да бъдат групирани по домейни.
Файл «/etc/dovecot/conf.d/10-master.conf»
service imap-login {
inet_listener imap {
port = 0
}
inet_listener imaps {
address = XX.XX.XX.X1, XX.XX.XX.X2, XX.XX.XX.X5, [XXXX:XXXX:XXXX:XXXX:1:1:1:1], [XXXX:XXXX:XXXX:XXXX:1:2:1:1], [XXXX:XXXX:XXXX:XXXX:1:1:5:1]
port = 993
ssl = yes
}
}
service pop3-login {
inet_listener pop3 {
port = 0
}
inet_listener pop3s {
address = XX.XX.XX.X1, XX.XX.XX.X2, XX.XX.XX.X5, [XXXX:XXXX:XXXX:XXXX:1:1:1:1], [XXXX:XXXX:XXXX:XXXX:1:2:1:1], [XXXX:XXXX:XXXX:XXXX:1:1:5:1]
port = 995
ssl = yes
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service imap {
}
service pop3 {
}
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
}
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
user = dovecot
}
service auth-worker {
user = vmail
}
service dict {
unix_listener dict {
}
} Това е главният файл за настройките на dovecot.
Тук изключваме незащитените връзки.
И активираме защитените връзки.
Файл «/etc/dovecot/conf.d/10-ssl.conf»
ssl = required
ssl_cert = < /etc/nginx/ssl/domain1.com.2018.chained.crt
ssl_key = < /etc/nginx/ssl/domain1.com.2018.key
local XX.XX.XX.X5 {
ssl_cert = < /etc/nginx/ssl/domain2.com.2018.chained.crt
ssl_key = < /etc/nginx/ssl/domain2.com.2018.key
}Настройваме ssl. Посочваме, че ssl — е задължителен.
И самият сертификат. Важен детайл е директивата «local». Тя указва, при свързване към кой локален IPv4 — кой ssl сертификат да се използва.Между другото, IPv6 тук не е настроен, ще поправя това пропускане по-късно.
XX.XX.XX.X5 (domain2) — сертификатът отсъства. За свързване на клиенти трябва да се посочва domain1.com.
XX.XX.XX.X2 (domain3) — сертификатът е наличен, за свързване на клиенти може да се посочва domain1.com или domain3.com.
Файл «/etc/dovecot/conf.d/15-lda.conf»
protocol lda {
mail_plugins = $mail_plugins sieve
}Това по-късно ще е нужно за spamassassin.
Файл «/etc/dovecot/conf.d/20-imap.conf»
protocol imap {
mail_plugins = $mail_plugins antispam
}Това е antispam плъгин. Необходим е за обучение на spamassassin при преместване в/от папката «Spam».
Файл «/etc/dovecot/conf.d/20-pop3.conf»
protocol pop3 {
}Просто такъв файл съществува.
Файл «/etc/dovecot/conf.d/20-lmtp.conf»
протокол lmtp {
mail_plugins = $mail_plugins sieve
postmaster_address = admin@domain1.com
}Конфигурация lmtp.
Файл "\/etc\/dovecot\/conf.d\/90-antispam.conf"
плагин {
antispam_backend = pipe
antispam_trash = Trash;trash
antispam_spam = Junk;Spam;SPAM
antispam_pipe_program_spam_arg = --spam
antispam_pipe_program_notspam_arg = --ham
antispam_pipe_program = \/usr\/bin\/sa-learn
antispam_pipe_program_args = --username=%Lu
}Настройки обучения spamassassin во время переноса в\/из папки «Spam».
Файл "\/etc\/dovecot\/conf.d\/90-sieve.conf"
плагин {
sieve = ~\/.dovecot.sieve
sieve_dir = ~\/sieve
sieve_after = \/var\/lib\/dovecot\/sieve\/default.sieve
}Файл, в котором указано, что делать с входящими письмами.
Файл "\/var\/lib\/dovecot\/sieve\/default.sieve"
require ["fileinto", "mailbox"];
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Spam";
}Необходимо скомпилировать файл: «sievec default.sieve».
Файл "\/etc\/dovecot\/conf.d\/auth-sql.conf.ext"
passdb {
driver = sql
args = \/etc\/dovecot\/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=\/var\/mail\/vhosts\/%d\/%n
} Указание sql файлов для авторизации.
А сам файл — это способ авторизации.
Файл "\/etc\/dovecot\/dovecot-sql.conf.ext"
driver = mysql
connect = host=127.0.0.1 dbname=servermail user=usermail password=password
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';Это соответствует аналогичным настройкам для postfix.
Файл "\/etc\/dovecot\/dovecot.conf"
protocols = imap lmtp pop3
listen = *, ::
dict {
}
!include conf.d\/*.conf
!include_try local.conf Основной файл конфигурации.
Важно, что мы здесь указываем-добавляем протоколы.
============= SpamAssassin =============
apt-get install spamassassin spamcУстановим пакеты.
adduser spamd --disabled-loginДобавим пользователя от имени которого.
systemctl enable spamassassin.serviceВключаем авто-загрузку spamassassin сервис при загрузке.
Файл "\/etc\/default\/spamassassin":
CRON=1Включаем автоматическое обновление правил «по умолчанию».
Файл "\/etc\/spamassassin\/local.cf":
report_safe 0
use_bayes 1
bayes_auto_learn 1
bayes_auto_expire 1
bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
bayes_sql_dsn DBI:mysql:sa:localhost:3306
bayes_sql_username sa
bayes_sql_password passwordНеобходимо создать в mysql БД «sa» с пользователем «sa» и паролем «password» (заменить на что-то адекватное).
report_safe — это вместо письма будет присылаться отчет о письме-спаме.
use_bayes — это настройки машинного обучения spamassassin.
Остальные настройки spamassassin применялись ранее согласно статье.
.
.
.
.
============= Обращение к сообществу =============
Също така искам да предложа идея на общността за това как да се повиши нивото на защита на изпращаните имейли. След като се потопих дълбоко в темата за имейлите.
Потребителят да може на своя клиент (outlook, thunderbird, browser-plugin, ...) да създаде комплект ключове. Публичен и частен. Публичният — да се изпраща в DNS. Частният — да се съхранява на клиента. Имейл сървърите да могат да прилагат публичния ключ за изпращане до конкретния адресат.
И за защита от спам при такива имейли (да, имейл сървърът не може да види съдържанието) — трябва да се въведат 3 правила:
- Задължителен истински подпис DKIM, задължителен SPF, задължителен rDNS.
- Невронна мрежа на тема обучение на антиспам + база данни към нея от страната на клиента.
- Алгоритъмът на шифроване трябва да бъде такъв, че изпращащата страна да изразходва 100 пъти повече CPU мощност за шифроване от приемащата страна.
Освен публичните имейли — да се разработи стандарт за имейл-предложение «да започнем защитена кореспонденция». Един от потребителите (имейл кутия) изпраща на друга имейл кутия имейл с прикачен файл. В имейла текст-предложение за започване на защитен канал за комуникация и публичен ключ на притежателя на имейл кутията (при това частният ключ е от страната на клиента).
Може дори да се създават комплект ключове специално за всяка кореспонденция. Получателят може да приеме това предложение и да изпрати своя публичен ключ (също създаден специално за тази кореспонденция). След това първият потребител изпраща служебно контролно писмо (шифровано с публичния ключ на втория потребител) — при получаването му вторият потребител може да счита, че създаденият канал за комуникация е надежден. След това вторият потребител изпраща контролно писмо — и тогава първият потребител също може да смята създадения канал за защитен.
За борба с прихващането на ключове по пътя — е необходимо в протокола да се предвиди възможност за предаване поне на един публичен ключ с помощта на флашка.
И най-важното — за да работи всичко това (въпросът «а кой ще плати за това?»):
Въведете пощенски сертификати на цена от 10$ за 3 години. Които ще позволят на изпращача да посочи в dns, че „моите публични ключове са там“. И ще дават възможност за започване на защитено свързване. При това — да приемат такива връзки безплатно.
gmail най-накрая монетизира своите потребители. За 10$ за 3 години — право да създават защитени канали за кореспонденция.
============= Заключение =============
За тестване на цялата статия си планирах да наема отделен сървър за един месец и да купя домейн с ssl сертификат.
Но житейските обстоятелства се стекоха така, че този въпрос се забави с 2 месеца.
И ето, когато отново се появи свободно време — реших да публикувам статията така, каквато е, а не да рискувам да се забави публикацията още за една година.
Ако има достатъчно много въпроси от типа „е, тук не е достатъчно подробно описано“ — тогава вероятно ще се намерят сили наистина да взема отделен сървър с нов домейн и нов SSL сертификат и да опиша всичко по-подробно, а най-важното — да открия всички пропуснати важни детайли.
Също така бих искал да получа отзиви относно идеята за пощенските сертификати. Ако идеята се хареса — ще се опитам да намеря сили да напиша черновик за rfc.
При копиране на големи части от статията — посочвайте линк към тази статия.
При превод на какъвто и да е друг език — посочвайте линк към тази статия.
На английски език сам ще се опитам да преведа и ще оставя кръстосани линкове.
Източник: habr.com
