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

Cet article explique comment configurer un serveur de messagerie moderne.
Postfix + Pigeonnier. SPF + DKIM + rDNS. Avec IPv6.
Avec cryptage TSL. Avec prise en charge de plusieurs domaines - partie avec un véritable certificat SSL.
Avec une protection antispam et un indice antispam élevé provenant d'autres serveurs de messagerie.
Prend en charge plusieurs interfaces physiques.
Avec OpenVPN, dont la connexion se fait via IPv4, et qui fournit IPv6.

Si vous ne souhaitez pas apprendre toutes ces technologies, mais souhaitez mettre en place un tel serveur, alors cet article est fait pour vous.

L’article ne tente pas d’expliquer chaque détail. L’explication porte sur ce qui n’est pas configuré en standard ou est important du point de vue du consommateur.

La motivation de créer un serveur de messagerie est un de mes rêves de longue date. Cela peut paraître stupide, mais à mon humble avis, c'est bien mieux que de rêver d'une nouvelle voiture de votre marque préférée.

Il existe deux motivations pour configurer IPv6. Un informaticien doit constamment apprendre de nouvelles technologies pour survivre. Je voudrais apporter ma modeste contribution à la lutte contre la censure.

La motivation pour configurer OpenVPN est simplement de faire fonctionner IPv6 sur la machine locale.
La motivation pour mettre en place plusieurs interfaces physiques est que sur mon serveur j'ai une interface « lente mais illimitée » et une autre « rapide mais payante ».

La motivation pour configurer les paramètres de Bind est que mon FAI fournit un serveur DNS instable et que Google échoue parfois également. Je veux un serveur DNS stable pour un usage personnel.

Motivation pour écrire un article – J'ai écrit un brouillon il y a 10 mois et je l'ai déjà regardé deux fois. Même si l’auteur en a régulièrement besoin, il y a de fortes chances que d’autres en aient également besoin.

Il n'existe pas de solution universelle pour un serveur de messagerie. Mais je vais essayer d’écrire quelque chose comme « faites ceci et ensuite, quand tout fonctionne comme il se doit, jetez les trucs supplémentaires ».

La société tech.ru dispose d'un serveur de colocation. Il est possible de comparer avec OVH, Hetzner, AWS. Pour résoudre ce problème, la coopération avec tech.ru sera beaucoup plus efficace.

Debian 9 est installé sur le serveur.

Le serveur dispose de 2 interfaces `eno1` et `eno2`. Le premier est respectivement illimité et le second est rapide.

Il y a 3 adresses IP statiques, XX.XX.XX.X0 et XX.XX.XX.X1 et XX.XX.XX.X2 sur l'interface `eno1` et XX.XX.XX.X5 sur l'interface `eno2` .

Disponible XXXX:XXXX:XXXX:XXXX::/64 un pool d'adresses IPv6 attribuées à l'interface `eno1` et à partir de là XXXX:XXXX:XXXX:XXXX:1:2::/96 a été attribué à `eno2` à ma demande.

Il existe 3 domaines « domain1.com », « domain2.com », « domain3.com ». Il existe un certificat SSL pour « domain1.com » et « domain3.com ».

J'ai un compte Google auquel je souhaite associer ma boîte mail[email protected]` (réception et envoi de mail directement depuis l'interface gmail).
Il doit y avoir une boîte aux lettres[email protected]`, une copie du mail que je souhaite voir dans mon Gmail. Et c'est rare de pouvoir envoyer quelque chose de la part de `[email protected]` via l'interface web.

Il doit y avoir une boîte aux lettres[email protected]`, qu'Ivanov utilisera depuis son iPhone.

Les e-mails envoyés doivent être conformes à toutes les exigences antispam modernes.
Le niveau de cryptage le plus élevé doit être fourni sur les réseaux publics.
Il devrait y avoir une prise en charge IPv6 pour l'envoi et la réception de lettres.
Il devrait y avoir un SpamAssassin qui ne supprimera jamais les e-mails. Et il sera rebondi, ignoré ou envoyé dans le dossier IMAP « Spam ».
L'auto-apprentissage de SpamAssassin doit être configuré : si je déplace une lettre vers le dossier Spam, il en tirera des leçons ; si je déplace une lettre du dossier Spam, il en tirera des leçons. Les résultats de la formation SpamAssassin devraient influencer le fait que la lettre finisse dans le dossier Spam.
Les scripts PHP doivent être capables d'envoyer du courrier au nom de n'importe quel domaine sur un serveur donné.
Il devrait y avoir un service openvpn, avec la possibilité d'utiliser IPv6 sur un client qui n'a pas IPv6.

Vous devez d'abord configurer les interfaces et le routage, y compris IPv6.
Ensuite, vous devrez configurer OpenVPN, qui se connectera via IPv4 et fournira au client une adresse IPv6 réelle et statique. Ce client aura accès à tous les services IPv6 sur le serveur et à toutes les ressources IPv6 sur Internet.
Ensuite, vous devrez configurer Postfix pour envoyer des lettres + SPF + DKIM + rDNS et d'autres petites choses similaires.
Ensuite, vous devrez configurer Dovecot et configurer Multidomain.
Ensuite, vous devrez configurer SpamAssassin et configurer la formation.
Enfin, installez Bind.

============= Multi-interfaces =============

Pour configurer les interfaces, vous devez écrire ceci dans « /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

Ces paramètres peuvent être appliqués sur n'importe quel serveur de tech.ru (avec un peu de coordination avec le support) et cela fonctionnera immédiatement comme il se doit.

Si vous avez de l’expérience dans la mise en place de choses similaires pour Hetzner, OVH, là c’est différent. Plus difficile.

eno1 est le nom de la carte réseau n°1 (lent mais illimité).
eno2 est le nom de la carte réseau n°2 (rapide, mais avec tarif).
tun0 est le nom de la carte réseau virtuelle d'OpenVPN.
XX.XX.XX.X0 - IPv4 #1 sur eno1.
XX.XX.XX.X1 - IPv4 #2 sur eno1.
XX.XX.XX.X2 - IPv4 #3 sur eno1.
XX.XX.XX.X5 - IPv4 #1 sur eno2.
XX.XX.XX.1 - Passerelle IPv4.
XXXX:XXXX:XXXX:XXXX ::/64 - IPv6 pour l'ensemble du serveur.
XXXX:XXXX:XXXX:XXXX:1:2::/96 - IPv6 pour eno2, tout le reste de l'extérieur va dans eno1.
XXXX:XXXX:XXXX:XXXX::1 — Passerelle IPv6 (il convient de noter que cela peut/doit être fait différemment. Spécifiez le commutateur IPv6).
dns-nameservers - 127.0.0.1 est indiqué (car bind est installé localement) et 213.248.1.6 (cela provient de tech.ru).

"table eno1t" et "table eno2t" - la signification de ces règles de route est que le trafic entrant par eno1 -> sortirait par elle, et le trafic entrant par eno2 -> sortirait par elle. Et aussi les connexions initiées par le serveur passeraient par eno1.

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

Avec cette commande, nous spécifions que tout trafic incompréhensible relevant d'une règle marquée « table eno1t » -> soit envoyé à l'interface eno1.

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

Avec cette commande nous précisons que tout trafic initié par le serveur doit être dirigé vers l'interface eno1.

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

Avec cette commande, nous définissons les règles de marquage du trafic.

auto eno1:2
iface eno1:2 inet static
address XX.XX.XX.X2
netmask 255.255.255.0
        post-up ip rule add table eno1t from XX.XX.XX.X2
        post-up ip rule add table eno1t to XX.XX.XX.X2

Ce bloc spécifie un deuxième IPv4 pour l'interface eno1.

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

Avec cette commande, nous définissons la route des clients OpenVPN vers l'IPv4 local sauf XX.XX.XX.X0.
Je ne comprends toujours pas pourquoi cette commande suffit pour tout IPv4.

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

C'est ici que nous définissons l'adresse de l'interface elle-même. Le serveur l'utilisera comme adresse « sortante ». Ne sera plus utilisé en aucune façon.

Pourquoi ":1:1::" est-il si compliqué ? Pour qu'OpenVPN fonctionne correctement et uniquement pour cela. Nous en reparlerons plus tard.

Au sujet de la passerelle, c'est comme ça que ça marche et c'est très bien. Mais la bonne manière est d'indiquer ici l'IPv6 du switch auquel le serveur est connecté.

Cependant, pour une raison quelconque, IPv6 cesse de fonctionner si je fais cela. Il s'agit probablement d'une sorte de problème tech.ru.

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

Cela ajoute une adresse IPv6 à l'interface. Si vous avez besoin d'une centaine d'adresses, cela signifie une centaine de lignes dans ce fichier.

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

J'ai noté les adresses et sous-réseaux de toutes les interfaces pour que ce soit clair.
eno1 - doit être "/64" - parce qu'il s'agit de l'intégralité de notre pool d'adresses.
tun0 - le sous-réseau doit être plus grand que eno1. Sinon, il ne sera pas possible de configurer une passerelle IPv6 pour les clients OpenVPN.
eno2 - le sous-réseau doit être plus grand que tun0. Sinon, les clients OpenVPN ne pourront pas accéder aux adresses IPv6 locales.
Pour plus de clarté, j'ai choisi un pas de sous-réseau de 16, mais si vous le souhaitez, vous pouvez même faire le pas « 1 ».
En conséquence, 64+16 = 80 et 80+16 = 96.

Pour encore plus de clarté :
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY sont des adresses qui doivent être attribuées à des sites ou services spécifiques sur l'interface eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY sont des adresses qui doivent être attribuées à des sites ou services spécifiques sur l'interface eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY sont des adresses qui doivent être attribuées aux clients OpenVPN ou utilisées comme adresses de service OpenVPN.

Pour configurer le réseau, il devrait être possible de redémarrer le serveur.
Les modifications IPv4 sont récupérées lors de leur exécution (assurez-vous de les envelopper dans screen - sinon cette commande fera simplement planter le réseau sur le serveur) :

/etc/init.d/networking restart

Ajouter à la fin du fichier « /etc/iproute2/rt_tables » :

100 eno1t
101 eno2t

Sans cela, vous ne pouvez pas utiliser de tables personnalisées dans le fichier « /etc/network/interfaces ».
Les numéros doivent être uniques et inférieurs à 65535.

Les modifications IPv6 peuvent être facilement modifiées sans redémarrer, mais pour ce faire, vous devez apprendre au moins trois commandes :

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

Paramètre "/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

Ce sont les paramètres "sysctl" de mon serveur. Permettez-moi de souligner quelque chose d'important.

net.ipv4.ip_forward = 1

Sans cela, OpenVPN ne fonctionnera pas du tout.

net.ipv6.ip_nonlocal_bind = 1

Quiconque tente de lier IPv6 (par exemple nginx) immédiatement après le lancement de l'interface recevra une erreur. Que cette adresse n'est pas disponible.

Pour éviter une telle situation, un tel réglage est effectué.

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

Sans ces paramètres IPv6, le trafic du client OpenVPN ne sort pas vers le monde.

Les autres paramètres ne sont pas pertinents ou je ne me souviens plus à quoi ils servent.
Mais juste au cas où, je le laisse « tel quel ».

Pour que les modifications apportées à ce fichier soient récupérées sans redémarrer le serveur, vous devez exécuter la commande :

sysctl -p

Plus de détails sur les règles de « table » : habr.com/post/108690

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

OpenVPN IPv4 ne fonctionne pas sans iptables.

Mes iptables sont comme ceci pour 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 est mon adresse IPv4 statique de la machine locale.
10.8.0.0/24 - Réseau openvpn IPv4. Adresses IPv4 pour les clients openvpn.
La cohérence des règles est 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

Il s'agit d'une limitation permettant à moi seul de pouvoir utiliser OpenVPN à partir de mon adresse IP statique.

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

Pour transférer des paquets IPv4 entre les clients OpenVPN et Internet, vous devez enregistrer l'une de ces commandes.

Pour différents cas, l'une des options ne convient pas.
Les deux commandes conviennent à mon cas.
Après avoir lu la documentation, j'ai choisi la première option car elle utilise moins de CPU.

Pour que tous les paramètres iptables soient récupérés après le redémarrage, vous devez les enregistrer quelque part.

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

De tels noms n’ont pas été choisis par hasard. Ils sont utilisés par le package "iptables-persistent".

apt-get install iptables-persistent

Installation du package principal OpenVPN :

apt-get install openvpn easy-rsa

Créons un modèle pour les certificats (remplacez vos valeurs) :

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

Modifions les paramètres du modèle de certificat :

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

Créez un certificat de serveur :

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

Préparons la possibilité de créer les fichiers finaux « nom-client.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

Préparons un script qui fusionnera tous les fichiers en un seul fichier 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

Création du premier client OpenVPN :

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

Le fichier « ~/client-configs/files/client-name.ovpn » est envoyé à l'appareil du client.

Pour les clients iOS, vous devrez suivre l'astuce suivante :
Le contenu de la balise "tls-auth" doit être sans commentaires.
Et mettez également « key-direction 1 » immédiatement avant la balise « tls-auth ».

Configurons la configuration du serveur 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

Ceci est nécessaire afin de définir une adresse statique pour chaque client (pas nécessaire, mais je l'utilise) :

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

Le détail le plus difficile et le plus clé.

Malheureusement, OpenVPN ne sait pas encore comment configurer indépendamment une passerelle IPv6 pour les clients.
Vous devez le transmettre « manuellement » pour chaque client.

# Run client-specific script on connection and disconnection
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/server-clientdisconnect.sh"

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

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

Les deux scripts utilisent le fichier « /etc/openvpn/variables » :

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

J'ai du mal à me rappeler pourquoi c'est écrit ainsi.

Maintenant, netmask = 112 semble étrange (il devrait être 96 juste là).
Et le préfixe est étrange, il ne correspond pas au réseau tun0.
Mais bon, je vais le laisser tel quel.

cipher DES-EDE3-CBC

Ce n'est pas pour tout le monde - j'ai choisi cette méthode de cryptage de la connexion.

En savoir plus sur la configuration d'OpenVPN IPv4.

En savoir plus sur la configuration d'OpenVPN IPv6.

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

Installation du package principal :

apt-get install postfix

Lors de l'installation, sélectionnez « site internet ».

Mon "/etc/postfix/main.cf" ressemble à ceci :

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

Regardons les détails de cette configuration.

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

Selon les habitants de Khabrovsk, ce bloc contient « des informations erronées et des thèses incorrectes ».Ce n'est que 8 ans après le début de ma carrière que j'ai commencé à comprendre le fonctionnement de SSL.

Je me permettrai donc de décrire comment utiliser SSL (sans répondre aux questions « Comment ça marche ? » et « Pourquoi ça marche ? »).

La base du cryptage moderne est la création d’une paire de clés (deux très longues chaînes de caractères).

Une « clé » est privée, l’autre clé est « publique ». Nous gardons la clé privée très soigneusement secrète. Nous distribuons la clé publique à tout le monde.

À l’aide d’une clé publique, vous pouvez chiffrer une chaîne de texte afin que seul le propriétaire de la clé privée puisse la déchiffrer.
Eh bien, c'est toute la base de la technologie.

Étape n°1 – Sites https.
Lors de l'accès à un site, le navigateur apprend du serveur web que le site est https et demande donc une clé publique.
Le serveur web donne la clé publique. Le navigateur utilise la clé publique pour crypter la requête http et l'envoyer.
Le contenu d'une requête http ne peut être lu que par ceux qui possèdent la clé privée, c'est-à-dire uniquement par le serveur auquel la requête est adressée.
La requête HTTP contient au moins un URI. Par conséquent, si un pays tente de restreindre l'accès non pas à l'ensemble du site, mais à une page spécifique, cela est alors impossible à faire pour les sites https.

Étape n°2 : réponse cryptée.
Le serveur Web fournit une réponse facilement lisible en cours de route.
La solution est extrêmement simple : le navigateur génère localement la même paire de clés privée-publique pour chaque site https.
Et en plus de la demande de clé publique du site, il envoie sa clé publique locale.
Le serveur Web s'en souvient et, lors de l'envoi d'une réponse http, la crypte avec la clé publique d'un client spécifique.
Désormais, la réponse http ne peut être déchiffrée que par le propriétaire de la clé privée du navigateur du client (c'est-à-dire le client lui-même).

Étape n°3 - établir une connexion sécurisée via un canal public.
Il existe une vulnérabilité dans l'exemple n° 2 : rien n'empêche les sympathisants d'intercepter une requête http et de modifier des informations sur la clé publique.
Ainsi, l'intermédiaire verra clairement tout le contenu des messages envoyés et reçus jusqu'à ce que le canal de communication change.
La gestion de ce problème est extrêmement simple : il suffit d'envoyer la clé publique du navigateur sous forme de message chiffré avec la clé publique du serveur Web.
Le serveur Web envoie alors d’abord une réponse du type « votre clé publique est comme ça » et crypte ce message avec la même clé publique.
Le navigateur examine la réponse - si le message « votre clé publique est comme ceci » est reçu - alors c'est une garantie à 100 % que ce canal de communication est sécurisé.
Est-ce sûr ?
La création même d’un tel canal de communication sécurisé s’effectue à une vitesse de ping*2. Par exemple 20 ms.
L'attaquant doit disposer au préalable de la clé privée de l'une des parties. Ou trouvez une clé privée en quelques millisecondes.
Le piratage d’une clé privée moderne prendra des décennies sur un superordinateur.

Étape n°4 – base de données publique des clés publiques.
De toute évidence, dans toute cette histoire, il existe une possibilité pour un attaquant de s'installer sur le canal de communication entre le client et le serveur.
Le client peut se faire passer pour le serveur, et le serveur peut se faire passer pour le client. Et émulez une paire de clés dans les deux sens.
L’attaquant verra alors tout le trafic et pourra « modifier » le trafic.
Par exemple, modifiez l'adresse à laquelle envoyer de l'argent ou copiez le mot de passe des services bancaires en ligne ou bloquez le contenu « répréhensible ».
Pour lutter contre ces attaquants, ils ont mis au point une base de données publique avec des clés publiques pour chaque site https.
Chaque navigateur « connaît » l’existence d’environ 200 bases de données de ce type. Ceci est préinstallé dans chaque navigateur.
Les « connaissances » sont soutenues par une clé publique de chaque certificat. Autrement dit, la connexion à chaque autorité de certification spécifique ne peut pas être falsifiée.

Il existe désormais une compréhension simple de la façon d'utiliser SSL pour https.
Si vous utilisez votre cerveau, vous comprendrez comment les services spéciaux peuvent pirater quelque chose dans cette structure. Mais cela leur coûtera des efforts monstrueux.
Et pour les organisations plus petites que la NSA ou la CIA, il est presque impossible de pirater le niveau de protection existant, même pour les VIP.

J'ajouterai également sur les connexions ssh. Il n’y a pas de clé publique là-bas, alors que pouvez-vous faire ? Le problème est résolu de deux manières.
Option ssh par mot de passe :
Lors de la première connexion, le client ssh doit avertir que nous avons une nouvelle clé publique du serveur ssh.
Et lors d'autres connexions, si l'avertissement « nouvelle clé publique du serveur ssh » apparaît, cela signifiera qu'ils essaient de vous espionner.
Ou vous avez été écouté lors de votre première connexion, mais vous communiquez désormais avec le serveur sans intermédiaires.
En fait, étant donné que le fait des écoutes téléphoniques est révélé facilement, rapidement et sans effort, cette attaque n'est utilisée que dans des cas particuliers pour un client spécifique.

Option ssh par clé :
Nous prenons une clé USB, y écrivons la clé privée du serveur ssh (il y a des termes et beaucoup de nuances importantes pour cela, mais j'écris un programme éducatif, pas des instructions d'utilisation).
Nous laissons la clé publique sur la machine où se trouvera le client ssh et nous la gardons également secrète.
Nous apportons la clé USB au serveur, l'insérons, copions la clé privée, brûlons la clé USB et dispersons les cendres au vent (ou au moins la formatons avec des zéros).
C'est tout - après une telle opération, il sera impossible de pirater une telle connexion ssh. Bien sûr, dans 10 ans, il sera possible de visualiser le trafic sur un superordinateur, mais c'est une autre histoire.

Je m'excuse pour l'offtopic.

Alors maintenant que la théorie est connue. Je vais vous parler du processus de création d'un certificat SSL.

En utilisant « openssl genrsa », nous créons une clé privée et des « blancs » pour la clé publique.
Nous envoyons les « blancs » à une société tierce, à laquelle nous payons environ 9 $ pour le certificat le plus simple.

Après quelques heures, nous recevons notre clé « publique » et un ensemble de plusieurs clés publiques de cette société tierce.

Pourquoi une société tierce devrait-elle payer pour l'enregistrement de ma clé publique est une question distincte, nous ne l'examinerons pas ici.

La signification de l’inscription est maintenant claire :

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

Le dossier «/etc/ssl» contient tous les fichiers pour les problèmes SSL.
domain1.com – nom de domaine.
2018 est l’année de la création clé.
« clé » - désignation selon laquelle le fichier est une clé privée.

Et la signification de ce fichier :

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com – nom de domaine.
2018 est l’année de la création clé.
enchaîné - désignation selon laquelle il existe une chaîne de clés publiques (la première est notre clé publique et les autres proviennent de la société qui a émis la clé publique).
crt - désignation qu'il existe un certificat prêt à l'emploi (clé publique avec explications techniques).

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

Ce paramètre n'est pas utilisé dans ce cas, mais est écrit à titre d'exemple.

Car une erreur dans ce paramètre entraînera l'envoi de spam depuis votre serveur (sans votre volonté).

Alors prouvez à tout le monde que vous n’êtes pas coupable.

recipient_delimiter = +

Beaucoup de gens ne le savent peut-être pas, mais il s’agit d’un caractère standard pour classer les e-mails et il est pris en charge par la plupart des serveurs de messagerie modernes.

Par exemple, si vous disposez d'une boîte aux lettres "[email protected]"essayez d'envoyer à"[email protected]"- regarde ce qui arrive.

inet_protocols = ipv4

Cela pourrait prêter à confusion.

Mais ce n'est pas seulement comme ça. Chaque nouveau domaine est par défaut uniquement IPv4, puis j'active IPv6 pour chacun séparément.

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

Nous précisons ici que tout le courrier entrant est envoyé à Dovecot.
Et les règles pour le domaine, la boîte aux lettres, l'alias - recherchez dans la base de données.

/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

Désormais, Postfix sait que le courrier ne peut être accepté pour un envoi ultérieur qu'après autorisation de Dovecot.

Je ne comprends vraiment pas vraiment pourquoi cela est dupliqué ici. Nous avons déjà spécifié tout ce qui est nécessaire dans « virtual_transport ».

Mais le système postfix est très ancien – c’est probablement un retour du bon vieux temps.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Cela peut être configuré différemment pour chaque serveur de messagerie.

J'ai 3 serveurs de messagerie à ma disposition et ces paramètres sont très différents en raison des différentes exigences d'utilisation.

Vous devez le configurer avec soin - sinon du spam vous affluera, ou pire encore - du spam sortira de vous.

# SPF
policyd-spf_time_limit = 3600

Configuration d'un plugin lié à la vérification du SPF des lettres entrantes.

# 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

Le paramètre est que nous devons fournir une signature DKIM avec tous les e-mails sortants.

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

Il s'agit d'un détail clé dans le routage des lettres lors de l'envoi de lettres à partir de scripts PHP.

Fichier « /etc/postfix/sdd_transport.pcre » :

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

À gauche se trouvent les expressions régulières. À droite se trouve une étiquette qui marque la lettre.
Postfix conformément à l'étiquette - prendra en compte quelques lignes de configuration supplémentaires pour une lettre spécifique.

La manière exacte dont Postfix sera reconfiguré pour une lettre spécifique sera indiquée dans « master.cf ».

Les lignes 4, 5, 6 sont les principales. Au nom du domaine auquel nous envoyons la lettre, nous mettons cette étiquette.
Mais le champ « de » n'est pas toujours indiqué dans les scripts PHP dans l'ancien code. Ensuite, le nom d'utilisateur vient à la rescousse.

L'article est déjà long - je ne voudrais pas être distrait par la configuration de nginx+fpm.

En bref, pour chaque site, nous définissons son propre propriétaire utilisateur Linux. Et par conséquent votre pool fpm.

Fpm-pool utilise n'importe quelle version de php (c'est génial quand sur le même serveur vous pouvez utiliser différentes versions de php et même différents php.ini pour les sites voisins sans problème).

Ainsi, un utilisateur Linux spécifique « www-domain2 » possède un site Web domain2.com. Ce site dispose d'un code pour envoyer des emails sans préciser le champ de.

Ainsi, même dans ce cas, les lettres seront envoyées correctement et ne finiront jamais dans les spams.

Mon "/etc/postfix/master.cf" ressemble à ceci :

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

Le fichier n'est pas fourni dans son intégralité - il est déjà très volumineux.
J'ai seulement noté ce qui avait changé.

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}

Ce sont des paramètres liés à spamassasin, nous y reviendrons plus tard.

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

Nous vous permettons de vous connecter au serveur de messagerie via le port 587.
Pour ce faire, vous devez vous connecter.

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

Activez la vérification SPF.

apt-get install postfix-policyd-spf-python

Installons le package pour les vérifications SPF ci-dessus.

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

Et c'est la chose la plus intéressante. Il s'agit de la possibilité d'envoyer des lettres pour un domaine spécifique à partir d'une adresse IPv4/IPv6 spécifique.

Ceci est fait pour le bien du rDNS. rDNS est le processus de réception d'une chaîne par adresse IP.
Et pour le courrier, cette fonctionnalité permet de confirmer que l'hélicoptère correspond exactement au rDNS de l'adresse à partir de laquelle l'e-mail a été envoyé.

Si l'hélicoptère ne correspond pas au domaine de messagerie au nom duquel la lettre a été envoyée, des points de spam sont attribués.

Helo ne correspond pas au rDNS - de nombreux points de spam sont attribués.
En conséquence, chaque domaine doit avoir sa propre adresse IP.
Pour OVH - dans la console il est possible de préciser rDNS.
Pour tech.ru, le problème est résolu via le support.
Pour AWS, le problème est résolu via le support.
«inet_protocols» et «smtp_bind_address6» - nous activons la prise en charge IPv6.
Pour IPv6, vous devez également enregistrer rDNS.
"syslog_name" - et ceci pour faciliter la lecture des journaux.

Acheter des certificats Je recommande ici.

Configuration du lien postfix + dovecot ici.

Réglage du SPF.

============= Pigeonnier =============

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

Configuration de MySQL, installation des packages eux-mêmes.

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

disable_plaintext_auth = yes
auth_mechanisms = plain login

L'autorisation est uniquement cryptée.

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

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

Nous indiquons ici l'emplacement de stockage des lettres.

Je souhaite qu'ils soient stockés dans des fichiers et regroupés par domaine.

Fichier "/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 {
  }
}

Il s'agit du fichier de configuration principal de Dovecot.
Ici, nous désactivons les connexions non sécurisées.
Et activez des connexions sécurisées.

Fichier "/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
}

Configuration de SSL. Nous indiquons que SSL est requis.
Et le certificat lui-même. Et un détail important est la directive « locale ». Indique quel certificat SSL utiliser lors de la connexion à quel IPv4 local.

D’ailleurs, IPv6 n’est pas configuré ici, je corrigerai cette omission plus tard.
XX.XX.XX.X5 (domaine2) - pas de certificat. Pour connecter les clients, vous devez spécifier domain1.com.
XX.XX.XX.X2 (domain3) - il existe un certificat, vous pouvez spécifier domain1.com ou domain3.com pour connecter les clients.

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

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Cela sera nécessaire pour spamassassin à l'avenir.

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

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Ceci est un plugin anti-spam. Nécessaire pour la formation de spamassasin au moment du transfert vers/depuis le dossier « Spam ».

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

protocol pop3 {
}

Il existe justement un tel fichier.

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

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

Configuration de LMTP.

Fichier "/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
}

Paramètres de formation Spamassasin au moment du transfert vers/depuis le dossier Spam.

Fichier "/etc/dovecot/conf.d/90-sieve.conf"

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

Un fichier qui spécifie quoi faire avec les lettres entrantes.

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

require ["fileinto", "mailbox"];

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

Vous devez compiler le fichier : « sievec default.sieve ».

Fichier "/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
}

Spécification des fichiers SQL pour l'autorisation.
Et le fichier lui-même est utilisé comme méthode d'autorisation.

Fichier "/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';

Cela correspond à des paramètres similaires pour Postfix.

Fichier "/etc/dovecot/dovecot.conf"

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

Fichier de configuration principal.
L'important est que nous indiquions ici - ajouter des protocoles.

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

apt-get install spamassassin spamc

Installons les packages.

adduser spamd --disabled-login

Ajoutons un utilisateur au nom de qui.

systemctl enable spamassassin.service

Nous activons le service spamassassin à chargement automatique lors du chargement.

Fichier "/etc/default/spamassassin" :

CRON=1

En permettant la mise à jour automatique des règles « par défaut ».

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

Vous devez créer une base de données « sa » dans MySQL avec l'utilisateur « sa » avec le mot de passe « password » (remplacer par quelque chose d'adéquat).

report_safe - cela enverra un rapport de courrier indésirable au lieu d'une lettre.
use_bayes sont des paramètres d'apprentissage automatique de spamassassin.

Les paramètres restants de spamassassin ont été utilisés plus tôt dans l'article.

Paramètre général "spamassassin".
À propos du déplacement des nouveaux courriers indésirables vers le dossier IMAP « Spam ».
À propos d'une simple combinaison de Dovecot + SpamAssassin.
Je recommande de lire la théorie d'apprentissage du spamassasin lors du déplacement de lettres dans des dossiers imap (et je ne recommande pas de l'utiliser).

============= Appel à la communauté =============

Je voudrais également lancer une idée à la communauté sur la façon d'augmenter le niveau de sécurité des lettres transférées. Puisque je suis si profondément immergé dans le sujet du courrier.

Pour que l'utilisateur puisse créer une paire de clés sur son client (outlook, Thunderbird, browser-plugin, ...). Publique et privée. Public - envoyer au DNS. Privé - économisez sur le client. Les serveurs de messagerie pourraient utiliser une clé publique pour envoyer à un destinataire spécifique.

Et pour vous protéger du spam avec de telles lettres (oui, le serveur de messagerie ne pourra pas voir le contenu) - vous devrez introduire 3 règles :

  1. Signature DKIM réelle obligatoire, SPF obligatoire, rDNS obligatoire.
  2. Un réseau de neurones sur le thème de la formation antispam + une base de données pour celui-ci côté client.
  3. L'algorithme de chiffrement doit être tel que le côté émetteur doit consacrer 100 fois plus de puissance CPU au chiffrement que le côté récepteur.

En plus des lettres publiques, élaborez une lettre de proposition standard « pour commencer une correspondance sécurisée ». L'un des utilisateurs (boîte aux lettres) envoie une lettre avec pièce jointe à une autre boîte aux lettres. La lettre contient une proposition de texte pour démarrer un canal de communication sécurisé pour la correspondance et la clé publique du propriétaire de la boîte aux lettres (avec une clé privée côté client).

Vous pouvez même créer quelques clés spécifiquement pour chaque correspondance. L'utilisateur destinataire peut accepter cette offre et envoyer sa clé publique (également réalisée spécifiquement pour cette correspondance). Ensuite, le premier utilisateur envoie une lettre de contrôle de service (cryptée avec la clé publique du deuxième utilisateur) - à la réception de laquelle le deuxième utilisateur peut considérer comme fiable le canal de communication formé. Ensuite, le deuxième utilisateur envoie une lettre de contrôle - et le premier utilisateur peut alors également considérer le canal formé comme sécurisé.

Pour lutter contre l'interception des clés sur la route, le protocole doit prévoir la possibilité de transmettre au moins une clé publique à l'aide d'une clé USB.

Et le plus important c’est que tout fonctionne (la question est « qui va payer pour ça ? ») :
Entrez les certificats postaux à partir de 10 $ pour 3 ans. Ce qui permettra à l’expéditeur d’indiquer dans le DNS que « mes clés publiques sont là-bas ». Et ils vous donneront la possibilité d’établir une connexion sécurisée. Dans le même temps, l’acceptation de telles connexions est gratuite.
Gmail monétise enfin ses utilisateurs. Pour 10 $ tous les 3 ans - le droit de créer des canaux de correspondance sécurisés.

============= Conclusion =============

Pour tester l'intégralité de l'article, j'allais louer un serveur dédié pendant un mois et acheter un domaine avec un certificat SSL.

Mais les circonstances de la vie ont évolué et cette question a duré 2 mois.
Ainsi, lorsque j'ai eu du temps libre à nouveau, j'ai décidé de publier l'article tel quel, plutôt que de risquer que la publication s'éternise encore un an.

S'il y a beaucoup de questions du type « mais cela n'est pas décrit de manière suffisamment détaillée », alors il sera probablement plus fort de prendre un serveur dédié avec un nouveau domaine et un nouveau certificat SSL et de le décrire encore plus en détail et, la plupart du temps, surtout, identifiez tous les détails importants manquants.

J'aimerais également avoir des retours sur des idées concernant les certificats postaux. Si l’idée vous plaît, j’essaierai de trouver la force d’écrire un brouillon pour RFC.

Lorsque vous copiez de grandes parties d’un article, fournissez un lien vers cet article.
Lors de la traduction dans une autre langue, fournissez un lien vers cet article.
Je vais essayer de le traduire moi-même en anglais et laisser des références croisées.


Source: habr.com

Ajouter un commentaire