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

In diesem Artikel geht es um die Einrichtung eines modernen Mailservers.
Postfix + Taubenschlag. SPF + DKIM + rDNS. Mit IPv6.
Mit TSL-Verschlüsselung. Mit Unterstützung für mehrere Domains – teilweise mit echtem SSL-Zertifikat.
Mit Antispam-Schutz und einer hohen Antispam-Bewertung von anderen Mailservern.
Unterstützt mehrere physische Schnittstellen.
Mit OpenVPN, dessen Verbindung über IPv4 erfolgt und IPv6 bereitstellt.

Wenn Sie nicht alle diese Technologien erlernen möchten, aber einen solchen Server einrichten möchten, dann ist dieser Artikel genau das Richtige für Sie.

Der Artikel unternimmt keinen Versuch, jedes Detail zu erklären. Die Erklärung bezieht sich auf das, was nicht standardmäßig konfiguriert ist oder aus Verbrauchersicht wichtig ist.

Die Motivation, einen Mailserver einzurichten, war schon lange ein Traum von mir. Das klingt vielleicht dumm, aber meiner Meinung nach ist es viel besser, als von einem neuen Auto Ihrer Lieblingsmarke zu träumen.

Es gibt zwei Beweggründe für die Einrichtung von IPv6. Ein IT-Spezialist muss sich ständig neue Technologien aneignen, um zu überleben. Ich möchte meinen bescheidenen Beitrag zum Kampf gegen die Zensur leisten.

Die Motivation für die Einrichtung von OpenVPN besteht lediglich darin, IPv6 auf dem lokalen Computer zum Laufen zu bringen.
Die Motivation für die Einrichtung mehrerer physischer Schnittstellen liegt darin, dass ich auf meinem Server eine Schnittstelle „langsam aber unbegrenzt“ und eine andere „schnell aber mit Tarif“ habe.

Der Grund für die Einrichtung der Bind-Einstellungen liegt darin, dass mein ISP einen instabilen DNS-Server bereitstellt und Google manchmal auch ausfällt. Ich möchte einen stabilen DNS-Server für den persönlichen Gebrauch.

Motivation, einen Artikel zu schreiben – Ich habe vor 10 Monaten einen Entwurf geschrieben und ihn bereits zweimal angeschaut. Selbst wenn der Autor es regelmäßig benötigt, besteht eine hohe Wahrscheinlichkeit, dass andere es auch benötigen.

Es gibt keine universelle Lösung für einen Mailserver. Aber ich werde versuchen, etwas zu schreiben wie „Mach das und dann, wenn alles so funktioniert, wie es sollte, wirf das überschüssige Zeug weg.“

Das Unternehmen tech.ru verfügt über einen Colocation-Server. Ein Vergleich mit OVH, Hetzner, AWS ist möglich. Um dieses Problem zu lösen, wird die Zusammenarbeit mit tech.ru viel effektiver sein.

Debian 9 ist auf dem Server installiert.

Der Server verfügt über 2 Schnittstellen „eno1“ und „eno2“. Der erste ist unbegrenzt und der zweite ist schnell.

Es gibt 3 statische IP-Adressen, XX.XX.XX.X0 und XX.XX.XX.X1 und XX.XX.XX.X2 auf der Schnittstelle „eno1“ und XX.XX.XX.X5 auf der Schnittstelle „eno2“. .

Verfügbar XXXX:XXXX:XXXX:XXXX::/64 ein Pool von IPv6-Adressen, die der Schnittstelle „eno1“ zugewiesen sind und von dieser aus XXXX:XXXX:XXXX:XXXX:1:2::/96 auf meine Anfrage hin „eno2“ zugewiesen wurde.

Es gibt 3 Domains: „domain1.com“, „domain2.com“, „domain3.com“. Es gibt ein SSL-Zertifikat für „domain1.com“ und „domain3.com“.

Ich habe ein Google-Konto, mit dem ich mein Postfach verknüpfen möchte[E-Mail geschützt] ` (E-Mails empfangen und E-Mails direkt über die Gmail-Oberfläche senden).
Es muss ein Briefkasten vorhanden sein[E-Mail geschützt] `, eine Kopie der E-Mail, die ich in meinem Gmail sehen möchte. Und es kommt selten vor, dass man etwas im Namen von „senden“ kann[E-Mail geschützt] ` über die Weboberfläche.

Es muss ein Briefkasten vorhanden sein[E-Mail geschützt] `, das Ivanov von seinem iPhone aus verwenden wird.

Versendete E-Mails müssen allen modernen Antispam-Anforderungen entsprechen.
In öffentlichen Netzwerken muss die höchste Verschlüsselungsstufe vorhanden sein.
Es sollte IPv6-Unterstützung sowohl für den Versand als auch für den Empfang von Briefen geben.
Es sollte einen SpamAssassin geben, der niemals E-Mails löscht. Und es wird entweder zurückgesendet oder übersprungen oder an den IMAP-Ordner „Spam“ gesendet.
Das automatische Lernen von SpamAssassin muss konfiguriert sein: Wenn ich einen Brief in den Spam-Ordner verschiebe, lernt es daraus; Wenn ich einen Brief aus dem Spam-Ordner verschiebe, lernt es daraus. Die Ergebnisse der SpamAssassin-Schulung sollen Einfluss darauf haben, ob der Brief im Spam-Ordner landet.
PHP-Skripte müssen in der Lage sein, E-Mails im Namen einer beliebigen Domäne auf einem bestimmten Server zu senden.
Es sollte einen OpenVPN-Dienst geben, der die Möglichkeit bietet, IPv6 auf einem Client zu verwenden, der nicht über IPv6 verfügt.

Zuerst müssen Sie Schnittstellen und Routing konfigurieren, einschließlich IPv6.
Anschließend müssen Sie OpenVPN konfigurieren, das eine Verbindung über IPv4 herstellt und dem Client eine statische, echte IPv6-Adresse bereitstellt. Dieser Client hat Zugriff auf alle IPv6-Dienste auf dem Server und Zugriff auf alle IPv6-Ressourcen im Internet.
Dann müssen Sie Postfix so konfigurieren, dass es Briefe + SPF + DKIM + rDNS und andere ähnliche Kleinigkeiten sendet.
Dann müssen Sie Dovecot und Multidomain konfigurieren.
Anschließend müssen Sie SpamAssassin konfigurieren und das Training konfigurieren.
Zum Schluss installieren Sie Bind.

============= Multi-Schnittstellen =============

Um Schnittstellen zu konfigurieren, müssen Sie dies in „/etc/network/interfaces“ schreiben.

# 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

Diese Einstellungen können auf jedem Server in tech.ru angewendet werden (mit ein wenig Abstimmung mit dem Support) und es funktioniert sofort wie es sollte.

Wenn Sie Erfahrung mit der Einrichtung ähnlicher Dinge für Hetzner, OVH haben, ist das dort anders. Schwieriger.

eno1 ist der Name der Netzwerkkarte Nr. 1 (langsam, aber unbegrenzt).
eno2 ist der Name der Netzwerkkarte Nr. 2 (schnell, aber mit Tarif).
tun0 ist der Name der virtuellen Netzwerkkarte von OpenVPN.
XX.XX.XX.X0 – IPv4 #1 auf eno1.
XX.XX.XX.X1 – IPv4 #2 auf eno1.
XX.XX.XX.X2 – IPv4 #3 auf eno1.
XX.XX.XX.X5 – IPv4 #1 auf eno2.
XX.XX.XX.1 – IPv4-Gateway.
XXXX:XXXX:XXXX:XXXX::/64 - IPv6 für den gesamten Server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 – IPv6 für eno2, alles andere von außen geht in eno1.
XXXX:XXXX:XXXX:XXXX::1 – IPv6-Gateway (es ist zu beachten, dass dies anders gemacht werden kann/sollte. Geben Sie den IPv6-Switch an).
DNS-Nameserver - 127.0.0.1 wird angezeigt (da bind lokal installiert ist) und 213.248.1.6 (dies ist von tech.ru).

„table eno1t“ und „table eno2t“ – die Bedeutung dieser Routenregeln besteht darin, dass der über eno1 eingehende Verkehr -> durch ihn abfließt und der über eno2 -> eingehende Verkehr durch ihn abfließt. Und auch vom Server initiierte Verbindungen würden über eno1 laufen.

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

Mit diesem Befehl geben wir an, dass jeglicher unverständlicher Datenverkehr, der unter eine mit „table eno1t“ -> gekennzeichnete Regel fällt, an die eno1-Schnittstelle gesendet wird.

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

Mit diesem Befehl geben wir an, dass jeglicher vom Server initiierter Datenverkehr an die eno1-Schnittstelle weitergeleitet werden soll.

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

Mit diesem Befehl legen wir die Regeln für die Markierung des Verkehrs fest.

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

Dieser Block gibt eine zweite IPv4 für die eno1-Schnittstelle an.

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

Mit diesem Befehl legen wir die Route von OpenVPN-Clients auf lokales IPv4 außer XX.XX.XX.X0 fest.
Ich verstehe immer noch nicht, warum dieser Befehl für alle IPv4 ausreicht.

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

Hier legen wir die Adresse für die Schnittstelle selbst fest. Der Server verwendet sie als „ausgehende“ Adresse. Wird in keiner Weise wieder verwendet.

Warum ist „:1:1::“ so kompliziert? Damit OpenVPN korrekt und nur dafür funktioniert. Mehr dazu später.

Apropos Gateway – so funktioniert es und das ist auch gut so. Der richtige Weg ist jedoch, hier die IPv6 des Switches anzugeben, mit dem der Server verbunden ist.

Allerdings funktioniert IPv6 aus irgendeinem Grund nicht mehr, wenn ich das mache. Dies ist wahrscheinlich ein tech.ru-Problem.

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

Dadurch wird der Schnittstelle eine IPv6-Adresse hinzugefügt. Wenn Sie hundert Adressen benötigen, bedeutet das, dass diese Datei hundert Zeilen enthält.

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

Zur Verdeutlichung habe ich mir die Adressen und Subnetze aller Schnittstellen notiert.
eno1 – muss „sein“/64" - denn das ist unser gesamter Adresspool.
tun0 – das Subnetz muss größer als eno1 sein. Andernfalls ist es nicht möglich, ein IPv6-Gateway für OpenVPN-Clients zu konfigurieren.
eno2 – das Subnetz muss größer als tun0 sein. Andernfalls können OpenVPN-Clients nicht auf lokale IPv6-Adressen zugreifen.
Aus Gründen der Übersichtlichkeit habe ich einen Subnetzschritt von 16 gewählt, aber wenn Sie möchten, können Sie auch einen Schritt von „1“ machen.
Dementsprechend ist 64+16 = 80 und 80+16 = 96.

Für noch mehr Klarheit:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY sind Adressen, die bestimmten Standorten oder Diensten auf der eno1-Schnittstelle zugewiesen werden sollen.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY sind Adressen, die bestimmten Standorten oder Diensten auf der eno2-Schnittstelle zugewiesen werden sollen.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY sind Adressen, die OpenVPN-Clients zugewiesen oder als OpenVPN-Dienstadressen verwendet werden sollen.

Um das Netzwerk zu konfigurieren, sollte ein Neustart des Servers möglich sein.
IPv4-Änderungen werden bei der Ausführung übernommen (stellen Sie sicher, dass Sie sie in den Bildschirm einschließen, da dieser Befehl sonst einfach das Netzwerk auf dem Server zum Absturz bringt):

/etc/init.d/networking restart

Fügen Sie am Ende der Datei „/etc/iproute2/rt_tables“ hinzu:

100 eno1t
101 eno2t

Ohne dies können Sie keine benutzerdefinierten Tabellen in der Datei „/etc/network/interfaces“ verwenden.
Die Nummern müssen eindeutig sein und kleiner als 65535 sein.

IPv6-Änderungen können problemlos ohne Neustart geändert werden. Dazu müssen Sie jedoch mindestens drei Befehle lernen:

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

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

Dies sind die „sysctl“-Einstellungen meines Servers. Lassen Sie mich auf etwas Wichtiges hinweisen.

net.ipv4.ip_forward = 1

Ohne dies funktioniert OpenVPN überhaupt nicht.

net.ipv6.ip_nonlocal_bind = 1

Jeder, der versucht, IPv6 (z. B. Nginx) sofort nach dem Hochfahren der Schnittstelle zu binden, erhält eine Fehlermeldung. Dass diese Adresse nicht verfügbar ist.

Um eine solche Situation zu vermeiden, wird eine solche Einstellung vorgenommen.

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

Ohne diese IPv6-Einstellungen geht der Datenverkehr vom OpenVPN-Client nicht in die Welt hinaus.

Andere Einstellungen sind entweder nicht relevant oder ich weiß nicht mehr, wozu sie dienen.
Aber für alle Fälle lasse ich es so, wie es ist.

Damit Änderungen an dieser Datei übernommen werden, ohne den Server neu zu starten, müssen Sie den folgenden Befehl ausführen:

sysctl -p

Weitere Details zu den „Tisch“-Regeln: habr.com/post/108690

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

OpenVPN IPv4 funktioniert nicht ohne iptables.

Meine iptables für VPN sehen so aus:

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 ist meine statische IPv4-Adresse des lokalen Computers.
10.8.0.0/24 – IPv4 OpenVPN-Netzwerk. IPv4-Adressen für OpenVPN-Clients.
Die Konsistenz der Regeln ist wichtig.

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

Dies ist eine Einschränkung, sodass nur ich OpenVPN von meiner statischen IP aus verwenden kann.

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

Um IPv4-Pakete zwischen OpenVPN-Clients und dem Internet weiterzuleiten, müssen Sie einen dieser Befehle registrieren.

Für verschiedene Fälle ist eine der Optionen nicht geeignet.
Beide Befehle sind für meinen Fall geeignet.
Nachdem ich die Dokumentation gelesen hatte, entschied ich mich für die erste Option, da sie weniger CPU verbraucht.

Damit alle iptables-Einstellungen nach dem Neustart übernommen werden, müssen Sie sie irgendwo speichern.

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

Solche Namen wurden nicht zufällig gewählt. Sie werden vom Paket „iptables-persistent“ verwendet.

apt-get install iptables-persistent

Installation des Haupt-OpenVPN-Pakets:

apt-get install openvpn easy-rsa

Lassen Sie uns eine Vorlage für Zertifikate einrichten (ersetzen Sie Ihre Werte):

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

Lassen Sie uns die Einstellungen der Zertifikatvorlage bearbeiten:

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

Erstellen Sie ein Serverzertifikat:

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

Bereiten wir die Möglichkeit vor, die endgültigen Dateien „client-name.opvn“ zu erstellen:

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

Bereiten wir ein Skript vor, das alle Dateien in einer einzigen opvn-Datei zusammenführt.

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

Erstellen des ersten OpenVPN-Clients:

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

Die Datei „~/client-configs/files/client-name.ovpn“ wird an das Gerät des Clients gesendet.

Für iOS-Clients müssen Sie den folgenden Trick ausführen:
Der Inhalt des „tls-auth“-Tags muss ohne Kommentare sein.
Und fügen Sie außerdem „key-direction 1“ unmittelbar vor dem Tag „tls-auth“ ein.

Lassen Sie uns die OpenVPN-Serverkonfiguration konfigurieren:

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

Dies ist erforderlich, um für jeden Client eine statische Adresse festzulegen (nicht erforderlich, aber ich verwende sie):

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

Das schwierigste und wichtigste Detail.

Leider weiß OpenVPN noch nicht, wie man ein IPv6-Gateway für Clients selbstständig konfiguriert.
Diese müssen Sie für jeden Mandanten „manuell“ weiterleiten.

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

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

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

Beide Skripte verwenden die Datei „/etc/openvpn/variables“:

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

Es fällt mir schwer, mich daran zu erinnern, warum es so geschrieben ist.

Jetzt sieht netmask = 112 seltsam aus (es sollte genau dort 96 sein).
Und das Präfix ist seltsam, es passt nicht zum tun0-Netzwerk.
Aber okay, ich lasse es so wie es ist.

cipher DES-EDE3-CBC

Das ist nicht jedermanns Sache – ich habe diese Methode zur Verschlüsselung der Verbindung gewählt.

Erfahren Sie mehr über die Einrichtung von OpenVPN IPv4.

Erfahren Sie mehr über die Einrichtung von OpenVPN IPv6.

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

Installation des Hauptpakets:

apt-get install postfix

Wählen Sie bei der Installation „Internetseite“ aus.

Meine „/etc/postfix/main.cf“ sieht so aus:

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

Schauen wir uns die Details dieser Konfiguration an.

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

Nach Angaben der Einwohner von Chabrowsk enthält dieser Block „Fehlinformationen und falsche Thesen“.Erst 8 Jahre nach Beginn meiner Karriere begann ich zu verstehen, wie SSL funktioniert.

Daher erlaube ich mir, die Verwendung von SSL zu beschreiben (ohne die Fragen „Wie funktioniert es?“ und „Warum funktioniert es?“ zu beantworten).

Die Grundlage moderner Verschlüsselung ist die Erstellung eines Schlüsselpaares (zwei sehr lange Zeichenfolgen).

Ein „Schlüssel“ ist privat, der andere Schlüssel ist „öffentlich“. Wir halten den privaten Schlüssel sehr sorgfältig geheim. Wir verteilen den öffentlichen Schlüssel an alle.

Mit einem öffentlichen Schlüssel können Sie eine Textzeichenfolge verschlüsseln, sodass nur der Besitzer des privaten Schlüssels sie entschlüsseln kann.
Nun, das ist die gesamte Grundlage der Technologie.

Schritt #1 – https-Sites.
Beim Zugriff auf eine Seite erfährt der Browser vom Webserver, dass die Seite https ist und fordert daher einen öffentlichen Schlüssel an.
Der Webserver gibt den öffentlichen Schlüssel weiter. Der Browser verwendet den öffentlichen Schlüssel, um die http-Anfrage zu verschlüsseln und zu versenden.
Der Inhalt einer http-Anfrage kann nur von dem gelesen werden, der über den privaten Schlüssel verfügt, also nur von dem Server, an den die Anfrage gerichtet ist.
Die HTTP-Anfrage enthält mindestens einen URI. Wenn ein Land daher versucht, den Zugriff nicht auf die gesamte Website, sondern auf eine bestimmte Seite einzuschränken, ist dies für https-Websites nicht möglich.

Schritt #2 – verschlüsselte Antwort.
Der Webserver liefert eine Antwort, die auch unterwegs gut gelesen werden kann.
Die Lösung ist äußerst einfach: Der Browser generiert lokal für jede https-Site dasselbe private-öffentliche Schlüsselpaar.
Und zusammen mit der Anfrage nach dem öffentlichen Schlüssel der Site sendet es seinen lokalen öffentlichen Schlüssel.
Der Webserver merkt sich diesen und verschlüsselt ihn beim Senden einer HTTP-Antwort mit dem öffentlichen Schlüssel eines bestimmten Clients.
Jetzt kann die http-Antwort nur vom Besitzer des privaten Browserschlüssels des Clients (d. h. vom Client selbst) entschlüsselt werden.

Schritt Nr. 3 – Aufbau einer sicheren Verbindung über einen öffentlichen Kanal.
In Beispiel Nr. 2 gibt es eine Schwachstelle: Nichts hindert Gratulanten daran, eine http-Anfrage abzufangen und Informationen über den öffentlichen Schlüssel zu bearbeiten.
Somit sieht der Vermittler den gesamten Inhalt gesendeter und empfangener Nachrichten klar und deutlich, bis sich der Kommunikationskanal ändert.
Der Umgang damit ist äußerst einfach: Senden Sie einfach den öffentlichen Schlüssel des Browsers als Nachricht, die mit dem öffentlichen Schlüssel des Webservers verschlüsselt ist.
Der Webserver sendet dann zunächst eine Antwort wie „Ihr öffentlicher Schlüssel ist so“ und verschlüsselt diese Nachricht mit demselben öffentlichen Schlüssel.
Der Browser schaut sich die Antwort an – wenn die Meldung „Ihr öffentlicher Schlüssel ist so“ empfangen wird, ist dies eine 100-prozentige Garantie dafür, dass dieser Kommunikationskanal sicher ist.
Wie sicher ist es?
Die Erstellung eines solchen sicheren Kommunikationskanals erfolgt mit einer Ping-Geschwindigkeit*2. Zum Beispiel 20ms.
Der Angreifer muss im Voraus über den privaten Schlüssel einer der Parteien verfügen. Oder finden Sie in wenigen Millisekunden einen privaten Schlüssel.
Das Hacken eines modernen privaten Schlüssels wird auf einem Supercomputer Jahrzehnte dauern.

Schritt #4 – öffentliche Datenbank mit öffentlichen Schlüsseln.
Offensichtlich besteht in dieser ganzen Geschichte die Möglichkeit für einen Angreifer, auf dem Kommunikationskanal zwischen dem Client und dem Server zu sitzen.
Der Client kann vorgeben, der Server zu sein, und der Server kann vorgeben, der Client zu sein. Und emulieren Sie ein Tastenpaar in beide Richtungen.
Dann sieht der Angreifer den gesamten Datenverkehr und kann ihn „bearbeiten“.
Ändern Sie beispielsweise die Adresse, an die Geld gesendet werden soll, kopieren Sie das Passwort aus dem Online-Banking oder blockieren Sie „anstößige“ Inhalte.
Um solche Angreifer zu bekämpfen, haben sie eine öffentliche Datenbank mit öffentlichen Schlüsseln für jede https-Site erstellt.
Jeder Browser „weiß“, dass etwa 200 solcher Datenbanken existieren. Dies ist in jedem Browser vorinstalliert.
„Wissen“ wird durch einen öffentlichen Schlüssel jedes Zertifikats gesichert. Das heißt, die Verbindung zu jeder einzelnen Zertifizierungsstelle kann nicht vorgetäuscht werden.

Jetzt gibt es ein einfaches Verständnis für die Verwendung von SSL für https.
Wenn Sie Ihr Gehirn einsetzen, wird Ihnen klar, wie die Sonderdienste etwas in dieser Struktur hacken können. Aber es wird sie ungeheure Anstrengungen kosten.
Und bei Organisationen, die kleiner sind als die NSA oder die CIA, ist es fast unmöglich, das bestehende Schutzniveau zu hacken, selbst für VIPs.

Ich werde auch etwas über SSH-Verbindungen hinzufügen. Es gibt dort keine öffentlichen Schlüssel. Was können Sie also tun? Das Problem wird auf zwei Arten gelöst.
Option ssh-by-password:
Bei der ersten Verbindung sollte der SSH-Client warnen, dass wir einen neuen öffentlichen Schlüssel vom SSH-Server haben.
Und wenn bei weiteren Verbindungen die Warnung „Neuer öffentlicher Schlüssel vom SSH-Server“ erscheint, bedeutet dies, dass versucht wird, Sie abzuhören.
Oder Sie wurden bei Ihrer ersten Verbindung belauscht, kommunizieren nun aber ohne Zwischenhändler mit dem Server.
Da die Tatsache des Abhörens einfach, schnell und mühelos aufgedeckt werden kann, wird dieser Angriff tatsächlich nur in besonderen Fällen für einen bestimmten Kunden eingesetzt.

Option ssh-by-key:
Wir nehmen ein Flash-Laufwerk und schreiben den privaten Schlüssel für den SSH-Server darauf (es gibt dafür Begriffe und viele wichtige Nuancen, aber ich schreibe ein Lehrprogramm, keine Gebrauchsanweisung).
Wir belassen den öffentlichen Schlüssel auf der Maschine, auf der sich der SSH-Client befindet, und halten ihn auch geheim.
Wir bringen das Flash-Laufwerk zum Server, stecken es ein, kopieren den privaten Schlüssel, verbrennen das Flash-Laufwerk und verstreuen die Asche in den Wind (oder formatieren es zumindest mit Nullen).
Das ist alles – nach einer solchen Operation wird es unmöglich sein, eine solche SSH-Verbindung zu hacken. Natürlich wird es in 10 Jahren möglich sein, den Verkehr auf einem Supercomputer anzuzeigen – aber das ist eine andere Geschichte.

Ich entschuldige mich für die offtopic.

Nun, da die Theorie bekannt ist. Ich erzähle Ihnen über den Ablauf der Erstellung eines SSL-Zertifikats.

Mit „openssl genrsa“ erstellen wir einen privaten Schlüssel und „Leerzeichen“ für den öffentlichen Schlüssel.
Wir schicken die „Rohlinge“ an ein Drittunternehmen, dem wir für das einfachste Zertifikat etwa 9 US-Dollar zahlen.

Nach ein paar Stunden erhalten wir von diesem Drittunternehmen unseren „öffentlichen“ Schlüssel und einen Satz mehrerer öffentlicher Schlüssel.

Warum ein Drittunternehmen für die Registrierung meines öffentlichen Schlüssels bezahlen sollte, ist eine separate Frage, auf die wir hier nicht eingehen.

Jetzt ist klar, was die Inschrift bedeutet:

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

Der Ordner „/etc/ssl“ enthält alle Dateien für SSL-Probleme.
domain1.com – Domänenname.
2018 ist das Jahr der Schlüsselschöpfung.
„Schlüssel“ – Angabe, dass es sich bei der Datei um einen privaten Schlüssel handelt.

Und die Bedeutung dieser Datei:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com – Domänenname.
2018 ist das Jahr der Schlüsselschöpfung.
verkettet – Angabe, dass es eine Kette öffentlicher Schlüssel gibt (der erste ist unser öffentlicher Schlüssel und der Rest stammt von der Firma, die den öffentlichen Schlüssel ausgegeben hat).
crt – Angabe, dass es ein fertiges Zertifikat gibt (öffentlicher Schlüssel mit technischen Erläuterungen).

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

Diese Einstellung wird in diesem Fall nicht verwendet, sondern ist beispielhaft geschrieben.

Denn ein Fehler in diesem Parameter führt dazu, dass von Ihrem Server (ohne Ihren Willen) Spam versendet wird.

Dann beweisen Sie allen, dass Sie nicht schuldig sind.

recipient_delimiter = +

Viele Leute wissen es vielleicht nicht, aber dies ist ein Standardzeichen für das Ranking von E-Mails und wird von den meisten modernen Mailservern unterstützt.

Wenn Sie beispielsweise ein Postfach haben „[E-Mail geschützt] „versuchen Sie es zu senden an“[E-Mail geschützt] „- schauen Sie, was dabei herauskommt.

inet_protocols = ipv4

Das könnte verwirrend sein.

Aber es ist nicht einfach so. Jede neue Domäne ist standardmäßig nur IPv4, dann schalte ich IPv6 für jede einzeln ein.

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

Hier geben wir an, dass alle eingehenden E-Mails an Dovecot gehen.
Und die Regeln für Domain, Postfach, Alias ​​– schauen Sie in der Datenbank nach.

/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

Jetzt weiß Postfix, dass E-Mails nur nach Autorisierung durch Dovecot zum weiteren Versand angenommen werden können.

Ich verstehe wirklich nicht, warum das hier wiederholt wird. In „virtual_transport“ haben wir bereits alles Notwendige spezifiziert.

Aber das Postfix-System ist sehr alt – wahrscheinlich ist es ein Rückfall aus alten Zeiten.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Dies kann für jeden Mailserver unterschiedlich konfiguriert werden.

Mir stehen 3 Mailserver zur Verfügung und diese Einstellungen sind aufgrund unterschiedlicher Nutzungsanforderungen sehr unterschiedlich.

Sie müssen es sorgfältig konfigurieren, da sonst Spam bei Ihnen eindringt oder, noch schlimmer, Spam von Ihnen ausgeht.

# SPF
policyd-spf_time_limit = 3600

Einrichten eines Plugins zur Überprüfung des SPF eingehender Briefe.

# 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

Die Einstellung ist, dass wir bei allen ausgehenden E-Mails eine DKIM-Signatur bereitstellen müssen.

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

Dies ist ein wichtiges Detail bei der Briefweiterleitung beim Versenden von Briefen aus PHP-Skripten.

Datei „/etc/postfix/sdd_transport.pcre“:

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

Auf der linken Seite stehen reguläre Ausdrücke. Auf der rechten Seite befindet sich ein Etikett, das den Buchstaben kennzeichnet.
Postfix entsprechend dem Etikett – berücksichtigt einige weitere Konfigurationszeilen für einen bestimmten Buchstaben.

Wie genau Postfix für einen bestimmten Buchstaben umkonfiguriert wird, wird in „master.cf“ angezeigt.

Die Zeilen 4, 5, 6 sind die wichtigsten. Im Namen der Domain, an die wir den Brief senden, setzen wir dieses Etikett.
Aber das Feld „von“ wird in PHP-Skripten im alten Code nicht immer angezeigt. Dann kommt der Benutzername zur Rettung.

Der Artikel ist bereits umfangreich – ich möchte nicht durch die Einrichtung von nginx+fpm abgelenkt werden.

Kurz gesagt, wir legen für jede Site einen eigenen Linux-Benutzerbesitzer fest. Und dementsprechend Ihr FPM-Pool.

Fpm-pool verwendet jede PHP-Version (es ist großartig, wenn Sie auf demselben Server problemlos verschiedene PHP-Versionen und sogar unterschiedliche php.ini für benachbarte Sites verwenden können).

Ein bestimmter Linux-Benutzer „www-domain2“ hat also eine Website namens domain2.com. Diese Site verfügt über einen Code zum Senden von E-Mails ohne Angabe des Absenderfelds.

Auch in diesem Fall werden die Briefe also korrekt versendet und landen nie im Spam.

Meine „/etc/postfix/master.cf“ sieht so aus:

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

Die Datei wird nicht vollständig bereitgestellt, sie ist bereits sehr groß.
Ich habe nur notiert, was geändert wurde.

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}

Dies sind Einstellungen im Zusammenhang mit Spamassasin, dazu später mehr.

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

Wir ermöglichen Ihnen die Verbindung zum Mailserver über Port 587.
Dazu müssen Sie sich anmelden.

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

Aktivieren Sie die SPF-Prüfung.

apt-get install postfix-policyd-spf-python

Lassen Sie uns das Paket für SPF-Prüfungen oben installieren.

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

Und das ist das Interessanteste. Dies ist die Möglichkeit, Briefe für eine bestimmte Domain von einer bestimmten IPv4/IPv6-Adresse aus zu versenden.

Dies geschieht im Interesse von rDNS. rDNS ist der Prozess des Empfangens einer Zeichenfolge anhand der IP-Adresse.
Und bei E-Mails wird diese Funktion verwendet, um zu bestätigen, dass der Helo genau mit dem rDNS der Adresse übereinstimmt, von der die E-Mail gesendet wurde.

Wenn das Helo nicht mit der E-Mail-Domain übereinstimmt, in deren Namen der Brief gesendet wurde, werden Spam-Punkte vergeben.

Helo stimmt nicht mit rDNS überein – es werden viele Spam-Punkte vergeben.
Dementsprechend muss jede Domain über eine eigene IP-Adresse verfügen.
Für OVH ist es in der Konsole möglich, rDNS anzugeben.
Für tech.ru wird das Problem durch den Support gelöst.
Für AWS wird das Problem durch den Support gelöst.
„inet_protocols“ und „smtp_bind_address6“ – wir aktivieren die IPv6-Unterstützung.
Für IPv6 müssen Sie außerdem rDNS registrieren.
„syslog_name“ – und dies dient dem einfacheren Lesen von Protokollen.

Kaufen Sie Zertifikate Ich empfehle hier.

Postfix+Dovecot-Link hier einrichten.

Lichtschutzfaktor einstellen.

============= Taubenschlag =============

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

MySQL einrichten, die Pakete selbst installieren.

Datei „/etc/dovecot/conf.d/10-auth.conf“

disable_plaintext_auth = yes
auth_mechanisms = plain login

Die Autorisierung erfolgt ausschließlich verschlüsselt.

Datei „/etc/dovecot/conf.d/10-mail.conf“

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

Hier geben wir den Aufbewahrungsort für die Briefe an.

Ich möchte, dass sie in Dateien gespeichert und nach Domäne gruppiert werden.

Datei „/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 {
  }
}

Dies ist die Hauptkonfigurationsdatei für Dovecot.
Hier deaktivieren wir ungesicherte Verbindungen.
Und ermöglichen Sie sichere Verbindungen.

Datei „/etc/dovecot/conf.d/10-ssl.conf“

ssl = required
ssl_cert = </etc/nginx/ssl/domain1.com.2018.chained.crt
ssl_key = </etc/nginx/ssl/domain1.com.2018.key
local XX.XX.XX.X5 {
  ssl_cert = </etc/nginx/ssl/domain2.com.2018.chained.crt
  ssl_key =  </etc/nginx/ssl/domain2.com.2018.key
}

SSL einrichten. Wir weisen darauf hin, dass SSL erforderlich ist.
Und das Zertifikat selbst. Und ein wichtiges Detail ist die „lokale“ Richtlinie. Gibt an, welches SSL-Zertifikat beim Herstellen einer Verbindung zu welchem ​​lokalen IPv4 verwendet werden soll.

IPv6 ist hier übrigens nicht konfiguriert, ich werde dieses Versäumnis später korrigieren.
XX.XX.XX.X5 (Domäne2) – kein Zertifikat. Um Clients zu verbinden, müssen Sie domain1.com angeben.
XX.XX.XX.X2 (Domäne3) – es gibt ein Zertifikat, Sie können domain1.com oder domain3.com angeben, um Clients zu verbinden.

Datei „/etc/dovecot/conf.d/15-lda.conf“

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Dies wird in Zukunft für Spamassassin benötigt.

Datei „/etc/dovecot/conf.d/20-imap.conf“

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Dies ist ein Antispam-Plugin. Wird zum Trainieren von Spamassasin zum Zeitpunkt der Übertragung in/aus dem „Spam“-Ordner benötigt.

Datei „/etc/dovecot/conf.d/20-pop3.conf“

protocol pop3 {
}

Es gibt genau so eine Datei.

Datei „/etc/dovecot/conf.d/20-lmtp.conf“

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

lmtp einrichten.

Datei „/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
}

Spamassasin-Trainingseinstellungen zum Zeitpunkt der Übertragung in den/aus dem Spam-Ordner.

Datei „/etc/dovecot/conf.d/90-sieve.conf“

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

Eine Datei, die angibt, was mit eingehenden Briefen geschehen soll.

Datei „/var/lib/dovecot/sieve/default.sieve“

require ["fileinto", "mailbox"];

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

Sie müssen die Datei „sievec default.sieve“ kompilieren.

Datei „/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
}

Angeben von SQL-Dateien zur Autorisierung.
Und die Datei selbst wird als Autorisierungsmethode verwendet.

Datei „/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';

Dies entspricht ähnlichen Einstellungen für Postfix.

Datei „/etc/dovecot/dovecot.conf“

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

Hauptkonfigurationsdatei.
Wichtig ist, dass wir hier angeben – Protokolle hinzufügen.

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

apt-get install spamassassin spamc

Lassen Sie uns die Pakete installieren.

adduser spamd --disabled-login

Fügen wir einen Benutzer hinzu, in dessen Namen.

systemctl enable spamassassin.service

Wir aktivieren den automatisch ladenden Spamassassin-Dienst beim Laden.

Datei „/etc/default/spamassassin“:

CRON=1

Indem Sie die automatische Aktualisierung von Regeln „standardmäßig“ aktivieren.

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

Sie müssen in MySQL eine Datenbank „sa“ mit dem Benutzer „sa“ und dem Passwort „password“ erstellen (durch etwas Passendes ersetzen).

report_safe – Dies sendet einen Bericht über Spam-E-Mails anstelle eines Briefes.
use_bayes sind Spamassassin-Einstellungen für maschinelles Lernen.

Die übrigen Spamassassin-Einstellungen wurden weiter oben in diesem Artikel verwendet.

Allgemeine Einstellung „Spamassassin“.
Informationen zum Verschieben neuer Spam-E-Mails in den IMAP-Ordner „Spam“..
Über eine einfache Kombination aus Dovecot + SpamAssassin.
Ich empfehle, beim Verschieben von Briefen in IMAP-Ordnern die Spamassasin-Lerntheorie zu lesen (und ich empfehle nicht, sie zu verwenden)..

============= Appell an die Community =============

Ich möchte auch gerne eine Idee in die Community einbringen, wie man die Sicherheit weitergeleiteter Briefe erhöhen kann. Da ich so tief in das Thema Post vertieft bin.

Damit der Benutzer auf seinem Client (Outlook, Thunderbird, Browser-Plugin, ...) ein Schlüsselpaar erstellen kann. Öffentlich und privat. Öffentlich – an DNS senden. Privat – beim Kunden sparen. Mailserver könnten einen öffentlichen Schlüssel verwenden, um an einen bestimmten Empfänger zu senden.

Und um sich vor Spam mit solchen Briefen zu schützen (ja, der Mailserver kann den Inhalt nicht sehen) müssen Sie drei Regeln einführen:

  1. Obligatorische echte DKIM-Signatur, obligatorischer SPF, obligatorischer rDNS.
  2. Ein neuronales Netzwerk zum Thema Antispam-Training + eine Datenbank dafür auf Client-Seite.
  3. Der Verschlüsselungsalgorithmus muss so beschaffen sein, dass die sendende Seite 100-mal mehr CPU-Leistung für die Verschlüsselung aufwenden muss als die empfangende Seite.

Entwickeln Sie zusätzlich zu öffentlichen Briefen einen Standard-Vorschlagsbrief, „um eine sichere Korrespondenz zu beginnen“. Einer der Benutzer (Postfach) sendet einen Brief mit Anhang an ein anderes Postfach. Der Brief enthält einen Textvorschlag zur Einrichtung eines sicheren Kommunikationskanals für die Korrespondenz und den öffentlichen Schlüssel des Besitzers des Postfachs (mit einem privaten Schlüssel auf der Clientseite).

Sie können sogar ein paar Schlüssel speziell für jede Korrespondenz erstellen. Der Empfängerbenutzer kann dieses Angebot annehmen und seinen öffentlichen Schlüssel (ebenfalls speziell für diese Korrespondenz erstellt) senden. Als nächstes sendet der erste Benutzer einen Dienstkontrollbrief (verschlüsselt mit dem öffentlichen Schlüssel des zweiten Benutzers) – nach Erhalt kann der zweite Benutzer den gebildeten Kommunikationskanal als zuverlässig betrachten. Als nächstes sendet der zweite Nutzer einen Kontrollbrief – und dann kann auch der erste Nutzer den gebildeten Kanal als sicher betrachten.

Um das Abfangen von Schlüsseln im Straßenverkehr zu bekämpfen, muss das Protokoll die Möglichkeit vorsehen, mindestens einen öffentlichen Schlüssel über ein Flash-Laufwerk zu übertragen.

Und das Wichtigste ist, dass alles funktioniert (die Frage ist: „Wer soll das bezahlen?“):
Geben Sie Postzertifikate ab 10 $ für 3 Jahre ein. Dadurch kann der Absender im DNS angeben, dass „meine öffentlichen Schlüssel dort drüben sind“. Und sie geben Ihnen die Möglichkeit, eine sichere Verbindung herzustellen. Gleichzeitig ist die Annahme solcher Verbindungen kostenlos.
Gmail monetarisiert endlich seine Nutzer. Für 10 $ pro 3 Jahre – das Recht, sichere Korrespondenzkanäle einzurichten.

============= Fazit =============

Um den gesamten Artikel zu testen, wollte ich einen Monat lang einen dedizierten Server mieten und eine Domain mit SSL-Zertifikat kaufen.

Aber die Lebensumstände entwickelten sich so, dass sich dieses Problem über zwei Monate hinzog.
Und so beschloss ich, als ich wieder freie Zeit hatte, den Artikel so zu veröffentlichen, wie er ist, anstatt zu riskieren, dass sich die Veröffentlichung noch ein weiteres Jahr hinziehen würde.

Wenn es viele Fragen gibt wie „Aber das ist nicht ausführlich genug beschrieben“, dann wird es wahrscheinlich sinnvoll sein, einen dedizierten Server mit einer neuen Domain und einem neuen SSL-Zertifikat zu nehmen und ihn noch detaillierter und genauer zu beschreiben Wichtig ist, alle fehlenden wichtigen Details zu identifizieren.

Ich würde auch gerne Feedback zu Ideen zu Postzertifikaten erhalten. Wenn Ihnen die Idee gefällt, werde ich versuchen, die Kraft aufzubringen, einen Entwurf für RFC zu schreiben.

Wenn Sie große Teile eines Artikels kopieren, geben Sie einen Link zu diesem Artikel an.
Geben Sie bei der Übersetzung in eine andere Sprache einen Link zu diesem Artikel an.
Ich werde versuchen, es selbst ins Englische zu übersetzen und Querverweise zu hinterlassen.


Source: habr.com

Kommentar hinzufügen