Debian + Postfix + Dovecot + Multidomain + SSL + IPv6 + OpenVPN + Multi-interfaces + SpamAssassin-learn + Bind

Acest articol este despre cum să configurăm un server de poștă electronică modern.
Postfix + Dovecot. SPF + DKIM + rDNS. Cu IPv6.
Cu criptare TSL. Cu suport pentru mai multe domenii — parte cu un certificat SSL real.
Cu protecție anti-spam și un scor ridicat de anti-spam comparativ cu alte servere de poștă electronică.
Cu suport pentru mai multe interfețe fizice.
Cu OpenVPN, la care se poate conecta prin IPv4, și care oferă IPv6.

Dacă nu doriți să învățați toate aceste tehnologii, dar doriți să configurați un astfel de server - atunci acest articol este pentru dumneavoastră.

Articolul nu încearcă să explice fiecare detaliu. Explicațiile se referă la ceea ce este configurat neobișnuit sau important din perspectiva utilizatorului.

Motivația de a configura un server de poștă electronică — este un vis vechi al meu. Poate că sună stupid, dar IMHO, este mult mai bine decât să visezi la o mașină nouă de marcă preferată.

Motivul pentru a configura IPv6 este dublu. Un specialist IT trebuie să studieze noi tehnologii constant pentru a supraviețui. Vreau să contribui modest la lupta împotriva cenzurii.

Motivația pentru configurarea OpenVPN - doar pentru ca IPv6 să funcționeze pe mașina locală.
Motivația pentru configurarea mai multor interfețe fizice - pe serverul meu am o interfață 'lentă, dar nelimitată', iar cealaltă 'rapidă, dar cu tarif'.

Motivația pentru configurarea Bind - providerul meu oferă un server DNS instabil, iar Google poate avea și el probleme. Vreau un server DNS stabil pentru uz personal.

Motivația pentru a scrie articolul - un draft a fost scris acum 10 luni și l-am consultat deja de două ori. Dacă chiar și autorului îi este necesar frecvent - există o mare probabilitate ca și altora să le fie necesar.

Nu există o soluție universală pentru serverele de poștă electronică. Dar voi încerca să scriu ceva de genul 'faceți așa și apoi, când totul va funcționa corect - aruncați ce este în plus'.

Am un server de Colocare la compania tech.ru. Am ocazia să compar cu OVH, Hetzner, AWS. Pentru a rezolva această problemă, va fi mult mai eficient să colaborez cu tech.ru.

Pe server este instalat Debian 9.

Pe server sunt 2 interfețe `eno1` și `eno2`. Prima este nelimitată, iar a doua rapidă, respectiv.

Am 3 adrese IP statice, XX.XX.XX.X0, XX.XX.XX.X1 și XX.XX.XX.X2 pe interfața `eno1` și XX.XX.XX.X5 pe interfața `eno2`.

Am un pool de adrese IPv6 XXXX:XXXX:XXXX:XXXX::/64, care sunt alocate interfeței `eno1` și din care XXXX:XXXX:XXXX:XXXX:1:2::/96 au fost alocate pe `eno2` la cererea mea.

Există 3 domenii `domain1.com`, `domain2.com`, `domain3.com`. Pentru `domain1.com` și `domain3.com` există un certificat SSL.

Există un cont Google, la care vreau să asociez căsuța poștală `vasya.pupkin@domain1.com` (primirea și trimiterea de emailuri direct din interfața Gmail).
Trebuie să existe o căsuță poștală `support@domain2.com`, ale cărei emailuri vreau să le văd în Gmail. Și ocazional să am posibilitatea de a trimite emailuri din numele `support@domain2.com` prin intermediul interfeței web.

Trebuie să existe o căsuță poștală `ivanov@domain3.com`, care va fi folosită de Ivanov de pe iPhone-ul său.

Emailurile trimise trebuie să respecte toate cerințele actuale în materie de anti-spam.
Trebuie să existe cel mai înalt nivel de criptare prevăzut în rețelele publice.
Trebuie să existe suport pentru IPv6 atât pentru trimiterea, cât și pentru primirea emailurilor.
Trebuie să existe SpamAssassin, care să nu șteargă niciodată emailurile. Acesta va face fie bounce, fie va trece emailurile, fie le va trimite în folderul IMAP „Spam”.
Trebuie configurat auto-aprenderea pentru SpamAssassin: dacă mut un email în folderul „Spam”, acesta se va învăța din asta; dacă mut un email din folderul „Spam”, acesta se va învăța și de la asta. Rezultatele învățării SpamAssassin trebuie să influențeze probabilitatea ca un email să ajungă în folderul „Spam”.
Scripturile PHP trebuie să poată trimite emailuri în numele oricărui domeniu de pe acest server.
Trebuie să existe un serviciu OpenVPN, cu posibilitatea de a utiliza IPv6 pe client, care nu are IPv6.

Mai întâi trebuie să configurăm interfețele și rutarea, inclusiv IPv6.
Apoi, trebuie să configurăm OpenVPN, care va conecta prin IPv4 și va oferi clientului o adresă IPv6 statică reală. Acest client va avea acces la toate serviciile IPv6 de pe server și va putea accesa orice resurse IPv6 pe internet.
Apoi, trebuie să configurăm Postfix pentru trimiterea emailurilor + SPF + DKIM + rDNS și alte asemenea detalii.
Apoi, trebuie să configurăm Dovecot și să setăm Multidomeniu.
Apoi, trebuie să configurăm SpamAssassin și să setăm învățarea.
În final, trebuie să instalăm Bind.

============= Interfețe multiple =============

Pentru configurarea interfețelor trebuie să scrieți următoarele în „/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

Aceste setări pot fi aplicate pe orice server în tech.ru (cu o mică aprobată din partea suportului) și vor funcționa imediat.

Dacă ați avut experiență în configurarea unor lucruri similare pentru Hetzner, OVH — acolo este diferit. Mai complicat.

eno1 este denumirea plăcii de rețea #1 (lent, dar fără limită).
eno2 este denumirea plăcii de rețea #2 (rapid, dar cu tarif).
tun0 - este este numele adaptorului virtual de rețea de la OpenVPN.
XX.XX.XX.X0 - IPv4 #1 pe eno1.
XX.XX.XX.X1 - IPv4 #2 pe eno1.
XX.XX.XX.X2 - IPv4 #3 pe eno1.
XX.XX.XX.X5 - IPv4 #1 pe eno2.
XX.XX.XX.1 - gateway IPv4.
XXXX:XXXX:XXXX:XXXX::/64 - IPv6 pentru întregul server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 - IPv6 pentru eno2, tot restul intră pe eno1.
XXXX:XXXX:XXXX:XXXX::1 - gateway IPv6 (se remarcă că aici se poate/de fapt ar trebui să se facă altfel. Să se indice IPv6-ul switch-ului).
dns-nameservers - sunt specificate 127.0.0.1 (deoarece bind este instalat local) și 213.248.1.6 (acesta provine de la tech.ru).

«table eno1t» și «table eno2t» - semnificația acestor route-rule este că traficul care intră prin eno1 -> va ieși tot prin el, iar traficul care intră prin eno2 -> va ieși prin el. De asemenea, conexiunile inițiate de server vor ieși prin eno1.

ip route add default via XX.XX.XX.1 table eno1t

Această comandă stabilește că orice trafic neclar care se încadrează sub orice regulă marcată „table eno1t” -> să fie direcționat către interfața eno1.

ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1t

Această comandă stabilește că orice trafic inițiat de server să fie direcționat către interfața eno1.

ip rule add table eno1t from XX.XX.XX.X0
ip rule add table eno1t to XX.XX.XX.X0

Această comandă stabilește regulile de marcaj pentru trafic.

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

Acest bloc stabilește un al doilea IPv4 pentru interfața eno1.

ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t

Această comandă stabilește ruta de la clienții OpenVPN către IPv4-urile locale, cu excepția XX.XX.XX.X0.
De ce această comandă este suficientă pentru toate IPv4 - încă nu înțeleg.

iface eno1 inet6 static
        address XXXX:XXXX:XXXX:XXXX:1:1::/64
        gateway XXXX:XXXX:XXXX:XXXX::1

Aici stabilim adresa pentru interfață. Serverul o va folosi ca adresă „de ieșire”. Nu va fi folosită în alt mod.

De ce este specificat „:1:1::” atât de complicat? Pentru ca OpenVPN să funcționeze corect, doar pentru asta. Despre asta mai multe detalii mai târziu.

Referitor la gateway - așa funcționează și este bine. Dar corect ar fi ca aici să se indice IPv6-ul switch-ului la care este conectat serverul.

Cu toate acestea, dintr-un motiv sau altul, IPv6 nu mai funcționează dacă fac așa. Probabil este o problemă de la tech.ru.

ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE

Aceasta este adăugarea unei adrese IPv6 pe interfață. Dacă este nevoie de o sută de adrese - înseamnă că vor fi o sută de linii în acest fișier.

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

Am marcat adresele și subrețelele tuturor interfețelor, pentru a fi mai vizibil.
eno1 — trebuie să fie neapărat „/64” — deoarece acesta este întregul nostru pool de adrese.
tun0 — subrețeaua trebuie să fie neapărat mai mare decât eno1. Altfel, nu se va putea configura gateway-ul IPv6 pentru clienții OpenVPN.
eno2 — subrețeaua trebuie să fie neapărat mai mare decât tun0. Altfel, clienții OpenVPN nu vor putea accesa adresele IPv6 locale.
Pentru o mai bună ilustrare, am ales un pas de subrețea de 16, dar, dacă doriți, se poate face chiar un pas de „1”.
Astfel, 64+16 = 80, iar 80+16 = 96.

Pentru o și mai bună ilustrare:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — acestea sunt adresele care trebuie să fie alocate unor site-uri sau servicii pe interfața eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — acestea sunt adresele care trebuie să fie alocate unor site-uri sau servicii pe interfața eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — acestea sunt adresele care trebuie să fie alocate clienților OpenVPN sau utilizate ca adrese de serviciu OpenVPN.

Pentru configurarea rețelei — trebuie să existe posibilitatea de a reporni serverul.
Modificările IPv4 sunt preluate la executarea (neapărat să fie rulate în screen — altfel această comandă va cădea pur și simplu rețeaua pe server):

/etc/init.d/networking restart

În fișierul „/etc/iproute2/rt_tables” adăugați la final:

100 eno1t
101 eno2t

Fără aceasta, nu se pot folosi tabele personalizate în fișierul „/etc/network/interfaces”.
Numerele trebuie să fie unice și mai mici de 65535.

Modificările IPv6 se efectuează ușor fără repornire, dar pentru aceasta trebuie să învățați cel puțin trei comenzi:

ip -6 addr ...
ip -6 route ...
ip -6 neigh ...

Configurarea „/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

Acestea sunt setările „sysctl” ale serverului meu. Voi sublinia importanța.

net.ipv4.ip_forward = 1

Fără aceasta, OpenVPN nu va funcționa deloc.

net.ipv6.ip_nonlocal_bind = 1

Oricine încearcă să efectueze bind IPv6 (de exemplu nginx) imediat după ce interfața a fost schimbată — va primi o eroare. Că această adresă nu este disponibilă.

Pentru a evita această situație, se face această configurare.

net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1

Fără aceste setări, traficul IPv6 de la clientul OpenVPN nu iese în lume.

Alte setări fie nu sunt relevante, fie nu-mi amintesc de ce sunt.
Dar, pentru orice eventualitate, las „așa cum este”.

Pentru ca modificările acestui fișier să fie preluate fără repornirea serverului — trebuie să executați comanda:

sysctl -p

Mai în detaliu despre regulile „table”: habr.com/post/108690

============= OpenVPN =============

OpenVPN IPv4 nu funcționează fără iptables.

Iată iptables-urile mele pentru 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 este este adresa mea statică IPv4 a mașinii locale.
10.8.0.0/24 este rețeaua IPv4 openvpn. Adresele IPv4 pentru clienții openvpn.
Secvența regulilor este importantă.

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

Aceasta este o restricție, astfel încât doar eu, de la adresa mea statică IP, să pot folosi OpenVPN.

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
  -- sau --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADE

Pentru a permite pachetelor IPv4 să treacă între clienții OpenVPN și internet — trebuie să folosiți una dintre aceste comenzi.

Pentru diferite situații, una dintre opțiuni nu este potrivită.
Pentru cazul meu, ambele comenzi sunt potrivite.
După ce am citit documentația, am ales prima opțiune, deoarece consumă mai puțin CPU.

Pentru ca toate setările iptables să fie preluate după restart — trebuie să le salvați undeva.

iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

Aceste nume nu au fost alese întâmplător. Ele sunt utilizate de pachetul 'iptables-persistent'.

apt-get install iptables-persistent

Instalarea pachetului principal OpenVPN:

apt-get install openvpn easy-rsa

Să configurăm șablonul pentru certificate (înlocuiți cu valorile dumneavoastră):

make-cadir ~/openvpn-ca
cd ~/openvpn-ca
ln -s openssl-1.0.0.cnf openssl.cnf

Să edităm setările șablonului certificatelor:

mcedit vars

...
# Acestea sunt valorile implicite pentru câmpuri
# care vor fi plasate în certificat.
# Nu lăsați niciunul din aceste câmpuri liber.
export KEY_COUNTRY="RO"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Own"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"

# X509 Subject Field
export KEY_NAME="server"
...

Creăm certificatul serverului:

cd ~/openvpn-ca
source vars
./clean-all
./build-ca
./build-key-server server
./build-dh
openvpn --genkey --secret keys/ta.key

Pregătim posibilitatea de a crea fișierele finale „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

Pregătim un script care va combina toate fișierele într-un singur fișier 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

Creăm primul client OpenVPN:

cd ~/openvpn-ca
source vars
./build-key client-name
cd ~/client-configs
./make_config.sh client-name

Fișierul „~/client-configs/files/client-name.ovpn” este trimis pe dispozitivul clientului.

Pentru clienții iOS va fi nevoie de un truc:
Conținutul etichetei „tls-auth” trebuie să fie fără comentarii.
De asemenea, trebuie să setăm „key-direction 1” imediat înainte de eticheta „tls-auth”.

Să configurăm fișierul de configurare al serverului 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

Acest lucru este necesar pentru a aloca o adresă statică fiecărui client (nu este obligatoriu, dar eu folosesc):

# Client config dir
client-config-dir /etc/openvpn/ccd

Cea mai complexă și esențială detaliu.

Din păcate, OpenVPN încă nu poate configura automat gateway-ul IPv6 pentru clienți.
Trebuie să trecem manual prin aceasta pentru fiecare client.

# 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"

Fișierul „/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

Fișierul „/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

Ambele scripturi folosesc fișierul „/etc/openvpn/variables”:

# Subnet
prefix=XXXX:XXXX:XXXX:XXXX:2:
# netmask
prefixlen=112

De ce este scris așa aici - nu-mi amintesc.

Acum pare ciudat netmask = 112 (ar trebui să fie 96).
Și prefixul este ciudat, nu corespunde rețelei tun0.
Dar bine, îl las „așa cum este”.

cipher DES-EDE3-CBC

Este o chestiune de preferințe - am ales această metodă de criptare a conexiunii.

Mai multe detalii despre configurarea OpenVPN IPv4.

Mai multe detalii despre configurarea OpenVPN IPv6.

============= Postfix =============

Instalarea pachetului principal:

apt-get install postfix

La instalare, alegeți „internet-site”.

Fișierul meu „/etc/postfix/main.cf” arată astfel:

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

# adăugarea .domain este sarcina MUA-ului.
append_dot_mydomain = no

readme_directory = no

# Vezi http://www.postfix.org/COMPATIBILITY_README.html -- implicit 2 la
# instalări proaspete.
compatibility_level = 2

# Parametrii 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

# Tip de stocare
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

# Setările 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

# Adresa IP pe domeniu
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcre

Să analizăm detaliile acestei configurații.

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key

Potrivit utilizatorilor de pe Habrahabr, acest bloc conține `dezinformare și teze incorecte`.Abia după 8 ani de carieră am început să înțeleg cum funcționează SSL.

Așadar, îmi voi lua libertatea de a descrie cum se folosește SSL (fără a răspunde la întrebările „Cum funcționează?” și „De ce funcționează?”).

Bazele criptării moderne constau în crearea unui set de chei (două șiruri foarte lungi de caractere).

O cheie este privată, iar cealaltă cheie este „publică”. Cheia privată este păstrată cu mare grijă în secret. Cheia publică este distribuită tuturor doritorilor.

Prin intermediul cheii publice, se poate cripta un șir de text astfel încât să fie decriptat doar de proprietarul cheii private.
Și iată întreaga bază a tehnologiei.

Pasul nr. 1 – site-uri https.
Browserul, atunci când accesează un site, află de la serverul web că site-ul este https și, prin urmare, solicită cheia publică.
Serverul web oferă cheia publică. Browserul, folosind cheia publică, criptează http-request și îl trimite.
Conținutul http-request poate fi citit doar de cel care are cheia privată, adică doar serverul la care se face solicitarea.
Http-request conține cel puțin un URI. Așadar, dacă într-o țară se încearcă restricționarea accesului nu la întregul site, ci la o pagină specifică — atunci pentru site-urile https este imposibil.

Pasul nr. 2 — răspuns criptat.
Serverul web dă un răspuns care poate fi citit cu ușurință pe parcurs.
Soluția este extrem de simplă — browserul își formează local o pereche de chei private-publice pentru fiecare site https.
Și împreună cu cererea cheii publice a site-ului, trimite cheia sa publică locală.
Serverul web o reține și, la trimiterea http-response, criptează cu această cheie publică clientul specific.
Acum http-response poate fi decriptat doar de către deținătorul cheii private a browserului clientului (adică de către clientul însuși).

Pasul nr. 3 — stabilirea unei conexiuni securizate prin canal public.
În exemplul nr. 2 există o vulnerabilitate — nimic nu împiedică persoanele malițioase să intercepteze http-request și să editeze informația despre cheia publică.
Astfel, intermediarul va putea vedea întregul conținut al mesajelor trimise și primite până când canalul de comunicare nu se schimbă.
Să luptăm împotriva acestei probleme este extrem de simplu — este suficient să trimitem cheia publică a browserului ca un mesaj criptat cu cheia publică a serverului web.
Serverul web, atunci, trimite în primul rând un răspuns de tipul „cheia ta publică este aceasta” și criptează acest mesaj cu aceeași cheie publică.
Browserul verifică răspunsul — dacă a venit mesajul „cheia ta publică este aceasta” — atunci este o garanție 100% că acest canal de comunicare este sigur.
Cât de sigur este?
Crearea unui astfel de canal de comunicare sigur se face cu o viteză de ping*2. De exemplu, 20ms.
Atacatorul trebuie să aibă deja cheia privată a uneia dintre părți. Sau să găsească cheia privată în câteva milisecunde.
Spargerea unei chei private moderne va dura decenii pe un supercomputer.

Pasul nr. 4 — o bază de date publică a cheilor publice.
Este evident că în toată această poveste există o posibilitate pentru un atacator care se află pe canalul de comunicare între client și server.
Posibilitatea ca clientul să se prezinte ca server, iar serverul să se prezinte ca client. Și să se semuleze o pereche de chei în ambele direcții.
Atunci, atacatorul va vedea tot traficul și va avea posibilitatea de a "edita" traficul.
De exemplu, poate schimba adresa unde sunt trimise banii sau copia parola de la banca online sau bloca conținutul "nepotrivit".
Pentru a combate astfel de atacatori, s-a creat o bază de date publică cu chei publice pentru fiecare site https.
Fiecare browser "știe" despre existența a aproximativ 200 de astfel de baze de date. Acest lucru este preinstalat în fiecare browser.
"Cunoașterea" este susținută de cheia publică a fiecărui certificat. Adică, conexiunea cu fiecare centru de certificare specific nu poate fi falsificată.

Acum există o înțelegere simplă despre cum să folosești SSL pentru https.
Dacă folosești puțin raționamentul, vei înțelege cum agențiile specializate pot sparge această construcție. Dar le va costa eforturi enorme.
Iar pentru organizații, a spiona NSA sau CIA — este practic imposibil să spargi nivelul existent de protecție, chiar și pentru VIP-uri.

De asemenea, voi adăuga despre conexiunile ssh. Acolo nu există chei publice, ce este de făcut? Problema se rezolvă în două moduri.
Varianta ssh-pe-parolă:
La prima conexiune, clientul ssh trebuie să avertizeze că avem o nouă cheie publică de la serverul ssh.
Și la conexiunile ulterioare, dacă apare avertismentul "nouă cheie publică de la serverul ssh" — va însemna că cineva încearcă să vă spioneze.
Sau la prima conexiune ați fost ascultați, iar acum comunicați cu serverul fără intermediari.
De fapt, din cauza că faptul de spionaj este ușor, rapid și fără eforturi să fie descoperit — această metodă de atac este folosită doar în cazuri speciale, pentru clienți specifici.

Varianta ssh-pe-cheie:
Luăm un stick USB, scriem pe el cheia privată pentru serverul ssh (pentru asta există termeni și multe nuanțe semnificative, dar scriu un ghid, nu un manual de utilizare).
Cheia publică o păstrăm pe mașina unde va fi clientul ssh și o păstrăm și pe aceasta secret.
Aducem stick-ul la server, îl conectăm, copiem cheia privată, iar stick-ul îl ardem și împrăștiem cenușa în vânt (sau cel puțin îl formatăm cu zero).
Și gata — după o astfel de operațiune va deveni imposibil să fii spart prin acea conexiune ssh. Desigur, în câțiva ani, pe un supercomputer, ar putea fi analizat traficul — dar aceasta este o poveste separată.

Îmi cer scuze pentru offtopic.

Așadar, acum că teoria este cunoscută. Voi povesti despre fluxul de creare a certificatului ssl.

Folosind „openssl genrsa” creăm cheia privată și „schițele” pentru cheia publică.
„schițele” le trimitem unei companii externe, căreia îi plătim aproximativ 9 dolari pentru cel mai simplu certificat.

După câteva ore, primim de la această companie externă cheia noastră „publică” și și un set de câteva chei publice.

De ce să plătesc unei companii externe pentru a emite cheia mea publică — este o întrebare separată, nu ne ocupăm acum de aceasta.

Acum este clar care este sensul inscripției:

smtpd_tls_key_file=/<etc/ssl/domain1.com.2018.key

În folderul „/<etc/ssl” sunt stocate toate fișierele pentru problemele ssl.
domain1.com — numele domeniului.
2018 — anul creării cheilor.
„key” — înseamnă că fișierul este cheia privată.

Și sensul acestui fișier:

smtpd_tls_cert_file=/<etc/ssl/domain1.com.2018.chained.crt
domain1.com — numele domeniului.
2018 — anul creării cheilor.
chained — înseamnă că aici este un lanț de chei publice (prima — cheia noastră publică și restul — ceea ce a venit de la compania care a emis cheia publică).
crt — înseamnă că aici este un certificat gata (cheia publică cu explicații tehnice).

smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1

Această setare nu este utilizată în acest caz, dar este scrisă ca exemplu.

Pentru că o eroare în acest parametru va duce la trimiterea de spam de la serverul vostru (fără voința voastră).

Apoi trebuie să dovediți tuturor că nu sunteți vinovați.

recipient_delimiter = +

Probabil mulți nu știu, așa că acest simbol standard este folosit pentru clasificarea mesajelor, și acest lucru este susținut de majoritatea serverelor de poștă moderne.

De exemplu, dacă aveți o cutie poștală „username@gmail.com”, încercați să trimiteți la „username+spam@gmail.com” — vedeți ce iese.

inet_protocols = ipv4

Aceasta ar putea confunda.

Dar nu este întâmplător. Fiecare nou domeniu — implicit doar IPv4, apoi activez IPv6 pentru fiecare în parte.

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

Aici stabilim că toată poșta de intrare merge către dovecot.
Iar regulile pentru domeniu, cutie poștală, alias — le vedem în Baza de Date.

/etc/postfix/mysql-virtual-mailbox-domains.cf

user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

/etc/postfix/mysql-virtual-mailbox-maps.cf

user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'

/etc/postfix/mysql-virtual-alias-maps.cf

user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = 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

Acum postfix știe că poate accepta e-mailuri pentru trimitere doar prin autentificarea cu dovecot.

Nu înțeleg de ce este necesar să duplicăm asta aici. Am specificat deja în „virtual_transport” tot ce trebuie.

Dar sistemul postfix este foarte vechi – probabil sunt acest gen de workaround-uri din vremuri trecute.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Aceasta trebuie configurată pentru fiecare server de e-mail în parte.

Am la dispoziție 3 servere de e-mail și aceste configurații sunt foarte diferite din cauza cerințelor variate de utilizare.

Trebuie să configurezi cu atenție – altfel spamul va curge către tine sau, și mai rău, spamul va curge de la tine.

# SPF
policyd-spf_time_limit = 3600

Configurație pentru un plugin legat de verificarea SPF a e-mailurilor primite.

# 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

Configurația prin care toate e-mailurile trimise trebuie să fie semnate cu DKIM.

# IP address per domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcre

Este o detaliere cheie în rutarea e-mailurilor când trimitem e-mailuri din scripturi php.

Fișierul „/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:

În stânga – expresii regulate. În dreapta – eticheta care marchează e-mailul.
Postfix, conform etichetei, va lua în considerare câteva linii suplimentare de configurație pentru e-mailul specific.

Cum va fi reconstruit postfix pentru un anumit e-mail – va fi specificat în „master.cf”.

Liniile 4, 5, 6 – acestea sunt esențiale. Din ce domeniu trimitem e-mailul – așa punem eticheta.
Dar nu întotdeauna în scripturile php din codul vechi este specificat câmpul „from”. Atunci intervine numele utilizatorului.

Articolul este oricum extins – nu mi-ar plăcea să mă abțin de la configurarea nginx+fpm.

Pe scurt – pentru fiecare site definim un utilizator linux propriu. Și, în consecință, propriul fpm-pool.

Fpm-pool utilizează orice versiune php (este grozav că pe un singur server fără probleme putem folosi o versiune php diferită pentru site-urile vecine, chiar și cu php.ini diferit).

Așadar, utilizatorul linux specific „www-domain2” are site-ul domain2.com. Acest site are un cod pentru trimiterea e-mailurilor fără specificarea câmpului from.

Chiar și în acest caz, e-mailurile vor pleca corect și nu vor ajunge niciodată în spam.

Fișierul meu „/etc/postfix/master.cf” arată așa:

...
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

Fișierul este incomplet — este deja foarte mare.
Am marcat doar ce a fost modificat.

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}

Acestea sunt setările legate de spamassassin, despre el mai târziu.

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

Permitem conectarea la serverul de mail prin portul 587.
Pentru aceasta, este necesară autentificarea.

policyd-spf  unix  -       n       n       -       0       spawn
user=policyd-spf argv=/usr/bin/policyd-spf

Activăm verificarea SPF.

apt-get install postfix-policyd-spf-python

Vom instala pachetul pentru verificările 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

Acesta este cel mai interesant. Aceasta este posibilitatea de a trimite e-mailuri pentru un anumit domeniu de la o anumită adresă IPv4/IPv6.

Se face acest lucru pentru rDNS. rDNS este obținerea unei anumite stringuri pe baza adresei IP.
Și pentru e-mailuri, această posibilitate este utilizată pentru a confirma că helo se potrivește cu rDNS-ul adresei de la care a fost trimis e-mailul.

Dacă helo nu corespunde domeniului de e-mail de la care a fost trimis, se acumulează puncte de spam.

Helo care nu corespunde rDNS-ului — se acumulează multe puncte de spam.
Prin urmare, pentru fiecare domeniu, ar trebui să existe propria adresă IP.
Pentru OVH — în consolă există opțiunea de a specifica rDNS.
Pentru tech.ru — este o problemă care se rezolvă prin suport.
Pentru AWS — este o problemă care se rezolvă prin suport.
«inet_protocols» și «smtp_bind_address6» — acestea activează suportul pentru IPv6.
Este necesar să specificați și rDNS pentru IPv6.
«syslog_name» — acesta este pentru a facilita citirea jurnalelor.

Cumpărați certificatul recomand aici.

Configurarea legăturii postfix+dovecot aici.

Configurarea SPF.

============= Dovecot =============

apt-get install dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql dovecot-antispam

Configurarea mysql, instalăm pachetele necesare.

Fișierul «/etc/dovecot/conf.d/10-auth.conf»

disable_plaintext_auth = yes
auth_mechanisms = plain login

Autentificarea doar în mod criptat.

Fișierul «/etc/dovecot/conf.d/10-mail.conf»

mail_location = maildir:/var/mail/vhosts/%d/%n

Aici vom specifica locația de stocare a mesajelor.

Vreau ca acestea să fie stocate în fișiere și grupate pe domenii.

Fișierul «/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 {
  }
}

Acesta este fișierul principal de configurare pentru dovecot.
Aici dezactivăm conexiunile nesecurizate.
Și activăm conexiunile securizate.

Fișierul «/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
}

Configurăm ssl. Specificăm că ssl este obligatoriu.
Și certificatul în sine. O detaliu importantă – directiva «local». Aceasta indică, în cazul unei conexiuni la care IPv4 local, care certificat ssl trebuie folosit.

Apropo, IPv6 nu este configurat aici, voi corecta această omisiune cândva mai târziu.
XX.XX.XX.X5 (domain2) — nu există certificat. Pentru conexiunea clienților trebuie să specificați domain1.com.
XX.XX.XX.X2 (domain3) — există un certificat, pentru conexiunea clienților se poate specifica domain1.com sau domain3.com.

Fișierul «/etc/dovecot/conf.d/15-lda.conf»

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Aceasta va fi necesară ulterior pentru spamassassin.

Fișierul «/etc/dovecot/conf.d/20-imap.conf»

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Acesta este pluginul antispam. Este necesar pentru antrenarea spamassasin în momentul mutării în/din folderul «Spam».

Fișierul «/etc/dovecot/conf.d/20-pop3.conf»

protocol pop3 {
}

Pur și simplu avem un astfel de fișier.

Fișierul «/etc/dovecot/conf.d/20-lmtp.conf»

protocol lmtp {
  mail_plugins = $mail_plugins sieve
  postmaster_address = admin@domain1.com
}

Configurarea lmtp.

Fișierul „/etc/dovecot/conf.d/90-antispam.conf”

plugin {
  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
}

Setările de învățare a spamassassin în momentul mutării în/din folderul „Spam”.

Fișierul „/etc/dovecot/conf.d/90-sieve.conf”

plugin {
  sieve = ~/dovecot.sieve
  sieve_dir = ~/sieve
  sieve_after = /var/lib/dovecot/sieve/default.sieve
}

Fișierul în care se indică ce să facă cu emailurile primite.

Fișierul „/var/lib/dovecot/sieve/default.sieve”

require ["fileinto", "mailbox"];

if header :contains "X-Spam-Flag" "YES" {
        fileinto :create "Spam";
}

Trebuie să compilezi fișierul: „sievec default.sieve”.

Fișierul „/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
}

Indicația fișierelor sql pentru autorizare.
Iar fișierul acesta — ca metodă de autorizare.

Fișierul „/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';

Acestea corespund setărilor similare pentru postfix.

Fișierul „/etc/dovecot/dovecot.conf”

protocols = imap lmtp pop3
listen = *, ::
dict {
}
!include conf.d/*.conf
!include_try local.conf

Fișierul principal de configurare.
Important este faptul că aici indicăm/adăugăm protocoale.

============= SpamAssassin =============

apt-get install spamassassin spamc

Vom instala pachetele.

adduser spamd --disabled-login

Să adăugăm utilizatorul sub care va rula.

systemctl enable spamassassin.service

Activăm auto-încărcarea serviciului spamassassin la pornire.

Fișierul „/etc/default/spamassassin”:

CRON=1

Activăm actualizarea automată a regulilor „implicit”.

Fișierul „/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

Trebuie să creăm în baza de date mysql „sa” cu utilizatorul „sa” și parola „password” (înlocuiește cu ceva mai adecvat).

report_safe — în loc de email, va fi trimis un raport despre email-ul de spam.
use_bayes — acestea sunt setările de învățare automată spamassassin.

Celelalte setări spamassassin au fost aplicate anterior conform articolului.

Setarea generală „spamassassin”.
Despre mutarea emailurilor noi de spam în folderul IMAP „Spam”.
Despre legătura simplă Dovecot + SpamAssassin.
Îți recomand să citești teorie despre învățarea spamassassin în mutarea emailurilor în folderele imap (și nu recomand aplicarea acesteia).

============= Apel către comunitate =============

Aș dori, de asemenea, să propun o idee în comunitate despre cum să creștem nivelul de securitate al e-mailurilor trimise. Având în vedere că m-am implicat atât de profund în tema e-mailului.

Pentru ca utilizatorul să își poată crea la clientul său (Outlook, Thunderbird, browser-plugin, ...) o pereche de chei. O cheie publică și una privată. Cheia publică — să fie trimisă în DNS. Cheia privată — să fie păstrată la client. Serverele de e-mail ar trebui să poată aplica cheia publică pentru a trimite către un anumit destinatar.

Și pentru a ne proteja de spam în cazul acestor e-mailuri (da, serverul de e-mail nu va putea verifica conținutul) — ar trebui introduse 3 reguli:

  1. Semnătura DKIM autentică obligatorie, SPF obligatoriu, rDNS obligatoriu.
  2. O rețea neuronală axată pe învățarea anti-spam + o bază de date asociată pe partea clientului.
  3. Algoritmul de criptare ar trebui să fie astfel încât partea expeditorului să cheltuie de 100 de ori mai multe resurse CPU pentru criptare decât partea destinatarului.

Pe lângă e-mailurile publice — să dezvoltăm un standard de e-mail „pentru a începe o corespondență protejată”. Unul dintre utilizatori (cutia poștală) trimite unui alt utilizator un e-mail cu un atașament. În e-mail există un text-propunere pentru a începe un canal de comunicare protejat și cheia publică a proprietarului cutiei poștale (între timp, cheia privată să fie pe partea clientului).

Puteți chiar crea câteva chei special pentru fiecare corespondență. Utilizatorul-destinatar poate accepta această propunere și să trimită cheia sa publică (de asemenea, creată special pentru această corespondență). Apoi, primul utilizator trimite un e-mail de control (criptat cu cheia publică a celui de-al doilea utilizator) — la primirea acestuia, al doilea utilizator poate considera canalul de comunicare format ca fiind de încredere. Apoi, al doilea utilizator trimite un e-mail de control — și atunci primul utilizator poate considera, de asemenea, canalul format ca fiind protejat.

Pentru a combate interceptarea cheilor pe drum — trebuie prevăzută în protocol posibilitatea de a transmite cel puțin o cheie publică prin intermediul unui stick USB.

Și cel mai important — pentru ca toate acestea să funcționeze (întrebarea „cine va plăti pentru asta?”):
Introducerea certificatelor de e-mail, costând de la 10$ pe 3 ani. Acestea vor permite expeditorului să specifice în DNS că „cheile mele publice sunt acolo”. Vor permite inițierea unei conexiuni securizate. În plus, vor accepta astfel de conexiuni gratuit.
gmail își monetizează în sfârșit utilizatorii. Pentru 10$ pe 3 ani – dreptul de a crea canale de comunicare securizate.

============= Concluzie =============

Pentru testarea întregului articol, intenționam să închiriez un server dedicat pentru o lună și să cumpăr un domeniu cu certificat SSL.

Dar circumstanțele vieții au făcut ca această problemă să dureze 2 luni.
Și iată că, atunci când am avut din nou timp liber – am decis să public articolul așa cum este, și nu să risc că publicația se va întinde pe încă un an.

Dacă vor fi suficient de multe întrebări de genul „aici nu este descris suficient de detaliat” – atunci probabil că se vor găsi resursele necesare pentru a lua un server dedicat cu un domeniu nou și cu un nou certificat SSL și a detalia și, mai ales, a identifica toate detaliile importante care au fost omise.

De asemenea, mi-ar plăcea să primesc feedback pe tema ideii de certificate de e-mail. Dacă ideea va fi bine primită – voi încerca să găsesc resursele necesare pentru a scrie un draft pentru RFC.

Atunci când copiați porțiuni mari din articol – indicați un link către acest articol.
Când traduceți în orice altă limbă – indicați un link către acest articol.
Încerc să traduc eu în limba engleză și voi lăsa linkuri încrucișate.


Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster