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

Questo articolo spiega come configurare un server di posta moderno.
Postfisso + Colombaia. SPF + DKIM + rDNS. Con IPv6.
Con crittografia TSL. Con supporto per più domini, in parte con un vero certificato SSL.
Con protezione antispam e un elevato livello di antispam da altri server di posta.
Supporta più interfacce fisiche.
Con OpenVPN, la cui connessione avviene tramite IPv4 e che fornisce IPv6.

Se non vuoi apprendere tutte queste tecnologie, ma desideri configurare un server di questo tipo, questo articolo fa per te.

L'articolo non tenta di spiegare ogni dettaglio. La spiegazione va a ciò che non si configura come standard o è importante dal punto di vista del consumatore.

La motivazione per creare un server di posta è stato un mio sogno da molto tempo. Può sembrare stupido, ma IMHO è molto meglio che sognare una nuova auto della tua marca preferita.

Ci sono due motivazioni per impostare IPv6. Uno specialista IT deve apprendere costantemente nuove tecnologie per sopravvivere. Vorrei dare il mio modesto contributo alla lotta contro la censura.

La motivazione per impostare OpenVPN è semplicemente far funzionare IPv6 sul computer locale.
La motivazione per impostare più interfacce fisiche è che sul mio server ho un'interfaccia “lenta ma illimitata” e un'altra “veloce ma a tariffa”.

La motivazione per impostare le impostazioni di associazione è che il mio ISP fornisce un server DNS instabile e anche Google a volte fallisce. Voglio un server DNS stabile per uso personale.

Motivazione per scrivere un articolo: ho scritto una bozza 10 mesi fa e l'ho già rivista due volte. Anche se l'autore ne ha bisogno regolarmente, c'è un'alta probabilità che anche altri ne abbiano bisogno.

Non esiste una soluzione universale per un server di posta. Ma proverò a scrivere qualcosa del tipo “fai questo e poi, quando tutto funziona come dovrebbe, butta via le cose in più”.

La società tech.ru ha un server di colocation. È possibile effettuare il confronto con OVH, Hetzner, AWS. Per risolvere questo problema, la collaborazione con tech.ru sarà molto più efficace.

Debian 9 è installato sul server.

Il server ha 2 interfacce "eno1" e "eno2". Il primo è rispettivamente illimitato e il secondo è veloce.

Sono presenti 3 indirizzi IP statici, XX.XX.XX.X0 e XX.XX.XX.X1 e XX.XX.XX.X2 sull'interfaccia "eno1" e XX.XX.XX.X5 sull'interfaccia "eno2" .

Disponibile XXXX:XXXX:XXXX:XXXX::/64 un pool di indirizzi IPv6 assegnati all'interfaccia "eno1" e da esso XXXX:XXXX:XXXX:XXXX:1:2::/96 è stato assegnato a "eno2" su mia richiesta.

Ci sono 3 domini `domain1.com`, `domain2.com`, `domain3.com`. Esiste un certificato SSL per "dominio1.com" e "dominio3.com".

Ho un account Google a cui vorrei collegare la mia casella di posta[email protected]` (ricezione e invio di posta direttamente dall'interfaccia Gmail).
Ci deve essere una casella di posta`[email protected]`, una copia della posta che voglio vedere nella mia Gmail. Ed è raro poter inviare qualcosa per conto di `[email protected]` tramite l'interfaccia web.

Ci deve essere una casella di posta`[email protected]", che Ivanov utilizzerà dal suo iPhone.

Le e-mail inviate devono essere conformi a tutti i moderni requisiti antispam.
Nelle reti pubbliche deve essere disponibile il livello di crittografia più elevato.
Dovrebbe esserci il supporto IPv6 sia per l'invio che per la ricezione delle lettere.
Dovrebbe esserci uno SpamAssassin che non eliminerà mai le email. E rimbalzerà, salterà o invierà alla cartella "Spam" IMAP.
È necessario configurare l'autoapprendimento di SpamAssassin: se sposto una lettera nella cartella Spam, imparerà da questa; se sposto una lettera dalla cartella Spam, imparerà da questa. I risultati della formazione su SpamAssassin dovrebbero influenzare se la lettera finisce nella cartella Spam.
Gli script PHP devono essere in grado di inviare posta per conto di qualsiasi dominio su un determinato server.
Dovrebbe esserci un servizio openvpn, con la possibilità di utilizzare IPv6 su un client che non dispone di IPv6.

Per prima cosa devi configurare le interfacce e il routing, incluso IPv6.
Quindi dovrai configurare OpenVPN, che si connetterà tramite IPv4 e fornirà al client un indirizzo IPv6 statico-reale. Questo client avrà accesso a tutti i servizi IPv6 sul server e a qualsiasi risorsa IPv6 su Internet.
Quindi dovrai configurare Postfix per inviare lettere + SPF + DKIM + rDNS e altre piccole cose simili.
Successivamente dovrai configurare Dovecot e configurare Multidominio.
Quindi dovrai configurare SpamAssassin e configurare la formazione.
Infine, installa Bind.

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

Per configurare le interfacce è necessario scriverlo 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 po' di coordinamento con il supporto) e funzionerà immediatamente come dovrebbe.

Se hai esperienza nella creazione di cose simili per Hetzner, OVH, lì è diverso. Più difficile.

eno1 è il nome della scheda di rete n. 1 (lenta ma illimitata).
eno2 è il nome della scheda di rete n. 2 (veloce, ma a 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 dall'esterno va in eno1.
XXXX:XXXX:XXXX:XXXX::1 — Gateway IPv6 (vale la pena notare che questo può/dovrebbe essere fatto diversamente. Specificare lo switch IPv6).
dns-nameservers - è indicato 127.0.0.1 (perché bind è installato localmente) e 213.248.1.6 (proviene da tech.ru).

"tabella eno1t" e "tabella eno2t" - il significato di queste regole di percorso è che il traffico che entra da eno1 -> uscirà da esso, e il traffico che entra da eno2 -> uscirà da esso. E anche le connessioni avviate dal server passerebbero attraverso eno1.

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

Con questo comando specifichiamo che tutto il traffico incomprensibile che rientra in una qualsiasi regola contrassegnata “tabella eno1t” -> venga inviato all'interfaccia eno1.

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

Con questo comando specifichiamo che l'eventuale traffico avviato dal server dovrà 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 impostiamo le regole per la marcatura 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 specifica 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 impostiamo il percorso dai client OpenVPN all'IPv4 locale tranne XX.XX.XX.X0.
Ancora non capisco 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 è dove impostiamo l'indirizzo per l'interfaccia stessa. Il server lo utilizzerà come indirizzo “in uscita”. Non verrà più utilizzato in alcun modo.

Perché ":1:1::" è così complicato? In modo che OpenVPN funzioni correttamente e solo per questo. Ne parleremo più avanti.

Per quanto riguarda il gateway, funziona così e va bene. Ma il modo corretto è indicare qui l'IPv6 dello switch a cui è connesso il server.

Tuttavia, per qualche motivo IPv6 smette di funzionare se lo faccio. Questo è probabilmente una sorta di problema di 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 hai bisogno di cento indirizzi, significa che ci saranno 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 annotato gli indirizzi e le sottoreti di tutte le interfacce per renderlo chiaro.
eno1 - deve essere "/64" - perché questo è il nostro intero pool di indirizzi.
tun0: la sottorete deve essere più grande di eno1. Altrimenti non sarà possibile configurare un gateway IPv6 per i client OpenVPN.
eno2: la sottorete deve essere più grande di tun0. In caso contrario, i client OpenVPN non saranno in grado di accedere agli indirizzi IPv6 locali.
Per chiarezza, ho scelto un passaggio di sottorete pari a 16, ma se lo desideri, puoi anche eseguire il passaggio “1”.
Di conseguenza, 64+16 = 80 e 80+16 = 96.

Per una chiarezza ancora maggiore:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY sono indirizzi che devono essere assegnati a siti o servizi specifici sull'interfaccia eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY sono indirizzi che devono essere assegnati a siti o servizi specifici sull'interfaccia eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY sono indirizzi che devono essere assegnati ai client OpenVPN o utilizzati come indirizzi del servizio OpenVPN.

Per configurare la rete, dovrebbe essere possibile riavviare il server.
Le modifiche IPv4 vengono rilevate quando eseguite (assicuratevi di racchiuderle nello schermo, altrimenti questo comando manderà semplicemente in crash la rete sul server):

/etc/init.d/networking restart

Aggiungere alla fine del file “/etc/iproute2/rt_tables”:

100 eno1t
101 eno2t

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

Le modifiche IPv6 possono essere modificate facilmente senza riavviare, ma per fare ciò è 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. Vorrei sottolineare una cosa importante.

net.ipv4.ip_forward = 1

Senza questo, OpenVPN non funzionerà affatto.

net.ipv6.ip_nonlocal_bind = 1

Chiunque tenti di associare IPv6 (ad esempio nginx) immediatamente dopo l'attivazione dell'interfaccia riceverà un errore. Che questo indirizzo non è disponibile.

Per evitare una situazione del genere, viene creata tale impostazione.

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

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

Altre impostazioni non sono rilevanti o non ricordo a cosa servono.
Ma per ogni evenienza, lo lascio “così com’è”.

Affinché le modifiche a questo file vengano rilevate senza riavviare il server, è necessario eseguire il comando:

sysctl -p

Maggiori dettagli sulle regole della “tabella”: habr.com/post/108690

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

OpenVPN IPv4 non funziona senza iptables.

I miei iptables sono così per 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 del computer locale.
10.8.0.0/24 - Rete IPv4 openvpn. Indirizzi IPv4 per client openvpn.
La coerenza 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 è una limitazione in modo che solo io possa utilizzare OpenVPN dal mio IP statico.

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

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

Per diversi casi, una delle opzioni non è adatta.
Entrambi i comandi sono adatti al mio caso.
Dopo aver letto la documentazione, ho scelto la prima opzione perché utilizza meno CPU.

Affinché tutte le impostazioni di iptables vengano recuperate dopo il riavvio, è necessario salvarle da qualche parte.

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

Tali nomi non sono stati scelti a caso. Sono utilizzati dal pacchetto "iptables-persistent".

apt-get install iptables-persistent

Installazione del pacchetto OpenVPN principale:

apt-get install openvpn easy-rsa

Impostiamo un modello per i certificati (sostituisci i tuoi valori):

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

Modifichiamo le impostazioni del modello di certificato:

mcedit vars

...
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Own"
export KEY_EMAIL="[email protected]"
export KEY_OU="VPN"

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

Crea 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 i file finali “nome-cliente.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}/.crt 
    <(echo -e '</cert>n<key>') 
    ${KEY_DIR}/.key 
    <(echo -e '</key>n<tls-auth>') 
    ${KEY_DIR}/ta.key 
    <(echo -e '</tls-auth>') 
    > ${OUTPUT_DIR}/.ovpn

Creazione del primo client OpenVPN:

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

Il file "~/client-configs/files/client-name.ovpn" viene inviato al dispositivo del client.

Per i client iOS dovrai eseguire il seguente trucco:
Il contenuto del tag "tls-auth" deve essere senza commenti.
E metti anche "key-direction 1" immediatamente prima del tag "tls-auth".

Configuriamo la 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 impostare un indirizzo statico per ciascun client (non necessario, ma lo uso):

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

Il dettaglio più difficile e fondamentale.

Sfortunatamente OpenVPN non sa ancora come configurare autonomamente un gateway IPv6 per i client.
Devi inoltrarlo "manualmente" per ciascun 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

Trovo difficile ricordare perché è scritto così.

Ora netmask = 112 sembra strano (dovrebbe essere 96 proprio lì).
E il prefisso è strano, non corrisponde alla rete tun0.
Ma va bene, lo lascerò così com'è.

cipher DES-EDE3-CBC

Questo non è per tutti: ho scelto questo metodo per crittografare la connessione.

Ulteriori informazioni sulla configurazione di OpenVPN IPv4.

Ulteriori informazioni sulla configurazione di OpenVPN IPv6.

============= Postfisso =============

Installazione del pacchetto principale:

apt-get install postfix

Durante l'installazione selezionare “sito internet”.

Il mio "/etc/postfix/main.cf" assomiglia a questo:

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

# appending .domain is the MUA's job.
append_dot_mydomain = no

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2

# TLS parameters
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

# Storage type
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

# SMTP-Auth settings
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
        permit_sasl_authenticated,
        permit_mynetworks,
        #reject_invalid_hostname,
        #reject_unknown_recipient_domain,
        reject_unauth_destination,
        reject_rbl_client sbl.spamhaus.org,
        check_policy_service unix:private/policyd-spf

smtpd_helo_restrictions =
        #reject_invalid_helo_hostname,
        #reject_non_fqdn_helo_hostname,
        reject_unknown_helo_hostname

smtpd_client_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_non_fqdn_helo_hostname,
        permit

# SPF
policyd-spf_time_limit = 3600

# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sock

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

Diamo un'occhiata ai 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 gli abitanti di Khabrovsk, questo blocco contiene “disinformazione e tesi errate”.Solo 8 anni dopo l'inizio della mia carriera ho iniziato a capire come funziona SSL.

Pertanto mi prenderò la libertà di descrivere come utilizzare SSL (senza rispondere alle domande “Come funziona?” e “Perché funziona?”).

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

Una “chiave” è privata, l’altra chiave è “pubblica”. Manteniamo la chiave privata molto attentamente segreta. Distribuiamo la chiave pubblica a tutti.

Utilizzando una chiave pubblica, puoi crittografare una stringa di testo in modo che solo il proprietario della chiave privata possa decrittografarla.
Bene, questa è l'intera base della tecnologia.

Passaggio n. 1: siti https.
Quando si accede ad un sito, il browser apprende dal server web che il sito è https e quindi richiede una chiave pubblica.
Il server web fornisce la chiave pubblica. Il browser utilizza la chiave pubblica per crittografare la richiesta http e inviarla.
Il contenuto di una richiesta http può essere letto solo da chi possiede la chiave privata, cioè solo dal server a cui viene effettuata la richiesta.
La richiesta HTTP contiene almeno un URI. Pertanto, se un paese tenta di limitare l'accesso non all'intero sito, ma a una pagina specifica, ciò è impossibile per i siti https.

Passaggio n. 2: risposta crittografata.
Il server web fornisce una risposta che può essere facilmente letta mentre si è in viaggio.
La soluzione è estremamente semplice: il browser genera localmente la stessa coppia di chiavi pubblica-privata per ciascun sito https.
E insieme alla richiesta della chiave pubblica del sito, invia la sua chiave pubblica locale.
Il server web lo ricorda e, quando invia la risposta http, lo crittografa con la chiave pubblica di un client specifico.
Ora la risposta http può essere decrittografata solo dal proprietario della chiave privata del browser del client (ovvero, dal client stesso).

Passaggio n. 3: stabilire una connessione sicura tramite un canale pubblico.
Nell'esempio n. 2 esiste una vulnerabilità: nulla impedisce ai sostenitori di intercettare una richiesta http e modificare le informazioni sulla chiave pubblica.
In questo modo l'intermediario vedrà chiaramente tutto il contenuto dei messaggi inviati e ricevuti finché non cambia il canale di comunicazione.
Gestirlo è estremamente semplice: basta inviare la chiave pubblica del browser come messaggio crittografato con la chiave pubblica del server web.
Il server web invia quindi prima una risposta del tipo "la tua chiave pubblica è così" e crittografa questo messaggio con la stessa chiave pubblica.
Il browser esamina la risposta - se viene ricevuto il messaggio "la tua chiave pubblica è così" - allora questa è una garanzia al 100% che questo canale di comunicazione sia sicuro.
Quanto è sicuro?
La creazione stessa di un canale di comunicazione così sicuro avviene alla velocità di ping*2. Ad esempio 20 ms.
L'aggressore deve disporre in anticipo della chiave privata di una delle parti. Oppure trova una chiave privata in un paio di millisecondi.
Per hackerare una chiave privata moderna ci vorranno decenni su un supercomputer.

Passaggio n. 4: database pubblico di chiavi pubbliche.
Ovviamente, in tutta questa storia c'è la possibilità che un utente malintenzionato si sieda sul canale di comunicazione tra il client e il server.
Il client può fingere di essere il server e il server può fingere di essere il client. Ed emula una coppia di chiavi in ​​entrambe le direzioni.
Quindi l’aggressore vedrà tutto il traffico e sarà in grado di “modificarlo”.
Ad esempio, modificare l'indirizzo a cui inviare denaro o copiare la password dall'online banking o bloccare contenuti “discutibili”.
Per combattere questi aggressori, hanno creato un database pubblico con chiavi pubbliche per ciascun sito https.
Ogni browser "sa" dell'esistenza di circa 200 database di questo tipo. Questo è preinstallato in ogni browser.
La “Conoscenza” è supportata da una chiave pubblica di ciascun certificato. Cioè, la connessione a ciascuna specifica autorità di certificazione non può essere falsificata.

Ora è possibile comprendere in modo semplice come utilizzare SSL per https.
Se usi il cervello, diventerà chiaro come i servizi speciali possano hackerare qualcosa in questa struttura. Ma costerà loro sforzi mostruosi.
E per le organizzazioni più piccole della NSA o della CIA è quasi impossibile violare il livello di protezione esistente, anche per i VIP.

Aggiungerò anche le connessioni ssh. Non ci sono chiavi pubbliche lì, quindi cosa puoi fare? La questione viene risolta in due modi.
Opzione ssh-by-password:
Durante la prima connessione, il client ssh dovrebbe avvisare che abbiamo una nuova chiave pubblica dal server ssh.
E se durante le connessioni successive appare l'avviso “nuova chiave pubblica dal server ssh”, vorrà dire che stanno cercando di origliarvi.
Oppure sei stato intercettato alla tua prima connessione, ma ora comunichi con il server senza intermediari.
In realtà, poiché il fatto delle intercettazioni telefoniche viene rivelato facilmente, rapidamente e senza sforzo, questo attacco viene utilizzato solo in casi speciali per un cliente specifico.

Opzione ssh-by-key:
Prendiamo un'unità flash, scriviamo su di essa la chiave privata per il server ssh (ci sono termini e molte sfumature importanti per questo, ma sto scrivendo un programma educativo, non istruzioni per l'uso).
Lasciamo la chiave pubblica sulla macchina su cui si troverà il client ssh e la manteniamo segreta.
Portiamo la chiavetta sul server, la inseriamo, copiamo la chiave privata, bruciamo la chiavetta e disperdiamo le ceneri al vento (o almeno formattiamola con zeri).
Questo è tutto: dopo un'operazione del genere sarà impossibile hackerare una simile connessione ssh. Naturalmente, tra 10 anni sarà possibile visualizzare il traffico su un supercomputer, ma questa è una storia diversa.

Mi scuso per l'offtopico.

Quindi ora che la teoria è nota. Ti parlerò del flusso di creazione di un certificato SSL.

Usando "openssl genrsa" creiamo una chiave privata e "spazi vuoti" per la chiave pubblica.
Inviamo gli "spazi vuoti" a una società terza, alla quale paghiamo circa $ 9 per il certificato più semplice.

Dopo un paio d'ore riceviamo la nostra chiave “pubblica” e un insieme di diverse chiavi pubbliche da questa società terza.

Perché una società terza dovrebbe pagare per la registrazione della mia chiave pubblica è una questione a parte, non la considereremo qui.

Ora è chiaro qual è il significato dell’iscrizione:

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

La cartella "/etc/ssl" contiene tutti i file per i problemi SSL.
dominio1.com: nome di dominio.
Il 2018 è l’anno della creazione della chiave.
“chiave” - designazione del file come chiave privata.

E il significato di questo file:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
dominio1.com: nome di dominio.
Il 2018 è l’anno della creazione della chiave.
concatenato - designazione che esiste una catena di chiavi pubbliche (la prima è la nostra chiave pubblica e il resto è quello che proviene dalla società che ha emesso la chiave pubblica).
crt - designazione che esiste un certificato già 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 non viene utilizzata in questo caso, ma viene scritta come esempio.

Perché un errore in questo parametro porterà all'invio di spam dal tuo server (senza la tua volontà).

Allora dimostra a tutti che non sei colpevole.

recipient_delimiter = +

Molte persone potrebbero non saperlo, ma questo è un carattere standard per classificare le email ed è supportato dalla maggior parte dei server di posta moderni.

Ad esempio, se hai una casella di posta "[email protected]"prova a inviare a"[email protected]"-guarda cosa ne viene fuori.

inet_protocols = ipv4

Questo potrebbe creare confusione.

Ma non è solo così. Ogni nuovo dominio è per impostazione predefinita solo IPv4, quindi attivo IPv6 per ciascuno separatamente.

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 specifichiamo che tutta la posta in arrivo va a Dovecot.
E le regole per dominio, casella di posta, alias: guarda 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 la posta può essere accettata per ulteriori invii solo dopo l'autorizzazione di dovecot.

Davvero non capisco perché questo sia duplicato qui. Abbiamo già specificato tutto ciò che serve in “virtual_transport”.

Ma il sistema postfix è molto vecchio, probabilmente è un ritorno ai vecchi tempi.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Questo può essere configurato in modo diverso per ciascun server di posta.

Ho 3 server di posta a mia disposizione e queste impostazioni sono molto diverse a causa dei diversi requisiti di utilizzo.

Devi configurarlo attentamente, altrimenti lo spam fluirà verso di te o, peggio ancora, lo spam fluirà da te.

# SPF
policyd-spf_time_limit = 3600

Impostazione di alcuni plugin relativi al controllo dell'SPF delle lettere 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

L'impostazione è che dobbiamo fornire una firma DKIM con tutte le e-mail in uscita.

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

Questo è un dettaglio chiave nell'instradamento delle lettere quando si inviano lettere da script PHP.

File “/etc/postfix/sdd_transport.pcre”:

/^[email protected]$/ domain1:
/^[email protected]$/ domain2:
/^[email protected]$/ domain3:
/@domain1.com$/             domain1:
/@domain2.com$/             domain2:
/@domain3.com$/             domain3:

A sinistra ci sono le espressioni regolari. Sulla destra c'è un'etichetta che segna la lettera.
Suffisso secondo l'etichetta: terrà conto di alcune righe di configurazione in più per una lettera specifica.

Come verrà riconfigurato esattamente il suffisso per una lettera specifica sarà indicato in “master.cf”.

Le linee 4, 5, 6 sono le principali. A nome del dominio a cui inviamo la lettera, inseriamo questa etichetta.
Ma il campo “da” non è sempre indicato negli script PHP nel vecchio codice. Quindi il nome utente viene in soccorso.

L'articolo è già ampio: non vorrei essere distratto dalla configurazione di nginx+fpm.

In breve, per ogni sito impostiamo il proprio proprietario utente Linux. E di conseguenza il tuo pool fpm.

Fpm-pool utilizza qualsiasi versione di php (è fantastico quando sullo stesso server puoi utilizzare diverse versioni di php e anche diversi php.ini per siti vicini senza problemi).

Quindi, uno specifico utente Linux “www-domain2” ha un sito web domain2.com. Questo sito ha un codice per inviare email senza specificare il campo mittente.

Quindi, anche in questo caso, le lettere verranno inviate correttamente e non finiranno mai nello spam.

Il mio "/etc/postfix/master.cf" assomiglia a questo:

...
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 viene fornito per intero: è già molto grande.
Ho solo notato cosa è stato cambiato.

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 relative a spamassasin, ne parleremo più avanti.

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

Ti consentiamo di connetterti al server di posta tramite la porta 587.
Per fare ciò è necessario effettuare il login.

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

Abilita il controllo SPF.

apt-get install postfix-policyd-spf-python

Installiamo 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 cosa più interessante. Questa è la possibilità di inviare lettere per un dominio specifico da uno specifico indirizzo IPv4/IPv6.

Questo viene fatto per il bene di rDNS. rDNS è il processo di ricezione di una stringa tramite indirizzo IP.
E per la posta, questa funzione viene utilizzata per confermare che helo corrisponda esattamente all'rDNS dell'indirizzo da cui è stata inviata l'e-mail.

Se l'helo non corrisponde al dominio email per conto del quale è stata inviata la lettera, vengono assegnati punti spam.

Helo non corrisponde a rDNS: vengono assegnati molti punti spam.
Di conseguenza, ogni dominio deve avere il proprio indirizzo IP.
Per OVH - nella console è possibile specificare 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”: abilitiamo il supporto IPv6.
Per IPv6 è necessario registrare anche rDNS.
“syslog_name” - e questo serve per facilitare la lettura dei log.

Acquista certificati Lo consiglio qui.

Impostazione del collegamento postfix+dovecot qui.

Impostazione dell'SPF.

============= Colombaia =============

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

Configurazione di mysql, installazione dei pacchetti stessi.

File "/etc/dovecot/conf.d/10-auth.conf"

disable_plaintext_auth = yes
auth_mechanisms = plain login

L'autorizzazione è solo crittografata.

File “/etc/dovecot/conf.d/10-mail.conf”

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

Qui indichiamo il luogo di archiviazione delle lettere.

Voglio che siano archiviati in file e raggruppati per dominio.

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 abilita connessioni sicure.

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
}

Configurazione SSL. Indichiamo che è richiesto SSL.
E il certificato stesso. E un dettaglio importante è la direttiva “locale”. Indica quale certificato SSL utilizzare per la connessione a quale IPv4 locale.

A proposito, IPv6 non è configurato qui, correggerò questa omissione più tardi.
XX.XX.XX.X5 (dominio2) - nessun certificato. Per connettere i client è necessario specificare dominio1.com.
XX.XX.XX.X2 (dominio3): esiste un certificato, è possibile specificare dominio1.com o dominio3.com per connettere i client.

File "/etc/dovecot/conf.d/15-lda.conf"

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Ciò sarà necessario per Spamassassin in futuro.

File "/etc/dovecot/conf.d/20-imap.conf"

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Questo è un plugin antispam. Necessario per addestrare spamassasin al momento del trasferimento da/verso la cartella “Spam”.

File "/etc/dovecot/conf.d/20-pop3.conf"

protocol pop3 {
}

Esiste proprio un file del genere.

File “/etc/dovecot/conf.d/20-lmtp.conf”

protocol lmtp {
  mail_plugins = $mail_plugins sieve
  postmaster_address = [email protected]
}

Configurazione di ltp.

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 allenamento di Spamassasin 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
}

Un file che specifica cosa fare con le lettere in arrivo.

File "/var/lib/dovecot/sieve/default.sieve"

require ["fileinto", "mailbox"];

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

E' 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
}

Specifica dei file SQL per l'autorizzazione.
E il file stesso viene utilizzato come metodo di autorizzazione.

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';

Ciò corrisponde a impostazioni simili 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.
L'importante è che indichiamo qui: aggiungi protocolli.

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

apt-get install spamassassin spamc

Installiamo i pacchetti.

adduser spamd --disabled-login

Aggiungiamo un utente per conto di chi.

systemctl enable spamassassin.service

Abilitiamo il servizio di caricamento automatico spamassassin al momento del caricamento.

File "/etc/default/spamassassin":

CRON=1

Abilitando l'aggiornamento automatico delle regole “per impostazione predefinita”.

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

È necessario creare un database “sa” in mysql con l'utente “sa” con la password “password” (sostituire con qualcosa di adeguato).

report_safe: invierà una segnalazione di spam via e-mail invece di una lettera.
use_bayes sono le impostazioni di apprendimento automatico di spamassassin.

Le restanti impostazioni di spamassassin sono state utilizzate in precedenza nell'articolo.

Impostazione generale "spamassassin".
Informazioni sullo spostamento di nuove email di spam nella cartella "Spam" IMAP.
Informazioni su una semplice combinazione di Dovecot + SpamAssassin.
Consiglio di leggere la teoria dell'apprendimento di spamassasin quando si spostano le lettere nelle cartelle imap (e non consiglio di usarla).

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

Vorrei anche lanciare un'idea alla comunità su come aumentare il livello di sicurezza delle lettere inoltrate. Dato che sono così profondamente immerso nell'argomento della posta.

In modo che l'utente possa creare una coppia di chiavi sul suo client (outlook, Thunderbird, plugin del browser, ...). Pubblico e privato. Pubblico: invia al DNS. Privato: risparmia sul client. I server di posta sarebbero in grado di utilizzare una chiave pubblica per inviare a un destinatario specifico.

E per proteggerti dallo spam con tali lettere (sì, il server di posta non sarà in grado di visualizzare il contenuto), dovrai introdurre 3 regole:

  1. Firma DKIM reale obbligatoria, SPF obbligatorio, rDNS obbligatorio.
  2. Una rete neurale sul tema dell'addestramento antispam + un relativo database sul lato client.
  3. L'algoritmo di crittografia deve essere tale che il lato mittente debba spendere 100 volte più potenza della CPU per la crittografia rispetto al lato ricevente.

Oltre alle lettere pubbliche, sviluppare una lettera di proposta standard “per iniziare una corrispondenza sicura”. Uno degli utenti (cassetta postale) invia una lettera con un allegato a un'altra casella di posta. La lettera contiene una proposta testuale per avviare un canale di comunicazione sicuro per la corrispondenza e la chiave pubblica del proprietario della casella di posta (con chiave privata lato client).

Puoi anche creare un paio di chiavi specifiche per ogni corrispondenza. L'utente destinatario può accettare questa offerta e inviare la sua chiave pubblica (anch'essa realizzata appositamente per questa corrispondenza). Successivamente, il primo utente invia una lettera di controllo del servizio (crittografata con la chiave pubblica del secondo utente), al ricevimento della quale il secondo utente può considerare affidabile il canale di comunicazione formato. Successivamente, il secondo utente invia una lettera di controllo e quindi anche il primo utente può considerare sicuro il canale formato.

Per contrastare l'intercettazione delle chiavi stradali, il protocollo deve prevedere la possibilità di trasmettere almeno una chiave pubblica tramite una chiavetta USB.

E la cosa più importante è che tutto funzioni (la domanda è “chi lo pagherà?”):
Inserisci certificati postali a partire da $ 10 per 3 anni. Ciò consentirà al mittente di indicare nel DNS che “le mie chiavi pubbliche sono laggiù”. E ti daranno l'opportunità di avviare una connessione sicura. Allo stesso tempo, accettare tali connessioni è gratuito.
Gmail sta finalmente monetizzando i suoi utenti. Per 10 dollari ogni 3 anni: il diritto di creare canali di corrispondenza 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 si sono sviluppate, quindi questo problema si è trascinato per 2 mesi.
E così, quando ho avuto di nuovo del tempo libero, ho deciso di pubblicare l'articolo così com'è, per non rischiare che la pubblicazione si trascinasse per un altro anno.

Se ci sono molte domande del tipo “ma questo non è descritto in modo sufficientemente dettagliato”, allora probabilmente ci sarà la forza di prendere un server dedicato con un nuovo dominio e un nuovo certificato SSL e descriverlo in modo ancora più dettagliato e, soprattutto, soprattutto, identificare tutti i dettagli importanti mancanti.

Vorrei anche ricevere feedback su idee sui certificati postali. Se l’idea ti piace, proverò a trovare la forza per scrivere una bozza per rfc.

Quando copi parti estese di un articolo, fornisci un collegamento a questo articolo.
Quando traduci in qualsiasi altra lingua, fornisci un collegamento a questo articolo.
Cercherò di tradurlo io stesso in inglese e di lasciare i riferimenti incrociati.


Fonte: habr.com

Aggiungi un commento