Dieser Artikel handelt davon, wie man einen modernen Mailserver einrichtet.
Postfix + Dovecot. SPF + DKIM + rDNS. Mit IPv6.
Mit TSL-Verschlüsselung. Mit Unterstützung für mehrere Domains – Teil mit echtem SSL-Zertifikat.
Mit Antispam-Schutz und hoher Antispam-Bewertung bei anderen Mailservern.
Mit Unterstützung für mehrere physische Schnittstellen.
Mit OpenVPN, dessen Verbindung über IPv4 erfolgt und das IPv6 bereitstellt.
Wenn Sie all diese Technologien nicht lernen möchten, aber einen solchen Server einrichten wollen – dann ist dieser Artikel für Sie.
Der Artikel enthält keine Versuche, jedes Detail zu erklären. Die Erklärungen beziehen sich darauf, was nicht standardmäßig eingerichtet ist oder aus Sicht des Verbrauchers wichtig ist.
Die Motivation, einen Mailserver einzurichten, ist ein lange gehegter Traum von mir. Vielleicht klingt das lächerlich, aber IMHO ist es viel besser, als von einem neuen Auto meiner Lieblingsmarke zu träumen.
Die Motivation, IPv6 einzurichten, hat zwei Gründe. IT-Profis müssen ständig neue Technologien lernen, um zu überleben. Ich möchte meinen bescheidenen Beitrag im Kampf gegen Zensur leisten.
Die Motivation zur Einrichtung von OpenVPN – nur damit IPv6 auf der lokalen Maschine funktioniert.
Die Motivation, mehrere physische Schnittstellen einzurichten – ich habe auf dem Server eine Schnittstelle "langsam, aber unbegrenzt" und eine andere "schnell, aber mit Tarif".
Die Motivation, Bind einzurichten – mein Provider stellt einen instabilen DNS-Server zur Verfügung, und Google hat auch manchmal Ausfälle. Ich möchte einen stabilen DNS-Server für den persönlichen Gebrauch.
Die Motivation, einen Artikel zu schreiben – der Entwurf wurde vor 10 Monaten verfasst, und ich habe ihn bereits zweimal angesehen. Wenn der Autor das regelmäßig braucht, ist die Wahrscheinlichkeit groß, dass auch anderen dies notwendig ist.
Es gibt keine universelle Lösung für Mailserver. Aber ich werde versuchen, so etwas wie "machen Sie es so und dann, wenn alles funktioniert, wie es sollte – werfen Sie das Überflüssige weg" zu schreiben.
Es gibt einen Colocation-Server bei der Firma tech.ru. Es ist möglich, mit OVH, Hetzner, AWS zu vergleichen. Für diese Aufgabe wird die Zusammenarbeit mit tech.ru viel effizienter sein.
Auf dem Server ist Debian 9 installiert.
Der Server hat 2 Schnittstellen `eno1` und `eno2`. Die erste ist unbegrenzt, die zweite 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`.
Es gibt XXXX:XXXX:XXXX:XXXX::/64 Pool von IPv6-Adressen, die der Schnittstelle `eno1` zugewiesen sind, und auf meine Anfrage hin wurde XXXX:XXXX:XXXX:XXXX:1:2::/96 zu `eno2` zugewiesen.
Es gibt 3 Domains `domain1.com`, `domain2.com`, `domain3.com`. Für `domain1.com` und `domain3.com` gibt es ein SSL-Zertifikat.
Es gibt ein Google-Konto, an das ich das Postfach `vasya.pupkin@domain1.com` (zum Empfangen und Senden von E-Mails direkt aus der Gmail-Oberfläche) anbinden möchte.
Es muss ein Postfach `support@domain2.com` eingerichtet werden, von dem ich eine Kopie der E-Mails in meinem Gmail-Postfach sehen möchte. Und ich sollte selten die Möglichkeit haben, etwas im Namen von `support@domain2.com` über die Web-Oberfläche zu senden.
Es muss ein Postfach `ivanov@domain3.com` eingerichtet werden, das von Ivanov auf seinem iPhone genutzt wird.
Die gesendeten E-Mails müssen allen modernen Anforderungen an Antispam entsprechen.
Es muss das höchste Maß an Verschlüsselung vorgesehen sein, das in öffentlichen Netzwerken verfügbar ist.
Es muss IPv6-Unterstützung sowohl für das Senden als auch für das Empfangen von E-Mails geben.
Es muss SpamAssassin vorhanden sein, der niemals E-Mails löschen wird, sondern entweder zurückwerfen oder durchlassen oder in den IMAP-Ordner „Spam“ verschieben wird.
Es muss ein automatisches Lernen von SpamAssassin eingerichtet werden: Wenn ich eine E-Mail in den Ordner „Spam“ verschiebe, soll er daraus lernen; wenn ich eine E-Mail aus dem Ordner „Spam“ verschiebe, soll er auch daraus lernen. Die Lernergebnisse von SpamAssassin sollen die Wahrscheinlichkeit beeinflussen, dass eine E-Mail im Ordner „Spam“ landet.
PHP-Skripte müssen in der Lage sein, E-Mails im Namen einer beliebigen Domain auf diesem Server zu senden.
Es muss einen OpenVPN-Dienst mit der Möglichkeit geben, IPv6 auf einem Client zu nutzen, der kein IPv6 hat.
Zuerst müssen die Schnittstellen und das Routing, einschließlich IPv6, eingerichtet werden.
Dann muss OpenVPN eingerichtet werden, das sich über IPv4 verbindet und dem Client eine statische, reale IPv6-Adresse bereitstellt. Dieser Client hat Zugang zu allen IPv6-Diensten auf dem Server und Zugriff auf alle Ressourcen im Internet mit IPv6.
Dann muss Postfix zum Senden von E-Mails + SPF + DKIM + rDNS und andere ähnliche Dinge eingerichtet werden.
Dann muss Dovecot eingerichtet und Multidomain konfiguriert werden.
Dann muss SpamAssassin eingerichtet und das Lernen konfiguriert werden.
Zum Schluss muss Bind installiert werden.
============= Multi-interfaces =============
Für die Konfiguration der Schnittstellen muss Folgendes in „/etc/network/interfaces“ geschrieben werden.
# 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::/80Diese Einstellungen können auf jedem Server in tech.ru angewendet werden (mit kleiner Abstimmung mit dem Support) und es wird sofort wie gewünscht funktionieren.
Wenn Sie Erfahrung mit der Konfiguration ähnlicher Dinge für Hetzner, OVH haben – dort ist es anders. Komplizierter.
eno1 – das ist der Name der Netzwerkkarte #1 (langsam, aber unbegrenzt).
eno2 – das ist der Name der Netzwerkkarte #2 (schnell, aber kostenpflichtig).
tun0 – das 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 geht von außen über eno1.
XXXX:XXXX:XXXX:XXXX::1 – IPv6 Gateway (es ist erwähnenswert, dass dies anders gemacht werden kann/sollte. Die IPv6 des Switches anzugeben).
dns-nameservers – angegeben sind 127.0.0.1 (da local bind installiert ist) und 213.248.1.6 (das ist von tech.ru).
„table eno1t“ und „table eno2t“ – der Sinn dieser route-rule ist, dass der Verkehr, der über eno1 hereinkommt, auch darüber hinausgeht, und der Verkehr, der über eno2 hereinkommt, auch darüber hinausgeht. Außerdem sollten Verbindungen, die vom Server initiiert werden, über eno1 gehen.
ip route add default via XX.XX.XX.1 table eno1tMit diesem Befehl geben wir an, dass jeglicher unbekannter Verkehr, der unter eine Regel fällt, die mit „table eno1t“ gekennzeichnet ist, an das Interface eno1 weitergeleitet werden soll.
ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1tMit diesem Befehl geben wir an, dass jeglicher serverinitiierten Verkehr an das Interface eno1 weitergeleitet wird.
ip rule add table eno1t from XX.XX.XX.X0
ip rule add table eno1t to XX.XX.XX.X0Mit diesem Befehl geben wir die Regeln zur Markierung des Verkehrs an.
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.X2Dieser Block legt die zweite IPv4-Adresse für das Interface eno1 fest.
ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t Mit diesem Befehl geben wir die Route von OpenVPN-Klienten zu den lokalen IPv4-Adressen, außer XX.XX.XX.X0, an.
Warum dieser Befehl für alle IPv4 ausreichend ist, verstehe ich bis heute nicht.
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
gateway XXXX:XXXX:XXXX:XXXX::1Hier geben wir die Adresse für die Schnittstelle selbst an. Der Server wird sie als „ausgehende“ Adresse verwenden. Ansonsten wird sie nicht weiter genutzt.
Warum „:1:1::“ so kompliziert angegeben ist? Damit OpenVPN richtig funktioniert und nur dafür. Darüber später mehr.
Zum Thema Gateway – so funktioniert es und damit gut. Aber richtig müsste hier die IPv6 des Switches angegeben werden, an den der Server angeschlossen ist.
Warum IPv6 jedoch nicht mehr funktioniert, wenn ich es so mache, ist mir ein Rätsel. Wahrscheinlich sind das Probleme von tech.ru.
ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACEDies ist das Hinzufügen einer IPv6-Adresse zur Schnittstelle. Wenn man einhundert Adressen benötigt, bedeutet das einhundert Zeilen in dieser Datei.
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::/80Ich habe die Adressen und Subnetze aller Schnittstellen markiert, um es übersichtlich zu machen.
eno1 muss unbedingt "/64" sein, denn das ist unser gesamter Pool von Adressen.
tun0 muss unbedingt ein größeres Subnetz als eno1 haben. Andernfalls kann das IPv6-Gateway für OpenVPN-Kunden nicht eingerichtet werden.
eno2 muss unbedingt ein größeres Subnetz als tun0 haben. Andernfalls können OpenVPN-Kunden nicht auf die lokalen IPv6-Adressen zugreifen.
Zur besseren Übersicht habe ich einen Subnetz-Schritt von 16 gewählt, aber wenn gewünscht, kann man sogar einen Schritt von "1" machen.
Entsprechend 64+16 = 80 und 80+16 = 96.Zur noch besseren Veranschaulichung:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY – das sind Adressen, die bestimmten Websites oder Diensten an der Schnittstelle eno1 zugewiesen werden sollen.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY – das sind Adressen, die bestimmten Websites oder Diensten an der Schnittstelle eno2 zugewiesen werden sollen.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY – das sind Adressen, die OpenVPN-Kunden zugewiesen werden sollen oder als Dienstadressen für OpenVPN verwendet werden.
Für die Netzwerkkonfiguration muss der Server neu gestartet werden können.
IPv4-Änderungen werden beim Ausführen übernommen (unbedingt in screen einwickeln – andernfalls wird diese Befehlszeile einfach das Netzwerk auf dem Server zum Absturz bringen):
/etc/init.d/networking restartAm Ende der Datei "/etc/iproute2/rt_tables" hinzufügen:
100 eno1t
101 eno2t Ohne dies kann man keine benutzerdefinierten Tabellen in der Datei "/etc/network/interfaces" verwenden.
Die Zahlen müssen eindeutig und kleiner als 65535 sein.
IPv6-Änderungen können leicht ohne Neustart vorgenommen werden, dafür muss man aber mindestens drei Befehle lernen:
ip -6 addr ...
ip -6 route ...
ip -6 neigh ...Konfiguration von "/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 = 1Das sind die "sysctl"-Einstellungen meines Servers. Ich werde das Wichtige hervorheben.
net.ipv4.ip_forward = 1Ohne dies wird OpenVPN überhaupt nicht funktionieren.
net.ipv6.ip_nonlocal_bind = 1Jeder, der versucht, IPv6 zu binden (zum Beispiel nginx), erhält sofort einen Fehler, wenn die Schnittstelle aktiviert wurde – dass die Adresse nicht verfügbar ist.
Um diese Situation zu vermeiden, wird diese Einstellung vorgenommen.
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1Ohne diese Einstellungen kann der IPv6-Verkehr vom OpenVPN-Kunden nicht in die Welt gelangen.
Andere Einstellungen beziehen sich entweder nicht darauf oder ich erinnere mich nicht, warum sie nötig sind.
Aber ich lasse es zur Sicherheit "wie es ist".
Um sicherzustellen, dass die Änderungen dieser Datei ohne einen Server-Neustart übernommen werden, muss der Befehl ausgeführt werden:
sysctl -pMehr Details zu den "tabellen"-Regeln:
============= OpenVPN =============
OpenVPN IPv4 funktioniert nicht ohne iptables.
Ich habe solche iptables für 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 ist meine statische IPv4-Adresse des lokalen Rechners.
10.8.0.0/24 ist das IPv4-Netzwerk von openvpn. IPv4-Adressen für openvpn-Clients.
Die Reihenfolge 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 DROPDiese Einschränkung stellt sicher, dass nur ich von meiner statischen IP auf OpenVPN zugreifen kann.
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
-- oder --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADEUm IPv4-Pakete zwischen OpenVPN-Clients und dem Internet weiterzuleiten, muss einer dieser Befehle eingegeben werden.
Für verschiedene Fälle ist eine der Optionen nicht geeignet.
In meinem Fall sind beide Befehle geeignet.
Nach dem Lesen der Dokumentation habe ich die erste Option gewählt, da sie weniger CPU-Ressourcen benötigt.
Um alle iptables-Einstellungen nach einem Neustart zu übernehmen, müssen sie irgendwo gespeichert werden.
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6Diese Namen sind nicht zufällig gewählt. Sie werden vom Paket „iptables-persistent“ verwendet.
apt-get install iptables-persistentInstallation des Hauptpakets OpenVPN:
apt-get install openvpn easy-rsaLassen Sie uns eine Vorlage für die Zertifikate einrichten (setzen Sie Ihre Werte ein):
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
ln -s openssl-1.0.0.cnf openssl.cnfLassen Sie uns die Einstellungen der Zertifikatvorlage bearbeiten:
mcedit vars...
# Dies sind die Standardwerte für die Felder
# die im Zertifikat platziert werden.
# Lassen Sie keines dieser Felder leer.
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Eigentum"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"
# X509 Subject Field
export KEY_NAME="server"
...Wir erstellen ein Serverzertifikat:
cd ~/openvpn-ca
source vars
./clean-all
./build-ca
./build-key-server server
./build-dh
openvpn --genkey --secret keys/ta.keyBereiten wir die Möglichkeit vor, endgültige „client-name.opvn“-Dateien 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-CBCBereiten wir ein Skript vor, das alle Dateien zu einer einzigen opvn-Datei zusammenschnürt.
mcedit ~/client-configs/make_config.sh
chmod 700 ~/client-configs/make_config.sh#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG}
<(echo -e '<ca>')
${KEY_DIR}/ca.crt
<(echo -e '</ca>n<cert>')
${KEY_DIR}/${1}.crt
<(echo -e '</cert>n<key>')
${KEY_DIR}/${1}.key
<(echo -e '</key>n<tls-auth>')
${KEY_DIR}/ta.key
<(echo -e '</tls-auth>')
> ${OUTPUT_DIR}/${1}.ovpnWir erstellen den ersten OpenVPN-Client:
cd ~/openvpn-ca
source vars
./build-key client-name
cd ~/client-configs
./make_config.sh client-nameDie Datei «~\/client-configs\/files\/client-name.ovpn» wird an das Gerät des Kunden gesendet.
Für iOS-Kunden muss ein Trick gemacht werden:
Der Inhalt des Tags «tls-auth» sollte ohne Kommentare sein.
Und außerdem «key-direction 1» sofort vor dem Tag «tls-auth» setzen.
Lass uns die Konfiguration des OpenVPN-Servers einstellen:
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-CBCDas ist nötig, um jedem Kunden eine statische Adresse zuzuweisen (nicht zwingend, aber ich verwende es):
# Client config dir
client-config-dir /etc/openvpn/ccdDas ist das komplizierteste und wichtigste Detail.
Leider kann OpenVPN noch nicht automatisch eine IPv6-Gateway für die Kunden einrichten.
Man muss das „manuell“ für jeden Kunden 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"Die 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 eno1Die 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 eno1Beide Skripte verwenden die Datei «\/etc\/openvpn\/variables»:
# Subnet
prefix=XXXX:XXXX:XXXX:XXXX:2:
# netmask
prefixlen=112Warum hier so geschrieben ist — kann ich mich nicht erinnern.
Jetzt sieht es seltsam aus, netmask = 112 (hier sollte 96 sein).
Und das Präfix ist seltsam, entspricht nicht dem Netzwerk tun0.
Aber gut, ich lasse es „wie es ist“.
cipher DES-EDE3-CBCDas ist Geschmackssache — ich habe diesen Verschlüsselungsweg gewählt.
============= Postfix =============
Installation des Hauptpakets:
apt-get install postfixBei der Installation „internet-site“ auswählen.
Meine «\/etc\/postfix\/main.cf» sieht so aus:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = nein
# Das Anhängen von .domain liegt in der Verantwortung des MUA.
append_dot_mydomain = nein
readme_directory = nein
# Siehe http://www.postfix.org/COMPATIBILITY_README.html -- standardmäßig 2 bei
# frischen Installationen.
compatibility_level = 2
# TLS-Parameter
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
smtpd_use_tls=ja
smtpd_tls_auth_only = ja
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1
smtp_tls_security_level = kann
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
# Speichertyp
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-Einstellungen
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = ja
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-Adresse pro Domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreBetrachten wir die Einzelheiten dieses Konfigs.
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.keyLaut den Hubversern enthält dieser Block `Desinformation und falsche Thesen`.Erst acht Jahre nach Beginn meiner Karriere begann ich zu verstehen, wie SSL funktioniert.
Deshalb werde ich es mir erlauben, zu beschreiben, wie man SSL verwendet (ohne die Fragen «Wie funktioniert das?» und «Warum funktioniert das?» zu beantworten).
Die Basis der modernen Verschlüsselung ist die Erstellung eines Schlüsselpaares (zwei sehr lange Zeichenfolgen).
Einer ist der „private“ Schlüssel, der andere der „öffentliche“ Schlüssel. Den privaten Schlüssel bewahren wir sehr sorgfältig geheim. Den öffentlichen Schlüssel geben wir allen Interessierten weiter.
Mit dem öffentlichen Schlüssel kann man eine Textzeile so verschlüsseln, dass nur der Besitzer des privaten Schlüssels sie entschlüsseln kann.
Das ist also die Grundlage der Technologie.Schritt Nr. 1 — https Webseiten.
Der Browser erfährt beim Zugriff auf die Webseite vom Webserver, dass die Webseite https ist und fordert daher den öffentlichen Schlüssel an.
Der Webserver gibt den öffentlichen Schlüssel weiter. Der Browser verschlüsselt die http-Anfrage mit dem öffentlichen Schlüssel und sendet sie.
Den Inhalt der http-Anfrage kann nur der lesen, der den privaten Schlüssel hat, also nur der Server, an den die Anfrage gerichtet wird.
Die Http-Anfrage enthält mindestens eine URI. Daher ist es unmöglich, den Zugang in einem Land zu bestimmten Seiten für https-Seiten zu beschränken, wenn nicht die gesamte Website betroffen ist.Schritt Nr. 2 – die verschlüsselte Antwort.
Der Webserver gibt eine Antwort, die unterwegs leicht gelesen werden kann.
Die Lösung ist extrem einfach – der Browser bildet lokal ein solches Paar aus privatem und öffentlichem Schlüssel für jede https-Seite.
Und zusammen mit der Anfrage nach dem öffentlichen Schlüssel der Seite sendet er seinen lokalen öffentlichen Schlüssel.
Der Webserver merkt sich diesen und verschlüsselt bei der Sendung der http-Antwort mit diesem öffentlichen Schlüssel des spezifischen Clients.
Jetzt kann die http-Antwort nur vom Inhaber des privaten Schlüssels des Client-Browsers entschlüsselt werden (also vom Client selbst).Schritt Nr. 3 – die Einrichtung einer gesicherten Verbindung über einen öffentlichen Kanal.
Im Beispiel Nr. 2 gibt es eine Schwachstelle – nichts hindert Dritte daran, die http-Anfrage abzufangen und die Informationen über den öffentlichen Schlüssel zu ändern.
So kann der Mittelsmann den gesamten Inhalt der gesendeten und empfangenen Nachrichten sehen, solange der Kommunikationskanal nicht geändert wird.
Gegen dieses Problem ist es extrem einfach zu kämpfen – es reicht aus, den öffentlichen Schlüssel des Browsers als mit dem öffentlichen Schlüssel des Webservers verschlüsseltes Nachrichten zu senden.
Der Webserver sendet dann zunächst die Antwort in der Art: „Dein öffentlicher Schlüssel ist so und so“ und verschlüsselt diese Nachricht mit diesem öffentlichen Schlüssel.
Der Browser prüft die Antwort – wenn die Nachricht „Dein öffentlicher Schlüssel ist so und so“ eingetroffen ist, dann ist dies eine 100%ige Garantie, dass dieser Kommunikationskanal sicher ist.
Wie sicher ist er?
Die Erstellung eines solchen sicheren Kommunikationskanals erfolgt mit einer Geschwindigkeit von ping*2. Zum Beispiel 20 ms.
Ein Angreifer muss entweder im Voraus den privaten Schlüssel einer der Seiten besitzen oder den privaten Schlüssel innerhalb weniger Millisekunden erraten.
Das Knacken eines modernen privaten Schlüssels würde Jahrzehnte auf einem Supercomputer in Anspruch nehmen.Schritt Nr. 4 – öffentliche Datenbank der öffentlichen Schlüssel.
Es ist offensichtlich, dass in dieser ganzen Geschichte die Möglichkeit besteht, dass ein Angreifer zwischen dem Client und dem Server sitzt.
Die Möglichkeit, dass der Kunde sich als Server und der Server sich als Kunde ausgibt. Und ein Paar Schlüssel in beide Richtungen zu simulieren.
Dann wird der Angreifer den gesamten Datenverkehr sehen und die Möglichkeit haben, den Datenverkehr „nachzubearbeiten“.
Zum Beispiel die Adresse ändern, wohin man Geld sendet, oder das Passwort für das Online-Banking kopieren oder „unerwünschte“ Inhalte blockieren.
Um gegen solche Angreifer vorzugehen, wurden öffentliche Datenbanken mit öffentlichen Schlüsseln für jede HTTPS-Website geschaffen.
Jeder Browser „weiß“ von der Existenz von etwa 200 solchen Datenbanken. Das ist in jeden Browser eingebaut.
Das „Wissen“ wird durch den öffentlichen Schlüssel jedes Zertifikats unterstützt. Das bedeutet, dass eine Verbindung zu jedem bestimmten Zertifizierungszentrum nicht gefälscht werden kann.Jetzt gibt es ein einfaches Verständnis, wie man SSL für HTTPS nutzen kann.
Wenn man nachdenkt, wird klar, wie Geheimdienste in dieser Konstruktion etwas ausspionieren könnten. Aber das wird ihnen enorme Anstrengungen kosten.
Und für Organisationen ist es für NSA oder CIA praktisch unmöglich, das bestehende Schutzniveau selbst für VIPs zu hacken.Ich möchte auch etwas zu SSH-Verbindungen hinzufügen. Dort gibt es keine öffentlichen Schlüssel, was tun wir also? Die Frage wird auf zwei Arten gelöst.
SSH-Passwort-Option:
Beim ersten Verbindungsaufbau muss der SSH-Client warnen, dass hier ein neuer öffentlicher Schlüssel vom SSH-Server vorliegt.
Und bei weiteren Verbindungen wird die Warnung „neuer öffentlicher Schlüssel vom SSH-Server“ bedeuten, dass man abgehört wird.
Oder beim ersten Verbindungsaufbau wurde man abgehört, und jetzt kommuniziert man mit dem Server ohne Intermediäre.
Wirklich, weil das Abhören leicht, schnell und mühelos aufgedeckt wird, wird dieser Angriff nur in besonderen Fällen gegen einen bestimmten Kunden eingesetzt.SSH-Schlüssel-Option:
Wir nehmen einen USB-Stick, speichern den privaten Schlüssel für den SSH-Server darauf (es gibt dafür Begriffe und eine Menge wesentlicher Feinheiten, aber ich schreibe eine Einführung und keine Gebrauchsanweisung).
Den öffentlichen Schlüssel lassen wir auf der Maschine, wo der SSH-Client sein wird, und halten ihn ebenfalls geheim.
Wir bringen den USB-Stick zum Server, stecken ihn ein, kopieren den privaten Schlüssel und verbrennen den Stick und verstreuen die Asche im Wind (oder formatieren ihn zumindest mit Nullen).
Das ist alles — nach einer solchen Operation wird es unmöglich sein, eine solche SSH-Verbindung zu knacken. Natürlich kann man in etwa 10 Jahren auf einem Supercomputer den Verkehr ansehen — aber das ist eine andere Geschichte.Ich entschuldige mich für den Offtopic.
Also, jetzt, wo die Theorie bekannt ist. Ich werde über den Prozess der Erstellung eines SSL-Zertifikats sprechen.
Mit "openssl genrsa" erstellen wir den privaten Schlüssel und "Vorlagen" für den öffentlichen Schlüssel.
"Vorlagen" senden wir an eine externe Firma, der wir etwa 9 $ für das einfachste Zertifikat zahlen.
Nach ein paar Stunden erhalten wir von dieser externen Firma unseren "öffentlichen" Schlüssel und noch eine Reihe weiterer öffentlicher Schlüssel.
Warum eine externe Firma für die Ausstellung meines öffentlichen Schlüssels zu zahlen ist — das ist eine separate Frage, die wir hier nicht betrachten werden.
Jetzt ist klar, was der Sinn der Aufschrift ist:
smtpd_tls_key_file=\/etc\/ssl\/domain1.com.2018.key Im Ordner "/etc/ssl" befinden sich alle Dateien für SSL-Angelegenheiten.
domain1.com — Name der Domain.
2018 — Jahr der Erstellung der Schlüssel.
"key" — Bezeichnung, dass die Datei den privaten Schlüssel enthält.
Und der Sinn dieser Datei ist:
smtpd_tls_cert_file=\/etc\/ssl\/domain1.com.2018.chained.crt
domain1.com — Name der Domain.
2018 — Jahr der Erstellung der Schlüssel.
chained — Bezeichnung, dass hier eine Kette von öffentlichen Schlüsseln ist (der erste — unser öffentlicher Schlüssel und die anderen — was von der Firma kam, die den öffentlichen Schlüssel ausgestellt hat).
crt — Bezeichnung, dass hier das fertige Zertifikat ist (öffentlicher Schlüssel mit technischen Erläuterungen).
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1Diese Einstellung wird in diesem Fall nicht verwendet, ist aber als Beispiel angegeben.
Denn ein Fehler in diesem Parameter würde dazu führen, dass Ihr Server Spam verschickt (ohne Ihr Einverständnis).
Danach beweisen Sie allen, dass Sie unschuldig sind.
recipient_delimiter = +Vielleicht wissen viele das nicht, aber das ist das Standardsymbol für die Klassifizierung von E-Mails, und dies wird von den meisten modernen Mailservern unterstützt.
Wenn Sie beispielsweise einen E-Mail-Account "username@gmail.com" haben, versuchen Sie, an "username+spam@gmail.com" zu senden — sehen Sie, was dabei herauskommt.
inet_protocols = ipv4Das könnte verwirrend sein.
Aber das ist nicht ohne Grund. Jede neue Domain hat standardmäßig nur IPv4, später aktiviere ich IPv6 für jede einzeln.
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 legen wir fest, dass alle eingehenden E-Mails an Dovecot gesendet werden.
Die Regeln für Domain, Mailbox und Alias müssen in der Datenbank betrachtet werden.
/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 = yesJetzt weiß Postfix, dass E-Mails nur mit Authentifizierung über Dovecot akzeptiert werden können.
Ich verstehe wirklich nicht ganz, warum das hier doppelt angegeben werden muss. Wir haben doch bereits in „virtual_transport“ alles Wichtige angegeben.
Aber Postfix ist ein sehr altes System – wahrscheinlich sind das Überbleibsel aus alten Zeiten.
smtpd_recipient_restrictions =
...
smtpd_helo_restrictions =
...
smtpd_client_restrictions =
...Das ist für jeden Mailserver individuell einzustellen.
Ich habe drei Mailserver zur Verfügung, und diese Einstellungen sind aufgrund der unterschiedlichen Anforderungen sehr unterschiedlich.
Die Konfiguration muss sorgfältig vorgenommen werden – andernfalls wird Spam zu Ihnen kommen oder, noch schlimmer, Spam wird von Ihnen ausgehen.
# SPF
policyd-spf_time_limit = 3600Einstellung für ein Plugin zur Überprüfung von SPF für eingehende E-Mails.
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sockEinstellung, dass alle ausgehenden E-Mails mit einer DKIM-Signatur versehen werden müssen.
# IP address per domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreDies ist ein entscheidendes Detail bei der Routing von E-Mails, wenn sie von PHP-Skripten versendet werden.
Datei „/etc/postfix/sdd_transport.pcre“:
/^www-domain1@domain1.com$/ domain1:
/^www-domain2@domain1.com$/ domain2:
/^www-domain3@domain1.com$/ domain3:
/@domain1.com$/ domain1:
/@domain2.com$/ domain2:
/@domain3.com$/ domain3:Links – reguläre Ausdrücke. Rechts – das Label, mit dem die E-Mail markiert wird.
Postfix berücksichtigt je nach Label noch einige weitere Konfigurationszeilen für die spezifische E-Mail.Wie genau Postfix für eine spezifische E-Mail neu konfiguriert wird, wird in „master.cf“ angegeben.
Die Zeilen 4, 5, 6 sind entscheidend. In welchem Namen wir die E-Mail versenden, setzen wir das entsprechende Label.
Aber nicht immer wird im PHP-Skript im alten Code das Feld „from“ angegeben. Dann kommt der Benutzername ins Spiel.Der Artikel ist ohnehin schon umfangreich – ich möchte mich nicht mit der Konfiguration von nginx+fpm ablenken.
Kurz gesagt – für jede Website bestimmen wir einen eigenen Linux-Benutzer als Eigentümer. Entsprechend auch einen eigenen fpm-Pool.
Der fpm-Pool kann jede PHP-Version verwenden (das ist großartig, wenn auf einem Server ohne Probleme für benachbarte Websites unterschiedliche PHP-Versionen und sogar unterschiedliche php.ini verwendet werden können).
Der spezifische Linux-Benutzer „www-domain2“ hat die Website domain2.com. Auf dieser Website gibt es einen Code zum Versenden von E-Mails ohne Angabe des „from“-Feldes.
Selbst in einem solchen Fall werden die E-Mails korrekt versendet und landen niemals im Spam.
Mein „/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 ist nicht vollständig - sie ist ohnehin schon sehr groß.
Ich habe nur das markiert, 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 die mit Spamassassin verbundenen Einstellungen, 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 erlauben die Verbindung zum Mailserver über Port 587.
Dazu ist eine Authentifizierung erforderlich.
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spfWir aktivieren die SPF-Überprüfung.
apt-get install postfix-policyd-spf-pythonWir installieren das Paket für SPF-Überprüfungen.
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-domain1Und das ist das interessanteste. Dies ist die Möglichkeit, E-Mails für eine bestimmte Domain von einer bestimmten IPv4/IPv6-Adresse zu senden.
Das geschieht wegen rDNS. rDNS - das Abrufen einer bestimmten Zeichenfolge über die IP-Adresse.
Und für E-Mails wird diese Möglichkeit verwendet, um zu bestätigen, dass helo tatsächlich mit rDNS der Adresse übereinstimmt, von der die E-Mail gesendet wurde.Wenn helo nicht mit der Domain der E-Mail übereinstimmt, von der die E-Mail gesendet wurde, werden Spam-Punkte vergeben.
Helo stimmt nicht mit rDNS überein - es werden viele Spam-Punkte vergeben.
Daher sollte jede Domain ihre eigene IP-Adresse haben.
Für OVH gibt es im Control Panel die Möglichkeit, rDNS anzugeben.
Für tech.ru wird das Problem über den Support gelöst.
Für AWS wird das Problem auch über den Support gelöst.
«inet_protocols» und «smtp_bind_address6» – hier aktivieren wir die Unterstützung von IPv6.
Für IPv6 muss ebenfalls rDNS konfiguriert werden.
«syslog_name» – das dient zur besseren Lesbarkeit der Protokolle.
Zertifikate kaufen .
.
============= Dovecot =============
apt-get install dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql dovecot-antispamMySQL einrichten, wir installieren die Pakete selbst.
Datei «/etc/dovecot/conf.d/10-auth.conf»
disable_plaintext_auth = yes
auth_mechanisms = plain loginAuthentifizierung nur in verschlüsselter Form.
Datei «/etc/dovecot/conf.d/10-mail.conf»
mail_location = maildir:/var/mail/vhosts/%d/%nHier geben wir den Speicherort der E-Mails an.
Ich möchte, dass sie in Dateien gespeichert werden und nach Domains gruppiert sind.
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 {
}
} Das ist die Hauptkonfigurationsdatei von dovecot.
Hier deaktivieren wir ungesicherte Verbindungen.
Und aktivieren gesicherte 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
}Wir konfigurieren ssl. Wir geben an, dass ssl erforderlich ist.
Und das Zertifikat selbst. Und ein wichtiger Punkt – die Direktive «local». Sie gibt an, welches ssl-Zertifikat bei einer Verbindung zu welcher lokalen IPv4 verwendet werden soll.Übrigens, IPv6 ist hier nicht konfiguriert, ich werde dieses Versäumnis später beheben.
XX.XX.XX.X5 (domain2) – kein Zertifikat. Für die Kundenverbindungen muss domain1.com angegeben werden.
XX.XX.XX.X2 (domain3) – es gibt ein Zertifikat, für die Kundenverbindungen kann domain1.com oder domain3.com angegeben werden.
Datei «/etc/dovecot/conf.d/15-lda.conf»
protocol lda {
mail_plugins = $mail_plugins sieve
}Das wird später für spamassassin benötigt.
Datei «/etc/dovecot/conf.d/20-imap.conf»
protocol imap {
mail_plugins = $mail_plugins antispam
}Das ist das Antispam-Plugin. Es wird benötigt, um spamassassin beim Verschieben in/von dem „Spam“-Ordner zu trainieren.
Datei «/etc/dovecot/conf.d/20-pop3.conf»
protocol pop3 {
}Einfach eine solche Datei existiert.
Datei «/etc/dovecot/conf.d/20-lmtp.conf»
protocol lmtp {
mail_plugins = $mail_plugins sieve
postmaster_address = admin@domain1.com
}Konfiguration von lmtp.
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
}Einstellungen für das Training von SpamAssassin beim Verschieben in/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
}Datei, in der angegeben wird, was mit eingehenden E-Mails zu tun ist.
Datei „/var/lib/dovecot/sieve/default.sieve“
require ["fileinto", "mailbox"];
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Spam";
}Die Datei muss kompiliert werden: „sievec default.sieve“.
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
} Angabe der SQL-Dateien zur Authentifizierung.
Und die Datei selbst — als Methode zur Authentifizierung.
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 den entsprechenden Einstellungen für Postfix.
Datei „/etc/dovecot/dovecot.conf“
protocols = imap lmtp pop3
listen = *, ::
dict {
}
!include conf.d/*.conf
!include_try local.conf Die Hauptkonfigurationsdatei.
Wichtig ist, dass wir hier die Protokolle angeben/hinzufügen.
============= SpamAssassin =============
apt-get install spamassassin spamcWir installieren die Pakete.
adduser spamd --disabled-loginWir fügen den Benutzer hinzu, unter dessen Namen.
systemctl enable spamassassin.serviceWir aktivieren die Auto-Start-Funktion des SpamAssassin-Dienstes beim Booten.
Datei „/etc/default/spamassassin“:
CRON=1Aktiviert die automatische Aktualisierung der „Standard“-Regeln.
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 passwordEs ist notwendig, eine MySQL-Datenbank „sa“ mit dem Benutzer „sa“ und dem Passwort „password“ (durch etwas Angemessenes ersetzen) zu erstellen.
report_safe bedeutet, dass anstelle einer E-Mail ein Bericht über die Spam-E-Mail gesendet wird.
use_bayes sind die Einstellungen für das maschinelle Lernen von SpamAssassin.
Die übrigen Einstellungen für SpamAssassin wurden zuvor im Artikel angewendet.
.
.
.
.
============= Kontakt zur Gemeinschaft =============
Ich würde gerne eine Idee in die Gemeinschaft einbringen, wie man das Sicherheitsniveau beim Versenden von E-Mails erhöhen kann. Da ich mich so tief mit dem Thema E-Mail beschäftigt habe.
Damit der Benutzer auf seinem Client (Outlook, Thunderbird, Browser-Plugin, …) ein Paar Schlüssel erstellen kann. Ein öffentlicher und ein privater. Der öffentliche – wird im DNS gesendet. Der private – bleibt auf dem Client. Die Mailserver sollten in der Lage sein, den öffentlichen Schlüssel für den Versand an einen bestimmten Empfänger zu verwenden.
Und um sich vor Spam bei solchen E-Mails zu schützen (ja, der Mailserver kann den Inhalt nicht einsehen) – müssen drei Regeln eingeführt werden:
- Verpflichtende echte DKIM-Signatur, verpflichtender SPF, verpflichtendes rDNS.
- Ein neuronales Netzwerk zum Thema Spam-Filterung + eine Datenbank dazu auf der Client-Seite.
- Der Verschlüsselungsalgorithmus sollte so sein, dass die sendende Seite 100 Mal mehr CPU-Ressourcen für die Verschlüsselung aufbringen muss als die empfangende Seite.
Neben öffentlichen E-Mails – einen Standard für ein Angebotsmail „geschützte Kommunikation beginnen“ entwickeln. Ein Benutzer (E-Mail-Postfach) sendet einem anderen Postfach eine E-Mail mit einem Anhang. In der E-Mail steht der Vorschlag, einen geschützten Kommunikationskanal für den Austausch einzurichten, sowie der öffentliche Schlüssel des Postfachinhabers (während der private Schlüssel auf der Client-Seite bleibt).
Man könnte sogar Paare von Schlüsseln speziell für jede Korrespondenz erstellen. Der Empfangsbenutzer kann dieses Angebot annehmen und seinen öffentlichen Schlüssel (ebenfalls speziell für diese Korrespondenz erstellt) senden. Danach sendet der erste Benutzer ein Kontrollmail (verschlüsselt mit dem öffentlichen Schlüssel des zweiten Benutzers) – bei dessen Erhalt kann der zweite Benutzer den eingerichteten Kommunikationskanal als zuverlässig ansehen. Danach sendet der zweite Benutzer ein Kontrollmail – und dann kann auch der erste Benutzer den eingerichteten Kanal als geschützt betrachten.
Um der Abfangung von Schlüsseln auf dem Weg entgegenzuwirken – muss im Protokoll die Möglichkeit berücksichtigt werden, mindestens einen öffentlichen Schlüssel über einen USB-Stick zu übertragen.
Und das Wichtigste – damit das alles funktioniert (Frage: „Wer bezahlt dafür?“):
Eingeben von E-Mail-Zertifikaten ab 10 $ für 3 Jahre. Diese ermöglichen es dem Absender, im DNS anzugeben, dass „meine öffentlichen Schlüssel dort sind“. Und sie geben die Möglichkeit, eine sichere Verbindung aufzubauen. Dabei sind solche Verbindungen kostenlos.
Gmail monetarisiert endlich seine Benutzer. Für 10 $ in 3 Jahren – das Recht, geschützte Kommunikationskanäle zu erstellen.
============= Fazit =============
Zur Testung des gesamten Artikels wollte ich einen dedizierten Server für einen Monat mieten und eine Domain mit SSL-Zertifikat kaufen.
Doch die Lebensumstände haben dazu geführt, dass sich diese Frage auf 2 Monate zog.
Und jetzt, als wieder freie Zeit verfügbar war, habe ich beschlossen, den Artikel so zu veröffentlichen, wie er ist, anstatt das Risiko einzugehen, dass die Veröffentlichung sich um ein weiteres Jahr verzögert.
Wenn genug Fragen auftauchen, wie „Hier ist nicht ausreichend detailliert beschrieben“ – dann werden wahrscheinlich die Ressourcen gefunden, einen dedizierten Server mit einer neuen Domain und einem neuen SSL-Zertifikat zu mieten und noch detaillierter zu beschreiben sowie alle wichtigen Details zu erkennen, die möglicherweise übersehen wurden.
Ich würde auch gerne Feedback zur Idee von E-Mail-Zertifikaten erhalten. Wenn die Idee gefällt, werde ich versuchen, die Ressourcen zu finden, um einen Entwurf für die RFC zu schreiben.
Beim Kopieren großer Teile des Artikels – bitte auf diesen Artikel verweisen.
Bei der Übersetzung in eine andere Sprache – bitte auf diesen Artikel verweisen.
Ich werde versuchen, den Artikel selbst ins Englische zu übersetzen und Querverweise zu hinterlassen.
Quelle: habr.com
