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

Questo articolo spiega come configurare un moderno server di posta.
Postfix + Dovecot. SPF + DKIM + rDNS. Con IPv6.
Con crittografia TSL. Con supporto per più domini — incluso un vero certificato SSL.
Con protezione anti-spam e un alto punteggio anti-spam rispetto ad altri server di posta.
Con supporto per più interfacce fisiche.
Con OpenVPN, al quale ci si connette tramite IPv4, fornendo IPv6.

Se non vuoi studiare tutte queste tecnologie, ma desideri configurare un server simile — allora questo articolo è per te.

L'articolo non cerca di spiegare ogni dettaglio. Le spiegazioni riguardano ciò che è configurato in modo non standard o è rilevante dal punto di vista del consumatore.

La motivazione per configurare un server di posta è un mio vecchio sogno. Può sembrare sciocco, ma IMHO, è molto meglio che sognare un'auto nuova del mio marchio preferito.

Le motivazioni per configurare IPv6 sono due. Un professionista IT deve continuamente studiare nuove tecnologie per sopravvivere. Vorrei dare il mio modesto contributo alla lotta contro la censura.

La motivazione per configurare OpenVPN è solo per far funzionare IPv6 sulla macchina locale.
La motivazione per configurare più interfacce fisiche è che sul mio server ho un'interfaccia "lenta, ma illimitata" e un'altra "veloce, ma a pagamento delle tariffe".

La motivazione per configurare Bind è che il mio provider offre un server DNS instabile e Google può anche avere dei problemi. Voglio un server DNS stabile per uso personale.

La motivazione per scrivere un articolo è che la bozza è stata scritta 10 mesi fa e l'ho già consultata due volte. Se anche all'autore serve regolarmente, c'è una grande probabilità che anche ad altri serva.

Non esiste una soluzione universale per il server di posta. Ma cercherò di scrivere qualcosa come "fate in questo modo e poi, quando tutto funziona correttamente, rimuovete ciò che è superfluo".

Ho un server di colocation con la azienda tech.ru. C'è la possibilità di fare un confronto con OVH, Hetzner, AWS. Per risolvere questo compito, sarà molto più efficace collaborare proprio con tech.ru.

Sul server è installato Debian 9.

Il server ha 2 interfacce `eno1` e `eno2`. La prima è illimitata, mentre la seconda è veloce.

Ci sono 3 indirizzi IP statici, XX.XX.XX.X0, XX.XX.XX.X1 e XX.XX.XX.X2 sulla interfaccia `eno1` e XX.XX.XX.X5 sulla interfaccia `eno2`.

Disponiamo di un pool di indirizzi IPv6 XXXX:XXXX:XXXX:XXXX::/64 assegnati all'interfaccia `eno1` e su mia richiesta sono stati assegnati XXXX:XXXX:XXXX:XXXX:1:2::/96 a `eno2`.

Abbiamo 3 domini `domain1.com`, `domain2.com`, `domain3.com`. Per `domain1.com` e `domain3.com` è disponibile un certificato SSL.

Ho un account Google al quale desidero associare la casella di posta `vasya.pupkin@domain1.com` (per ricevere e inviare email direttamente dall'interfaccia di Gmail).
Deve essere presente una casella di posta `support@domain2.com`, di cui desidero ricevere una copia delle email nella mia Gmail. E avere la possibilità di inviare occasionalmente email a nome di `support@domain2.com` tramite l'interfaccia web.

Deve esserci la casella di posta `ivanov@domain3.com`, utilizzata da Ivanov dal suo iPhone.

Le email inviate devono soddisfare tutti i requisiti moderni contro lo spam.
Deve esserci il massimo livello di crittografia previsto nelle reti pubbliche.
Deve esserci supporto per IPv6 sia per l'invio che per la ricezione delle email.
Deve esserci SpamAssassin, che non eliminerà mai le email. Dovrà fare bounce, permettere il passaggio o inviare nella cartella IMAP ‘Spam’.
Deve essere impostato l'auto-apprendimento di SpamAssassin: se sposto un'email nella cartella "Spam", essa si addestra su questo; se sposto un'email dalla cartella "Spam", essa si addestra su questo. I risultati dell'apprendimento di SpamAssassin devono influenzare la collocazione delle email nella cartella "Spam".
Gli script PHP devono essere in grado di inviare email a nome di qualsiasi dominio su questo server.
Deve esserci un servizio OpenVPN con la possibilità di utilizzare IPv6 su un client che non ha IPv6.

In primo luogo, è necessario configurare le interfacce e il routing, inclusi gli IPv6.
Poi sarà necessario configurare OpenVPN, che si connetterà tramite IPv4 e fornirà al client un indirizzo IPv6 statico e reale. Questo client avrà accesso a tutti i servizi IPv6 sul server e a qualsiasi risorsa IPv6 su Internet.
In seguito, sarà necessario configurare Postfix per l'invio di email + SPF + DKIM + rDNS e altre piccole cose simili.
Successivamente, sarà necessario impostare Dovecot e configurare il Multidomain.
In seguito, sarà necessario configurare SpamAssassin e impostare l'apprendimento.
Infine, installare Bind.

============= Multi-interfacce =============

Per configurare le interfacce, è necessario scrivere quanto segue in "/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

Queste impostazioni possono essere applicate su qualsiasi server in tech.ru (con un piccolo accordo con il supporto) e funzioneranno immediatamente come previsto.

Se hai esperienza nella configurazione di cose simili per Hetzner, OVH — qui è diverso. È più complesso.

eno1 è il nome della scheda di rete #1 (lenta, ma senza limiti).
eno2 è il nome della scheda di rete #2 (veloce, ma con tariffa).
tun0 è il nome della scheda di rete virtuale di OpenVPN.
XX.XX.XX.X0 — IPv4 #1 su eno1.
XX.XX.XX.X1 — IPv4 #2 su eno1.
XX.XX.XX.X2 — IPv4 #3 su eno1.
XX.XX.XX.X5 — IPv4 #1 su eno2.
XX.XX.XX.1 — gateway IPv4.
XXXX:XXXX:XXXX:XXXX::/64 — IPv6 per l'intero server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 — IPv6 per eno2, tutto il resto entra in eno1.
XXXX:XXXX:XXXX:XXXX::1 — gateway IPv6 (vale la pena notare che qui si può/dovrebbe fare diversamente. Specificare l'IPv6 dello switch).
dns-nameservers — sono indicati 127.0.0.1 (perché bind è installato localmente) e 213.248.1.6 (questo da tech.ru).

«table eno1t» e «table eno2t» — il senso di queste route-rule è che il traffico entrato tramite eno1 -> dovrebbe uscire tramite lo stesso, mentre il traffico entrato tramite eno2 -> dovrebbe uscire tramite lo stesso. Inoltre, le connessioni iniziate dal server dovrebbero uscire tramite eno1.

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

Con questo comando definiamo che tutto il traffico sconosciuto che rientra in una qualsiasi regola contrassegnata con «table eno1t» deve essere indirizzato all'interfaccia eno1.

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

Con questo comando definiamo che tutto il traffico originato dal server deve essere indirizzato all'interfaccia eno1.

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

Con questo comando definiamo le regole di marking del traffico.

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

Questo blocco definisce un secondo IPv4 per l'interfaccia eno1.

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

Con questo comando definiamo un route dai clienti OpenVPN verso gli IPv4 locali, eccetto XX.XX.XX.X0.
Non capisco ancora perché questo comando sia sufficiente per tutti gli IPv4.

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

Qui definiamo l'indirizzo per l'interfaccia stessa. Il server lo utilizzerà come indirizzo «uscente». Non sarà usato in altro modo.

Perché è così complicato indicare «:1:1::»? Perché OpenVPN deve funzionare correttamente e solo per questo. Maggiori dettagli seguiranno.

Riguardo al gateway — così funziona, e va bene. Ma in modo corretto — qui bisogna indicare l'IPv6 dello switch a cui è collegato il server.

Tuttavia, per qualche motivo l'IPv6 smette di funzionare se faccio così. Forse ci sono delle stranezze da tech.ru.

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

Questo aggiunge un indirizzo IPv6 all'interfaccia. Se servono cento indirizzi — significa cento righe in questo file.

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

Ho segnato gli indirizzi e le sottoreti di tutte le interfacce per chiarezza.
eno1 — deve necessariamente avere «/64» — perché è tutto il nostro pool di indirizzi.
tun0 — la sottorete deve essere necessariamente più grande di eno1. Altrimenti non sarà possibile configurare il gateway IPv6 per i clienti OpenVPN.
eno2 — la sottorete deve essere necessariamente più grande di tun0. Altrimenti i clienti OpenVPN non riusciranno a raggiungere gli indirizzi IPv6 locali.
Per maggiore chiarezza, ho scelto un passo di sottorete di 16, ma se lo si desidera, si può anche fare un passo di «1».
Quindi 64+16 = 80, e 80+16 = 96.

Per ulteriore chiarezza:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — questi sono gli indirizzi che devono essere assegnati a siti o servizi specifici sull'interfaccia eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — questi indirizzi devono essere assegnati a siti specifici o servizi sull'interfaccia eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — questi indirizzi devono essere assegnati ai clienti OpenVPN o utilizzati come indirizzi di servizio OpenVPN.

Per configurare la rete — deve essere possibile riavviare il server.
Le modifiche a IPv4 vengono recepite all'esecuzione (assicurati di usare screen — altrimenti questo comando causerà un'interruzione della rete sul server):

/etc/init.d/networking restart

Aggiungi alla fine del file «/etc/iproute2/rt_tables»:

100 eno1t
101 eno2t

Senza questo non è possibile utilizzare tabelle personalizzate nel file «/etc/network/interfaces».
I numeri devono essere univoci e inferiori a 65535.

Le modifiche a IPv6 possono essere eseguite facilmente senza riavvio, ma per questo è necessario imparare almeno tre comandi:

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

Impostazione di «/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

Queste sono le impostazioni «sysctl» del mio server. Sottolineo l'importanza.

net.ipv4.ip_forward = 1

Senza questo OpenVPN non funzionerà affatto.

net.ipv6.ip_nonlocal_bind = 1

Chiunque provi a eseguire il binding IPv6 (ad esempio, nginx) subito dopo che l'interfaccia è stata configurata — riceverà un errore. Questo indirizzo non è disponibile.

Per evitare questa situazione si effettua tale configurazione.

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

Senza queste impostazioni, il traffico IPv6 dal client OpenVPN non esce nel mondo.

Altre impostazioni o non sono pertinenti o non ricordo a cosa servono.
Ma per ogni evenienza lascio "come è".

Per far sì che le modifiche a questo file vengano applicate senza riavviare il server, è necessario eseguire il comando:

sysctl -p

Maggiore dettaglio riguardo alle regole "table": habr.com/post/108690

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

OpenVPN IPv4 non funziona senza iptables.

Ho iptables impostati in questo modo per la 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 è il mio indirizzo IPv4 statico della macchina locale.
10.8.0.0/24 è la rete IPv4 di OpenVPN. Indirizzi IPv4 per i client di OpenVPN.
L'ordine delle regole è importante.

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

Questa limitazione serve per fare in modo che solo io, dal mio IP statico, possa utilizzare OpenVPN.

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

Per inoltrare pacchetti IPv4 tra i client OpenVPN e Internet, è necessario utilizzare uno di questi comandi.

Per diverse situazioni, una delle opzioni non è adatta.
Per il mio caso, entrambe le opzioni sono valide.
Dopo aver letto la documentazione, ho scelto la prima opzione perché consuma meno CPU.

Per assicurarsi che tutte le impostazioni di iptables vengano caricate dopo il riavvio, è necessario salvarle in un luogo.

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

Questi nomi non sono stati scelti a caso. Sono utilizzati dal pacchetto «iptables-persistent».

apt-get install iptables-persistent

Installazione del pacchetto principale OpenVPN:

apt-get install openvpn easy-rsa

Impostiamo un template per i certificati (sostituire con i propri valori):

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

Modifichiamo le impostazioni del template dei certificati:

mcedit vars

... 
# Questi sono i valori predefiniti per i campi
# che verranno inseriti nel certificato.
# Non lasciare nessuno di questi campi vuoto.
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Own"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"

# Campo del soggetto X509
export KEY_NAME="server"
...

Creiamo un certificato server:

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

Prepariamo la possibilità di creare file finali «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

Prepariamo uno script che unirà tutti i file in un unico file 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

Creiamo il primo cliente OpenVPN:

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

Invia il file «~/client-configs/files/client-name.ovpn» al dispositivo del cliente.

Per i clienti iOS, sarà necessario fare un trucco:
Il contenuto del tag «tls-auth» deve essere senza commenti.
E mettere «key-direction 1» subito prima del tag «tls-auth».

Configuriamo il file di configurazione del server 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

Questo è necessario per assegnare un indirizzo statico a ciascun cliente (non è obbligatorio, ma lo uso):

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

Il dettaglio più complesso e cruciale.

Sfortunatamente, OpenVPN non riesce ancora a configurare automaticamente il gateway IPv6 per i clienti.
È necessario passare manualmente questo per ogni cliente.

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

File «/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

File «/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

Entrambi gli script utilizzano il file «/etc/openvpn/variables»:

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

Non riesco a ricordare perché sia scritto in questo modo.

Adesso sembra strano netmask = 112 (qui dovrebbe essere 96).
E il prefix è strano, non corrisponde alla rete tun0.
Va bene, lo lascio «così com'è».

cipher DES-EDE3-CBC

Questo è una questione di gusto — ho scelto questo metodo di crittografia per la connessione.

Maggiore dettaglio sulla configurazione di OpenVPN IPv4.

Maggiore dettaglio sulla configurazione di OpenVPN IPv6.

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

Installazione del pacchetto principale:

apt-get install postfix

Durante l'installazione selezionare «internet-site».

Il mio «/etc/postfix/main.cf» appare così:

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

# l'aggiunta di .domain è compito del MUA.
append_dot_mydomain = no

readme_directory = no

# Vedi http://www.postfix.org/COMPATIBILITY_README.html -- predefinito a 2 su
# installazioni fresche.
compatibility_level = 2

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

# Tipo di archiviazione
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

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

# Indirizzo IP per dominio
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcre

Esaminiamo i dettagli di questa configurazione.

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

Secondo l'opinione degli utenti di Habr, questo blocco contiene `disinformazione e tesi errate`.Solo dopo 8 anni dall'inizio della mia carriera ho cominciato a capire come funziona l'SSL.

Pertanto, mi permetto di descrivere come utilizzare l'SSL (senza rispondere alle domande «Come funziona?» e «Perché funziona?»).

La base della moderna crittografia è la creazione di una coppia di chiavi (due lunghe stringhe di caratteri).

Una chiave è privata, l'altra è pubblica. La chiave privata deve essere conservata molto attentamente in segreto. La chiave pubblica è distribuita a chiunque ne faccia richiesta.

Con la chiave pubblica è possibile crittografare una stringa di testo in modo che solo il possessore della chiave privata possa decifrarla.
Ecco quindi l'essenza della tecnologia.

Passaggio n. 1 - i siti https.
Quando il browser si collega a un sito, apprende dal server web che il sito è https e quindi richiede la chiave pubblica.
Il server web restituisce la chiave pubblica. Il browser, utilizzando la chiave pubblica, crittografa la richiesta http e la invia.
Il contenuto della richiesta http può essere letto solo da chi possiede una chiave privata, ovvero solo dal server a cui si sta effettuando la richiesta.
La richiesta Http contiene almeno un URI. Pertanto, se in un paese si cerca di limitare l'accesso non all'intero sito, ma a pagine specifiche, questo è impossibile per i siti https.

Passo n. 2 — risposta crittografata.
Il server web fornisce una risposta che può essere facilmente letta lungo il percorso.
La soluzione è estremamente semplice: il browser genera localmente una coppia di chiavi private-pubbliche per ciascun sito https.
Insieme alla richiesta della chiave pubblica del sito, invia la propria chiave pubblica locale.
Il server web la memorizza e, durante l'invio della risposta http, crittografa con questa chiave pubblica il client specifico.
Ora la risposta http può essere decrittografata solo dal possessore della chiave privata del browser del client (cioè dallo stesso client).

Passo n. 3 — stabilire una connessione sicura su un canale pubblico.
Nell'esempio n. 2 c'è una vulnerabilità: non c'è nulla che impedisca ai malintenzionati di intercettare la richiesta http e modificare le informazioni sulla chiave pubblica.
In questo modo, l'intermediario potrà vedere tutto il contenuto dei messaggi inviati e ricevuti finché non cambia il canale di comunicazione.
Combattersi è estremamente semplice: basta inviare la chiave pubblica del browser come messaggio criptato con la chiave pubblica del server web.
Il server web prima di tutto invia una risposta del tipo "la tua chiave pubblica è questa" e cripta questo messaggio con la stessa chiave pubblica.
Il browser controlla la risposta: se riceve il messaggio "la tua chiave pubblica è questa", allora è una garanzia al 100% che questo canale di comunicazione è sicuro.
Quanto è sicuro?
La creazione di un tale canale di comunicazione sicuro avviene a una velocità pari a ping*2. Ad esempio, 20 ms.
Un malintenzionato deve già avere la chiave privata di una delle parti o riuscire a indovinare la chiave privata in pochi millisecondi.
Crackare una chiave privata moderna richiederà decenni su un supercomputer.

Passo n. 4 — un database pubblico di chiavi pubbliche.
È evidente che in tutta questa storia esiste la possibilità per un malintenzionato di sedere sul canale di comunicazione tra il cliente e il server.
La possibilità per il cliente di essere rappresentato dal server e il server dal cliente. E di simulare una coppia di chiavi in entrambe le direzioni.
In questo modo, un malintenzionato vedrà tutto il traffico e avrà l'opportunità di "modificare" il traffico.
Ad esempio, cambiando l'indirizzo dove inviare i soldi, copiando la password dell'online banking o bloccando contenuti "scomodi".
Per combattere tali malintenzionati, è stata creata una base di dati pubblica con chiavi pubbliche per ogni sito https.
Ogni browser "sa" dell'esistenza di circa 200 di queste basi di dati. Questo è preimpostato in ogni browser.
"La conoscenza" è supportata dalla chiave pubblica di ogni certificato. Cioè, è impossibile falsificare la connessione con ogni specifico centro di certificazione.

Ora c'è una comprensione semplice di come utilizzare SSL per https.
Se si riflette attentamente, diventa chiaro come i servizi segreti possano violare questa struttura. Ma ciò comporterebbe enormi sforzi da parte loro.
E per le organizzazioni, è praticamente impossibile violare l'attuale livello di protezione anche per i vip.

Aggiungerò qualcosa riguardo alle connessioni ssh. Non ci sono chiavi pubbliche, quindi come procedere? La questione può essere risolta in due modi.
Opzione ssh con password:
Alla prima connessione, il client ssh deve avvisare che qui abbiamo una nuova chiave pubblica del server ssh.
In ulteriori connessioni, se appare il messaggio di avviso «nuova chiave pubblica del server ssh» — significherà che qualcuno sta cercando di intercettarvi.
Oppure, nella prima connessione, qualcuno vi stava intercettando, e ora comunicate con il server senza intermediari.
Infatti, poiché il fatto di essere intercettati può essere facilmente e rapidamente scoperto, questa tecnica viene utilizzata solo in occasioni particolari per clienti specifici.

Opzione ssh con chiave:
Prendete una chiavetta USB, scrivete su di essa la chiave privata per il server ssh (per questo ci sono termini e un sacco di dettagli importanti, ma scrivo per informare, non come istruzione pratica).
Lasciate la chiave pubblica sulla macchina dove sarà il client ssh e mantenetela segreta.
Portate la chiavetta al server, collegate, copiate la chiave privata, poi bruciate la chiavetta e disperdete le ceneri al vento (o almeno formattatela riempiendola di zeri).
Ecco fatto — dopo un'operazione del genere, sarà impossibile violare una connessione SSH. Naturalmente, tra dieci anni, su un supercomputer si potrebbe comunque analizzare il traffico, ma questa è un'altra storia.

Mi scuso per l'argomento che esula dal tema.

Dunque, ora che abbiamo compreso la teoria, parlerò del flusso di creazione del certificato SSL.

Con «openssl genrsa» creiamo una chiave privata e «modelli» per la chiave pubblica.
Inviamo i «modelli» a un'azienda esterna, a cui paghiamo circa 9$ per il certificato più semplice.

Dopo alcune ore riceviamo da questa azienda esterna la nostra chiave «pubblica» e anche un set di altre chiavi pubbliche.

Perché pagare un'azienda esterna per la creazione della mia chiave pubblica è una domanda diversa, non la considereremo qui.

Ora è chiaro il senso della scritta:

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

Nella cartella «/etc/ssl» sono accumulati tutti i file per questioni SSL.
domain1.com — il nome del dominio.
2018 — l'anno di creazione delle chiavi.
«key» — indica che il file è una chiave privata.

E il significato di questo file:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com — il nome del dominio.
2018 — l'anno di creazione delle chiavi.
chained — indicazione che qui c'è una catena di chiavi pubbliche (la prima è la nostra chiave pubblica e le altre sono quelle fornite dalla compagnia che ha emesso la chiave pubblica).
crt — indicazione che qui c'è un certificato pronto (chiave pubblica con spiegazioni tecniche).

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

Questa impostazione in questo caso non viene utilizzata, ma è scritta come esempio.

Perché un errore in questo parametro può portare all'invio di spam dal vostro server (senza il vostro consenso).

Poi dovrete dimostrare a tutti che non siete colpevoli.

recipient_delimiter = +

Forse molti non sanno, ecco, questo è il simbolo standard per il ranking delle email, ed è supportato dalla maggior parte dei moderni server di posta.

Ad esempio, se avete una casella di posta "username@gmail.com", provate a inviare a "username+spam@gmail.com" — vedete che ne esce.

inet_protocols = ipv4

Forse questo vi confonderà.

Ma non è così per caso. Ogni nuovo dominio, di default, è solo IPv4, poi attivo IPv6 per ognuno individualmente.

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

Qui impostiamo che tutta la posta in arrivo va in dovecot.
Le regole per dominio, casella di posta, alias – vedere nel database.

/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

Ora postfix sa che può accettare email per ulteriore invio solo dopo l'autenticazione con dovecot.

Non mi è davvero chiaro perché duplicarlo qui. Abbiamo già specificato in «virtual_transport» tutto ciò che serve.

Ma postfix è un sistema molto vecchio – probabilmente è un workaround dai tempi passati.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Questa configurazione è diversa per ogni server di posta.

Ho a disposizione 3 server di posta e queste impostazioni variano notevolmente a causa delle diverse esigenze d'uso.

Le configurazioni devono essere eseguite con attenzione – altrimenti lo spam inonderà il tuo server o, peggio, lo spam partirà da te.

# SPF
policyd-spf_time_limit = 3600

Impostazione per un plugin legato alla verifica SPF delle email in arrivo.

# 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

Impostazione che tutte le email in uscita devono essere firmate con DKIM.

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

Questa è una componente fondamentale per la gestione della consegna delle email quando vengono inviate tramite script PHP.

Il file «/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:

A sinistra ci sono le espressioni regolari. A destra c'è l'etichetta che contrassegna l'email.
Postfix, in base all'etichetta, considererà ulteriori righe di configurazione per l'email specifica.

Come verrà riconfigurato Postfix per un'email specifica sarà indicato in «master.cf».

Le righe 4, 5, 6 sono le più importanti. L'etichetta è impostata in base al dominio dal quale si invia l'email.
Ma non sempre nei vecchi script PHP viene specificato il campo «from». In tal caso, si utilizza il nome utente.

L'articolo è già ampio — non vorrei distrarmi con la configurazione di nginx+fpm.

In sintesi, per ogni sito impostiamo un proprietario linux-user specifico. E di conseguenza, il proprio fpm-pool.

Fpm-pool può utilizzare qualsiasi versione di PHP (è fantastico poter utilizzare senza problemi versioni diverse di PHP e persino diversi php.ini su uno stesso server per siti vicini).

Così, per il linux-user specifico «www-domain2» c'è il sito domain2.com. In questo sito c'è codice per l'invio di email senza specificare il campo from.

Anche in questo caso, le email verranno inviate correttamente e non finiranno mai nello spam.

Il mio «/etc/postfix/master.cf» appare così:

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

Il file non è completo — è già molto grande.
Ho evidenziato solo ciò che è stato modificato.

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}

Queste sono le impostazioni legate a spamassassin, parlerò di lui più tardi.

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

Permetti la connessione al server di posta attraverso la porta 587.
È obbligatorio autenticarsi.

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

Attiviamo il controllo SPF.

apt-get install postfix-policyd-spf-python

Installeremo il pacchetto per i controlli SPF sopra.

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

E questa è la parte più interessante. È la possibilità di inviare email per un dominio specifico da un indirizzo IPv4/IPv6 specifico.

Questo viene fatto per il rDNS. Il rDNS è l'ottenimento di una certa stringa tramite l'indirizzo IP.
E per l'email questa possibilità viene utilizzata per confermare che l'helo corrisponde esattamente al rDNS dell'indirizzo da cui è stata inviata l'email.

Se l'helo non corrisponde al dominio dell'email, a nome del quale è stata inviata la lettera — si accumulano punti di spam.

Helo non corrisponde al rDNS — si accumulano molti punti di spam.
Pertanto, ogni dominio deve avere il proprio indirizzo IP.
Per OVH — nel pannello c'è la possibilità di specificare il rDNS.
Per tech.ru, il problema viene risolto tramite il supporto.
Per AWS, il problema viene risolto tramite il supporto.
«inet_protocols» e «smtp_bind_address6» attivano il supporto per IPv6.
È necessario configurare rDNS anche per IPv6.
«syslog_name» serve per facilitare la lettura dei log.

Acquistare certificati consiglio qui.

Configurazione della combinazione postfix+dovecot qui.

Configurazione SPF.

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

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

Configurazione di mysql, installiamo i pacchetti noi stessi.

File «/etc/dovecot/conf.d/10-auth.conf»

disable_plaintext_auth = yes
auth_mechanisms = plain login

Autenticazione solo in forma crittografata.

File «/etc/dovecot/conf.d/10-mail.conf»

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

Qui indicheremo il luogo di archiviazione delle mail.

Voglio che siano memorizzate in file e raggruppate per domini.

File «/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 {
  }
}

Questo è il file di configurazione principale di dovecot.
Qui disabilitiamo le connessioni non protette.
E abilitiamo le connessioni protette.

File «/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
}

Configuriamo ssl. Indichiamo che ssl è obbligatorio.
E il certificato stesso. E un dettaglio importante: la direttiva «local». Indica quale certificato ssl utilizzare per la connessione a quale IPv4 locale.

A proposito, IPv6 non è configurato qui, sistemerò questa mancanza più tardi.
XX.XX.XX.X5 (domain2) — certificato assente. Per collegare i clienti è necessario indicare domain1.com.
XX.XX.XX.X2 (domain3) — certificato presente, per collegare i clienti si possono indicare domain1.com o domain3.com.

File «/etc/dovecot/conf.d/15-lda.conf»

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Questo sarà necessario per spamassassin in seguito.

File «/etc/dovecot/conf.d/20-imap.conf»

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Questo è il plugin antispam. Necessario per l'addestramento dello spamassassin al momento del trasferimento nella/dalla cartella «Spam».

File «/etc/dovecot/conf.d/20-pop3.conf»

protocol pop3 {
}

Esiste semplicemente un file di questo tipo.

File «/etc/dovecot/conf.d/20-lmtp.conf»

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

Configurazione lmtp.

File «/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
}

Impostazioni di apprendimento di spamassassin al momento del trasferimento nella/dalla cartella «Spam».

File «/etc/dovecot/conf.d/90-sieve.conf»

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

File in cui è specificato cosa fare con le email in arrivo.

File «/var/lib/dovecot/sieve/default.sieve»

require ["fileinto", "mailbox"];

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

È necessario compilare il file: «sievec default.sieve».

File «/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
}

Indicazione dei file sql per l'autenticazione.
E il file stesso — come metodo di autenticazione.

File «/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';

Questo corrisponde alle impostazioni analoghe per postfix.

File «/etc/dovecot/dovecot.conf»

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

File di configurazione principale.
È importante ciò che qui specifichiamo / aggiungiamo i protocolli.

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

apt-get install spamassassin spamc

Installeremo i pacchetti.

adduser spamd --disabled-login

Aggiungiamo un utente da cui operare.

systemctl enable spamassassin.service

Attiviamo l'avvio automatico del servizio spamassassin all'avvio.

File «/etc/default/spamassassin»:

CRON=1

Attiva l'aggiornamento automatico delle regole «di default».

File «/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

Deve essere creata nel DB mysql «sa» con l'utente «sa» e la password «password» (sostituire con qualcosa di adeguato).

report_safe — invece di una lettera verrà inviato un rapporto sulla lettera spam.
use_bayes — queste sono le impostazioni di apprendimento automatico di spamassassin.

Le altre impostazioni di spamassassin sono state applicate in precedenza nell'articolo.

Impostazione generale di «spamassassin».
Riguardo al trasferimento di nuove email di spam nella cartella IMAP «Spam».
Riguardo alla semplice combinazione Dovecot + SpamAssassin.
Raccomando di leggere la teoria dell'apprendimento di spamassassin durante il movimento delle email nelle cartelle IMAP (e non consiglio di applicarla).

============= Appello alla comunità =============

Vorrei anche proporre un'idea alla comunità su come aumentare il livello di sicurezza delle email trasmesse. Dal momento che mi sono immerso così a fondo nel tema della posta.

In modo che l'utente possa creare un paio di chiavi nel proprio client (outlook, thunderbird, browser-plugin, …). Pubblica e privata. La pubblica — da inviare nel DNS. La privata — da conservare nel client. I server di posta dovrebbero applicare la chiave pubblica per inviare a un destinatario specifico.

E per proteggere da spam con tali email (sì, il server di posta non potrà vedere il contenuto) — sarà necessario introdurre 3 regole:

  1. Firma DKIM reale obbligatoria, SPF obbligatorio, rDNS obbligatorio.
  2. Rete neurale per l'apprendimento anti-spam + database associato sul lato client.
  3. L'algoritmo di crittografia deve essere tale che la parte mittente deve spendere 100 volte più potenza CPU per la crittografia rispetto alla parte ricevente.

Oltre alle email pubbliche, sviluppare uno standard per l'email di proposta "iniziare una corrispondenza protetta". Un utente (casella di posta) invia a un'altra casella di posta un'email con allegato. Nell'email c'è un testo che propone di iniziare un canale di comunicazione protetto per la corrispondenza insieme alla chiave pubblica del proprietario della casella di posta (con la chiave privata sul lato client).

È possibile persino creare una coppia di chiavi specifiche per ogni conversazione. L'utente destinatario può accettare questa proposta e inviare la propria chiave pubblica (anch'essa creata specificamente per questa conversazione). Successivamente, il primo utente invia una e-mail di controllo (crittografata con la chiave pubblica del secondo utente) — una volta ricevuta, il secondo utente può considerare il canale di comunicazione stabilito affidabile. Poi, il secondo utente invia una e-mail di controllo — a quel punto, anche il primo utente può considerare il canale stabilito protetto.

Per combattere l'intercettazione delle chiavi durante il trasferimento — il protocollo deve prevedere la possibilità di inviare almeno una chiave pubblica tramite chiavetta USB.

E la cosa più importante — affinché tutto ciò funzioni (la domanda è «chi pagherà per questo?»):
Introdurre certificati di posta elettronica a partire da 10$ per 3 anni. Questi consentiranno al mittente di specificare nel DNS che «le mie chiavi pubbliche si trovano lì». E daranno la possibilità di avviare una connessione protetta. Inoltre, accettare tali connessioni sarà gratuito.
Gmail finalmente monetizzerà i propri utenti. Per 10$ in 3 anni — diritto di creare canali di comunicazione sicuri.

============= Conclusione =============

Per testare l'intero articolo, avevo intenzione di affittare un server dedicato per un mese e acquistare un dominio con certificato SSL.

Ma le circostanze della vita hanno fatto sì che questa questione si prolungasse per 2 mesi.
E quando ho avuto di nuovo tempo libero, ho deciso di pubblicare l'articolo così com'è e non rischiare che la pubblicazione si prolungasse ulteriormente di un anno.

Se ci saranno abbastanza domande tipo «qui non è descritto in modo sufficientemente dettagliato» — allora penso che troverò la forza di prendere un server dedicato con un nuovo dominio e un nuovo certificato SSL e descrivere in modo ancora più dettagliato, scoprendo soprattutto tutti i dettagli importanti trascurati.

Mi piacerebbe anche ricevere feedback sull'idea dei certificati di posta. Se l'idea piace, cercherò di trovare la forza per scrivere una bozza per l'rfc.

Quando copiate grandi parti dell'articolo, dovete indicare un link a questo articolo.
Quando traducete in qualsiasi altra lingua, dovete indicare un link a questo articolo.
Cercherò di tradurre in inglese personalmente e lascerò collegamenti incrociati.


Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster