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

Dit artikel gaat over het opzetten van een moderne mailserver.
Postfix + Duiventil. SPF + DKIM + rDNS. Met IPv6.
Met TSL-codering. Met ondersteuning voor meerdere domeinen - deels met een echt SSL-certificaat.
Met antispambescherming en een hoge antispambeoordeling van andere mailservers.
Ondersteunt meerdere fysieke interfaces.
Bij OpenVPN loopt de verbinding via IPv4 en biedt IPv6.

Als je niet al deze technologieën wilt leren, maar zo’n server wilt opzetten, dan is dit artikel iets voor jou.

Het artikel doet geen poging om elk detail uit te leggen. De uitleg gaat naar wat niet standaard is geconfigureerd of belangrijk is vanuit het oogpunt van de consument.

De motivatie om een ​​mailserver op te zetten is al lang een droom van mij. Dit klinkt misschien stom, maar IMHO is het veel beter dan dromen van een nieuwe auto van je favoriete merk.

Er zijn twee redenen om IPv6 in te voeren. Een IT-specialist moet voortdurend nieuwe technologieën leren om te kunnen overleven. Ik wil graag mijn bescheiden bijdrage leveren aan de strijd tegen censuur.

De motivatie voor het opzetten van OpenVPN is alleen maar om IPv6 op de lokale machine te laten werken.
De motivatie voor het opzetten van verschillende fysieke interfaces is dat ik op mijn server één interface heb “langzaam maar onbeperkt” en een andere “snel maar met een tarief”.

De motivatie voor het instellen van Bind-instellingen is dat mijn ISP een onstabiele DNS-server biedt, en Google faalt soms ook. Ik wil een stabiele DNS-server voor persoonlijk gebruik.

Motivatie om een ​​artikel te schrijven - Ik heb 10 maanden geleden een concept geschreven en ik heb er al twee keer naar gekeken. Zelfs als de auteur het regelmatig nodig heeft, is de kans groot dat anderen het ook nodig zullen hebben.

Er bestaat geen universele oplossing voor een mailserver. Maar ik zal proberen iets te schrijven als ‘doe dit en als alles naar behoren werkt, gooi dan de extra dingen weg.’

Het bedrijf tech.ru heeft een colocatieserver. Het is mogelijk om te vergelijken met OVH, Hetzner, AWS. Om dit probleem op te lossen zal de samenwerking met tech.ru veel effectiever zijn.

Debian 9 is op de server geïnstalleerd.

De server heeft 2 interfaces `eno1` en `eno2`. De eerste is respectievelijk onbeperkt en de tweede is snel.

Er zijn 3 statische IP-adressen, XX.XX.XX.X0 en XX.XX.XX.X1 en XX.XX.XX.X2 op de `eno1`-interface en XX.XX.XX.X5 op de `eno2`-interface .

Beschikbaar XXXX:XXXX:XXXX:XXXX::/64 een pool van IPv6-adressen die zijn toegewezen aan de `eno1`-interface en van daaruit werd XXXX:XXXX:XXXX:XXXX:1:2::/96 op mijn verzoek toegewezen aan `eno2`.

Er zijn 3 domeinen `domein1.com`, `domein2.com`, `domein3.com`. Er is een SSL-certificaat voor `domein1.com` en `domein3.com`.

Ik heb een Google-account waaraan ik mijn mailbox wil koppelen[e-mail beveiligd]` (e-mail ontvangen en rechtstreeks verzenden vanuit de Gmail-interface).
Er moet een brievenbus aanwezig zijn[e-mail beveiligd]`, een kopie van de e-mail die ik in mijn Gmail wil zien. En het komt zelden voor dat je iets kunt sturen namens `[e-mail beveiligd]` via de webinterface.

Er moet een brievenbus aanwezig zijn[e-mail beveiligd]`, die Ivanov vanaf zijn iPhone zal gebruiken.

Verzonden e-mails moeten voldoen aan alle moderne antispamvereisten.
In openbare netwerken moet het hoogste niveau van versleuteling aanwezig zijn.
Er moet IPv6-ondersteuning zijn voor zowel het verzenden als ontvangen van brieven.
Er zou een SpamAssassin moeten zijn die nooit e-mails verwijdert. En het zal ofwel stuiteren, overslaan of naar de IMAP-map "Spam" sturen.
Het automatisch leren van SpamAssassin moet worden geconfigureerd: als ik een brief naar de map Spam verplaats, leert hij hiervan; als ik een brief uit de map Spam verplaats, leert hij hiervan. De resultaten van de SpamAssassin-training moeten van invloed zijn op de vraag of de brief in de map Spam terechtkomt.
PHP-scripts moeten e-mail kunnen verzenden namens elk domein op een bepaalde server.
Er zou een openvpn-service moeten zijn, met de mogelijkheid om IPv6 te gebruiken op een client die geen IPv6 heeft.

Eerst moet u de interfaces en routing configureren, inclusief IPv6.
Vervolgens moet u OpenVPN configureren, dat verbinding maakt via IPv4 en de client een statisch-echt IPv6-adres geeft. Deze client heeft toegang tot alle IPv6-services op de server en toegang tot alle IPv6-bronnen op internet.
Vervolgens moet u Postfix configureren om brieven + SPF + DKIM + rDNS en andere soortgelijke kleine dingen te verzenden.
Vervolgens moet u Dovecot en Multidomain configureren.
Vervolgens moet u SpamAssassin configureren en training configureren.
Installeer ten slotte Bind.

============= Meerdere interfaces =============

Om interfaces te configureren, moet u dit schrijven in “/etc/network/interfaces”.

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eno1
iface eno1 inet static
        address XX.XX.XX.X0/24
        gateway XX.XX.XX.1
        dns-nameservers 127.0.0.1 213.248.1.6
        post-up ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1t
        post-up ip route add default via XX.XX.XX.1 table eno1t
        post-up ip rule add table eno1t from XX.XX.XX.X0
        post-up ip rule add table eno1t to XX.XX.XX.X0

auto eno1:1
iface eno1:1 inet static
address XX.XX.XX.X1
netmask 255.255.255.0
        post-up ip rule add table eno1t from XX.XX.XX.X1
        post-up ip rule add table eno1t to XX.XX.XX.X1
        post-up   ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t
        post-down ip route del 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t

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

iface eno1 inet6 static
        address XXXX:XXXX:XXXX:XXXX:1:1::/64
        gateway XXXX:XXXX:XXXX:XXXX::1
        up   ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE
        up   ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:2/64 dev $IFACE
        down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACE
        down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:1:1:2/64 dev $IFACE

# The secondary network interface
allow-hotplug eno2
iface eno2 inet static
        address XX.XX.XX.X5
        netmask 255.255.255.0
        post-up   ip route add XX.XX.XX.0/24 dev eno2 src XX.XX.XX.X5 table eno2t
        post-up   ip route add default via XX.XX.XX.1 table eno2t
        post-up   ip rule add table eno2t from XX.XX.XX.X5
        post-up   ip rule add table eno2t to XX.XX.XX.X5
        post-up   ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X5 table eno2t
        post-down ip route del 10.8.0.0/24 dev tun0 src XX.XX.XX.X5 table eno2t

iface eno2 inet6 static
        address XXXX:XXXX:XXXX:XXXX:1:2::/96
        up   ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:2:1:1/64 dev $IFACE
        up   ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:2:1:2/64 dev $IFACE
        down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:2:1:1/64 dev $IFACE
        down ip -6 addr del XXXX:XXXX:XXXX:XXXX:1:2:1:2/64 dev $IFACE

# OpenVPN network
iface tun0 inet6 static
        address XXXX:XXXX:XXXX:XXXX:1:3::/80

Deze instellingen kunnen op elke server in tech.ru worden toegepast (met een beetje coördinatie met ondersteuning) en het zal onmiddellijk werken zoals het zou moeten.

Als je ervaring hebt met het opzetten van soortgelijke dingen voor Hetzner, OVH, dan is het daar anders. Moeilijker.

eno1 is de naam van netwerkkaart #1 (langzaam maar onbeperkt).
eno2 is de naam van netwerkkaart #2 (snel, maar met een tarief).
tun0 is de naam van de virtuele netwerkkaart van OpenVPN.
XX.XX.XX.X0 - IPv4 #1 op eno1.
XX.XX.XX.X1 - IPv4 #2 op eno1.
XX.XX.XX.X2 - IPv4 #3 op eno1.
XX.XX.XX.X5 - IPv4 #1 op eno2.
XX.XX.XX.1 - IPv4-gateway.
XXXX:XXXX:XXXX:XXXX::/64 - IPv6 voor de gehele server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 - IPv6 voor eno2, al het andere van buitenaf gaat naar eno1.
XXXX:XXXX:XXXX:XXXX::1 — IPv6-gateway (het is vermeldenswaard dat dit anders kan/moet worden gedaan. Specificeer de IPv6-switch).
dns-nameservers - 127.0.0.1 is aangegeven (omdat binding lokaal is geïnstalleerd) en 213.248.1.6 (dit is van tech.ru).

“table eno1t” en “table eno2t” - de betekenis van deze routeregels is dat verkeer dat binnenkomt via eno1 -> er doorheen zou vertrekken, en verkeer dat binnenkomt via eno2 -> er doorheen zou vertrekken. En ook verbindingen die door de server worden geïnitieerd, gaan via eno1.

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

Met dit commando specificeren we dat al het onbegrijpelijke verkeer dat valt onder een regel gemarkeerd met “table eno1t” -> naar de eno1-interface wordt gestuurd.

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

Met dit commando specificeren we dat al het verkeer dat door de server wordt geïnitieerd, naar de eno1-interface moet worden geleid.

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

Met dit commando stellen we de regels in voor het markeren van verkeer.

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

Dit blok specificeert een tweede IPv4 voor de eno1-interface.

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

Met dit commando stellen we de route in van OpenVPN-clients naar lokaal IPv4 behalve XX.XX.XX.X0.
Ik begrijp nog steeds niet waarom dit commando voldoende is voor alle IPv4.

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

Hier stellen we het adres voor de interface zelf in. De server zal het gebruiken als een “uitgaand” adres. Zal op geen enkele manier meer gebruikt worden.

Waarom is ":1:1::" zo ingewikkeld? Zodat OpenVPN correct werkt en alleen hiervoor. Hierover later meer.

Over het onderwerp gateway gesproken: zo werkt het en dat is prima. Maar de juiste manier is om hier het IPv6 aan te geven van de switch waarop de server is aangesloten.

Om de een of andere reden werkt IPv6 echter niet meer als ik dit doe. Dit is waarschijnlijk een soort tech.ru-probleem.

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

Hiermee wordt een IPv6-adres aan de interface toegevoegd. Als je honderd adressen nodig hebt, betekent dat honderd regels in dit bestand.

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

Ik heb de adressen en subnetten van alle interfaces genoteerd om het duidelijk te maken.
eno1 - moet zijn "/64" - omdat dit onze hele verzameling adressen is.
tun0 - het subnet moet groter zijn dan eno1. Anders is het niet mogelijk om een ​​IPv6-gateway voor OpenVPN-clients te configureren.
eno2 - het subnet moet groter zijn dan tun0. Anders hebben OpenVPN-clients geen toegang tot lokale IPv6-adressen.
Voor de duidelijkheid heb ik een subnetstap van 16 gekozen, maar als je wilt, kun je zelfs stap “1” doen.
Dienovereenkomstig is 64+16 = 80 en 80+16 = 96.

Voor nog meer duidelijkheid:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY zijn adressen die moeten worden toegewezen aan specifieke sites of services op de eno1-interface.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY zijn adressen die moeten worden toegewezen aan specifieke sites of services op de eno2-interface.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY zijn adressen die moeten worden toegewezen aan OpenVPN-clients of moeten worden gebruikt als OpenVPN-serviceadressen.

Om het netwerk te configureren, moet het mogelijk zijn om de server opnieuw op te starten.
IPv4-wijzigingen worden opgepikt wanneer ze worden uitgevoerd (zorg ervoor dat deze in het scherm worden weergegeven - anders crasht deze opdracht eenvoudigweg het netwerk op de server):

/etc/init.d/networking restart

Voeg aan het einde van het bestand “/etc/iproute2/rt_tables” toe:

100 eno1t
101 eno2t

Zonder dit kunt u geen aangepaste tabellen gebruiken in het bestand “/etc/network/interfaces”.
De nummers moeten uniek zijn en kleiner dan 65535.

IPv6-wijzigingen kunnen eenvoudig worden gewijzigd zonder opnieuw op te starten, maar om dit te doen moet u minstens drie opdrachten leren:

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

Instelling "/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

Dit zijn de "sysctl" -instellingen van mijn server. Laat mij op iets belangrijks wijzen.

net.ipv4.ip_forward = 1

Zonder dit zal OpenVPN helemaal niet werken.

net.ipv6.ip_nonlocal_bind = 1

Iedereen die IPv6 (bijvoorbeeld nginx) probeert te binden onmiddellijk nadat de interface is opgestart, krijgt een foutmelding. Dat dit adres niet beschikbaar is.

Om een ​​dergelijke situatie te voorkomen, wordt een dergelijke instelling gemaakt.

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

Zonder deze IPv6-instellingen gaat het verkeer van de OpenVPN-client niet de wereld in.

Andere instellingen zijn niet relevant of ik weet niet meer waarvoor ze dienen.
Maar voor het geval dat, laat ik het ‘zoals het is’.

Om wijzigingen in dit bestand op te halen zonder de server opnieuw op te starten, moet u de opdracht uitvoeren:

sysctl -p

Meer details over “tafel”-regels: habr.com/post/108690

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

OpenVPN IPv4 werkt niet zonder iptables.

Mijn iptables zijn als volgt voor 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 is mijn statische IPv4-adres van de lokale machine.
10.8.0.0/24 - IPv4 openvpn-netwerk. IPv4-adressen voor openvpn-clients.
De consistentie van de regels is belangrijk.

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

Dit is een beperking zodat alleen ik OpenVPN kan gebruiken vanaf mijn statische IP.

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

Om IPv4-pakketten door te sturen tussen OpenVPN-clients en internet, moet u een van deze opdrachten registreren.

Voor verschillende gevallen is een van de opties niet geschikt.
Beide commando's zijn geschikt voor mijn geval.
Na het lezen van de documentatie heb ik voor de eerste optie gekozen omdat deze minder CPU gebruikt.

Om ervoor te zorgen dat alle iptables-instellingen na het opnieuw opstarten worden opgehaald, moet u ze ergens opslaan.

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

Dergelijke namen zijn niet toevallig gekozen. Ze worden gebruikt door het pakket "iptables-persistent".

apt-get install iptables-persistent

Het hoofdpakket van OpenVPN installeren:

apt-get install openvpn easy-rsa

Laten we een sjabloon voor certificaten opzetten (vervang uw waarden):

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

Laten we de certificaatsjablooninstellingen bewerken:

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

Maak een servercertificaat:

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

Laten we de mogelijkheid voorbereiden om de laatste “client-name.opvn”-bestanden te maken:

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

Laten we een script voorbereiden dat alle bestanden samenvoegt tot één enkel opvn-bestand.

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

De eerste OpenVPN-client maken:

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

Het bestand “~/client-configs/files/client-name.ovpn” wordt naar het apparaat van de client verzonden.

Voor iOS-clients moet je de volgende truc doen:
De inhoud van de tag "tls-auth" moet zonder commentaar zijn.
En plaats ook “key-direction 1” onmiddellijk vóór de tag “tls-auth”.

Laten we de OpenVPN-serverconfiguratie configureren:

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

Dit is nodig om voor elke client een statisch adres in te stellen (niet nodig, maar ik gebruik het):

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

Het moeilijkste en belangrijkste detail.

Helaas weet OpenVPN nog niet hoe hij zelfstandig een IPv6-gateway voor klanten moet configureren.
Dit moet je per cliënt “handmatig” doorsturen.

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

Bestand “/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

Bestand “/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 scripts gebruiken het bestand “/etc/openvpn/variables”:

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

Ik vind het moeilijk om te onthouden waarom het zo is geschreven.

Nu ziet netmask = 112 er vreemd uit (daar zou het 96 moeten zijn).
En het voorvoegsel is vreemd, het komt niet overeen met het tun0-netwerk.
Maar goed, ik laat het zoals het is.

cipher DES-EDE3-CBC

Dit is niet voor iedereen weggelegd - ik heb voor deze methode gekozen om de verbinding te coderen.

Meer informatie over het instellen van OpenVPN IPv4.

Meer informatie over het instellen van OpenVPN IPv6.

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

Het hoofdpakket installeren:

apt-get install postfix

Selecteer tijdens de installatie “internetsite”.

Mijn "/etc/postfix/main.cf" ziet er als volgt uit:

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

Laten we eens kijken naar de details van deze configuratie.

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

Volgens inwoners van Khabrovsk bevat dit blok ‘verkeerde informatie en onjuiste stellingen’.Pas 8 jaar na het begin van mijn carrière begon ik te begrijpen hoe SSL werkt.

Daarom ben ik zo vrij om te beschrijven hoe SSL te gebruiken (zonder de vragen “Hoe werkt het?” en “Waarom werkt het?”) te beantwoorden.

De basis van moderne encryptie is het creëren van een sleutelpaar (twee zeer lange tekenreeksen).

De ene “sleutel” is privé, de andere sleutel is “openbaar”. Wij houden de privésleutel zeer zorgvuldig geheim. Wij distribueren de publieke sleutel aan iedereen.

Met een publieke sleutel kun je een tekstreeks versleutelen, zodat alleen de eigenaar van de privésleutel deze kan ontsleutelen.
Welnu, dat is de hele basis van de technologie.

Stap 1 - https-sites.
Bij het bezoeken van een site leert de browser van de webserver dat de site https is en vraagt ​​daarom om een ​​publieke sleutel.
De webserver geeft de publieke sleutel. De browser gebruikt de publieke sleutel om het http-verzoek te versleutelen en te versturen.
De inhoud van een http-verzoek kan alleen worden gelezen door degenen die over de privésleutel beschikken, dat wil zeggen alleen de server waarop het verzoek wordt gedaan.
Http-request bevat minimaal een URI. Als een land de toegang dus niet tot de hele site, maar tot een specifieke pagina probeert te beperken, is dit voor https-sites onmogelijk.

Stap #2 - gecodeerd antwoord.
De webserver zorgt voor een antwoord dat onderweg gemakkelijk te lezen is.
De oplossing is uiterst eenvoudig: de browser genereert lokaal hetzelfde privé-publieke sleutelpaar voor elke https-site.
En samen met het verzoek om de publieke sleutel van de site, wordt de lokale publieke sleutel verzonden.
De webserver onthoudt het en codeert het bij het verzenden van een http-respons met de publieke sleutel van een specifieke client.
Nu kan http-respons alleen worden gedecodeerd door de eigenaar van de privésleutel van de browser van de client (dat wil zeggen, de client zelf).

Stap nr. 3: een beveiligde verbinding tot stand brengen via een openbaar kanaal.
Er is een kwetsbaarheid in voorbeeld nr. 2: niets weerhoudt weldoeners ervan een http-verzoek te onderscheppen en informatie over de openbare sleutel te bewerken.
Zo zal de tussenpersoon duidelijk alle inhoud van verzonden en ontvangen berichten zien totdat het communicatiekanaal verandert.
Hiermee omgaan is uiterst eenvoudig: stuur gewoon de openbare sleutel van de browser als een bericht dat is gecodeerd met de openbare sleutel van de webserver.
De webserver stuurt dan eerst een reactie in de trant van “uw publieke sleutel is zo” en versleutelt dit bericht met dezelfde publieke sleutel.
De browser kijkt naar de reactie – als de melding “uw publieke sleutel is zo” wordt ontvangen – dan is dit een 100% garantie dat dit communicatiekanaal veilig is.
Hoe veilig is het?
Het creëren van een dergelijk veilig communicatiekanaal gebeurt met een snelheid van ping*2. Bijvoorbeeld 20 ms.
De aanvaller moet vooraf over de privésleutel van één van de partijen beschikken. Of vind binnen een paar milliseconden een privésleutel.
Het hacken van één moderne privésleutel zal tientallen jaren duren op een supercomputer.

Stap #4 - openbare database met openbare sleutels.
Het is duidelijk dat er in dit hele verhaal een mogelijkheid is voor een aanvaller om op het communicatiekanaal tussen de client en de server te zitten.
De client kan zich voordoen als de server en de server kan zich voordoen als de client. En emuleer een paar sleutels in beide richtingen.
Vervolgens ziet de aanvaller al het verkeer en kan hij het verkeer ‘bewerken’.
Wijzig bijvoorbeeld het adres waarnaar u geld wilt sturen, kopieer het wachtwoord van online bankieren of blokkeer ‘aanstootgevende’ inhoud.
Om dergelijke aanvallers te bestrijden, bedachten ze een openbare database met openbare sleutels voor elke https-site.
Elke browser “weet” van het bestaan ​​van ongeveer 200 van dergelijke databases. Dit is vooraf geïnstalleerd in elke browser.
“Kennis” wordt ondersteund door een publieke sleutel van elk certificaat. Dat wil zeggen dat de verbinding met elke specifieke certificeringsinstantie niet kan worden nagebootst.

Nu is er een eenvoudig begrip van hoe u SSL voor https kunt gebruiken.
Als je je hersenen gebruikt, wordt duidelijk hoe de speciale diensten iets in deze structuur kunnen hacken. Maar het zal hen monsterlijke inspanningen kosten.
En bij organisaties die kleiner zijn dan de NSA of CIA is het bijna onmogelijk om het bestaande beschermingsniveau te hacken, zelfs voor VIP's.

Ik zal ook iets toevoegen over ssh-verbindingen. Er zijn daar geen openbare sleutels, dus wat kunt u doen? Het probleem wordt op twee manieren opgelost.
Optie ssh-per-wachtwoord:
Tijdens de eerste verbinding moet de ssh-client waarschuwen dat we een nieuwe openbare sleutel van de ssh-server hebben.
En als tijdens verdere verbindingen de waarschuwing “nieuwe openbare sleutel van de ssh-server” verschijnt, betekent dit dat ze u proberen af ​​te luisteren.
Of u werd bij uw eerste verbinding afgeluisterd, maar communiceert nu zonder tussenpersonen met de server.
Omdat het feit van afluisteren gemakkelijk, snel en moeiteloos aan het licht komt, wordt deze aanval eigenlijk alleen in speciale gevallen voor een specifieke klant gebruikt.

Optie ssh-per-sleutel:
We nemen een flashdrive en schrijven er de privésleutel voor de ssh-server op (hier zijn voorwaarden en veel belangrijke nuances voor, maar ik schrijf een educatief programma, geen gebruiksinstructies).
We laten de publieke sleutel achter op de machine waarop de ssh-client komt te staan ​​en houden deze ook geheim.
We brengen de flashdrive naar de server, plaatsen deze, kopiëren de privésleutel en branden de flashdrive en verstrooien de as in de wind (of formatteren hem in ieder geval met nullen).
Dat is alles - na zo'n operatie zal het onmogelijk zijn om zo'n ssh-verbinding te hacken. Natuurlijk zal het over tien jaar mogelijk zijn om verkeer op een supercomputer te bekijken, maar dat is een ander verhaal.

Mijn excuses voor het offtopic.

Dus nu de theorie bekend is. Ik zal je vertellen over het proces van het maken van een SSL-certificaat.

Met behulp van “openssl genrsa” creëren we een privésleutel en “spaties” voor de publieke sleutel.
We sturen de ‘blanco’s’ naar een derde partij, aan wie we ongeveer $ 9 betalen voor het eenvoudigste certificaat.

Na een paar uur ontvangen we onze ‘openbare’ sleutel en een set van verschillende openbare sleutels van dit externe bedrijf.

Waarom zou een derde partij moeten betalen voor de registratie van mijn publieke sleutel is een aparte vraag, die we hier niet zullen behandelen.

Nu is het duidelijk wat de betekenis van de inscriptie is:

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

De map “/etc/ssl” bevat alle bestanden voor SSL-problemen.
domein1.com — domeinnaam.
2018 is het jaar van de sleutelcreatie.
"sleutel" - aanduiding dat het bestand een privésleutel is.

En de betekenis van dit bestand:

smtpd_tls_cert_file=/etc/ssl/domein1.com.2018.chained.crt
domein1.com — domeinnaam.
2018 is het jaar van de sleutelcreatie.
geketend - aanduiding dat er een keten van openbare sleutels is (de eerste is onze openbare sleutel en de rest is afkomstig van het bedrijf dat de openbare sleutel heeft uitgegeven).
crt - aanduiding dat er een kant-en-klaar certificaat is (openbare sleutel met technische uitleg).

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

Deze instelling wordt in dit geval niet gebruikt, maar is als voorbeeld geschreven.

Omdat een fout in deze parameter ertoe zal leiden dat spam vanaf uw server wordt verzonden (zonder uw wil).

Bewijs dan aan iedereen dat je niet schuldig bent.

recipient_delimiter = +

Veel mensen weten het misschien niet, maar dit is een standaardteken voor het rangschikken van e-mails en wordt ondersteund door de meeste moderne mailservers.

Als u bijvoorbeeld een mailbox heeft "[e-mail beveiligd]"probeer te verzenden naar"[e-mail beveiligd]"-kijk eens wat er van komt.

inet_protocols = ipv4

Dit kan verwarrend zijn.

Maar het is niet zomaar zo. Elk nieuw domein is standaard alleen IPv4, daarna schakel ik IPv6 voor elk domein afzonderlijk in.

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 specificeren we dat alle inkomende post naar de duiventil gaat.
En de regels voor domein, mailbox, alias - kijk in de database.

/etc/postfix/mysql-virtuele-mailbox-domeinen.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

Nu weet postfix dat post alleen na toestemming van de duiventil voor verdere verzending kan worden geaccepteerd.

Ik begrijp werkelijk niet waarom dit hier herhaald wordt. We hebben al alles gespecificeerd wat nodig is in “virtual_transport”.

Maar het postfix-systeem is erg oud - waarschijnlijk is het een terugkeer naar vroeger.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Dit kan per mailserver anders worden geconfigureerd.

Ik heb 3 mailservers tot mijn beschikking en deze instellingen zijn erg verschillend vanwege de verschillende gebruiksvereisten.

U moet het zorgvuldig configureren - anders stroomt er spam naar u toe, of erger nog - er stroomt spam van u uit.

# SPF
policyd-spf_time_limit = 3600

Instellen van een plug-in gerelateerd aan het controleren van de SPF van inkomende brieven.

# 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

De instelling is dat we bij alle uitgaande e-mails een DKIM-handtekening moeten voorzien.

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

Dit is een belangrijk detail bij het routeren van brieven bij het verzenden van brieven vanuit PHP-scripts.

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

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

Aan de linkerkant staan ​​reguliere expressies. Aan de rechterkant bevindt zich een label dat de letter markeert.
Postfix in overeenstemming met het label - houdt rekening met nog een paar configuratieregels voor een specifieke letter.

Hoe postfix precies opnieuw wordt geconfigureerd voor een specifieke letter, wordt aangegeven in “master.cf”.

Lijnen 4, 5, 6 zijn de belangrijkste. Namens welk domein wij de brief versturen, plaatsen wij dit label.
Maar het veld “van” wordt in PHP-scripts in de oude code niet altijd aangegeven. Dan komt de gebruikersnaam te hulp.

Het artikel is al uitgebreid - ik zou niet afgeleid willen worden door het instellen van nginx+fpm.

Kort gezegd stellen we voor elke site zijn eigen Linux-gebruikerseigenaar in. En dienovereenkomstig uw fpm-pool.

Fpm-pool gebruikt elke versie van php (het is geweldig als je op dezelfde server zonder problemen verschillende versies van php en zelfs verschillende php.ini voor aangrenzende sites kunt gebruiken).

Een specifieke Linux-gebruiker “www-domain2” heeft dus een website domain2.com. Deze site heeft een code voor het verzenden van e-mails zonder het veld 'van' op te geven.

Dus zelfs in dit geval worden de brieven correct verzonden en komen ze nooit in de spam terecht.

Mijn "/etc/postfix/master.cf" ziet er als volgt uit:

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

Het bestand wordt niet volledig verstrekt; het is al erg groot.
Ik heb alleen genoteerd wat er veranderd is.

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}

Dit zijn instellingen gerelateerd aan spamassasin, daarover later meer.

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

Wij staan ​​u toe verbinding te maken met de mailserver via poort 587.
Om dit te doen, moet u inloggen.

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

Schakel SPF-controle in.

apt-get install postfix-policyd-spf-python

Laten we het pakket voor SPF-controles hierboven installeren.

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

En dit is het meest interessante. Dit is de mogelijkheid om brieven voor een specifiek domein te verzenden vanaf een specifiek IPv4/IPv6-adres.

Dit wordt gedaan omwille van rDNS. rDNS is het proces waarbij een string wordt ontvangen op IP-adres.
En voor e-mail wordt deze functie gebruikt om te bevestigen dat de helo exact overeenkomt met de rDNS van het adres waarvandaan de e-mail is verzonden.

Als de helo niet overeenkomt met het e-maildomein namens wie de brief is verzonden, worden spampunten toegekend.

Helo komt niet overeen met rDNS - er worden veel spampunten toegekend.
Daarom moet elk domein een eigen IP-adres hebben.
Voor OVH - in de console is het mogelijk om rDNS op te geven.
Voor tech.ru wordt het probleem opgelost via ondersteuning.
Voor AWS wordt het probleem opgelost via ondersteuning.
“inet_protocols” en “smtp_bind_address6” - we schakelen IPv6-ondersteuning in.
Voor IPv6 moet u ook rDNS registreren.
“syslog_name” - en dit is voor het gemak van het lezen van logs.

Koop certificaten Ik raad het hier aan.

Stel hier de postfix+duiventillink in.

SPF instellen.

============= Duiventil =============

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

MySQL instellen, de pakketten zelf installeren.

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

disable_plaintext_auth = yes
auth_mechanisms = plain login

Autorisatie is alleen gecodeerd.

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

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

Hier geven wij de bewaarplaats voor de brieven aan.

Ik wil dat ze worden opgeslagen in bestanden en gegroepeerd op domein.

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

Dit is het belangrijkste configuratiebestand voor de duiventil.
Hier schakelen we onbeveiligde verbindingen uit.
En maak beveiligde verbindingen mogelijk.

Bestand "/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 instellen. Wij geven aan dat ssl vereist is.
En het certificaat zelf. En een belangrijk detail is de “lokale” richtlijn. Geeft aan welk SSL-certificaat moet worden gebruikt bij verbinding met welk lokaal IPv4.

Overigens is IPv6 hier niet geconfigureerd, ik zal deze omissie later corrigeren.
XX.XX.XX.X5 (domein2) - geen certificaat. Om clients te verbinden, moet u domein1.com opgeven.
XX.XX.XX.X2 (domein3) - er is een certificaat, u kunt domein1.com of domein3.com opgeven om clients te verbinden.

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

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Dit zal in de toekomst nodig zijn voor spamassassin.

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

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Dit is een antispam-plug-in. Nodig voor het trainen van spamassasin op het moment van overdracht van/naar de map “Spam”.

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

protocol pop3 {
}

Er is zo'n bestand.

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

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

LMTP instellen.

Bestand “/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-trainingsinstellingen op het moment van overdracht van/naar de map Spam.

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

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

Een bestand dat specificeert wat er met inkomende brieven moet gebeuren.

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

require ["fileinto", "mailbox"];

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

U moet het bestand compileren: “sievec default.sieve”.

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

SQL-bestanden opgeven voor autorisatie.
En het bestand zelf wordt gebruikt als autorisatiemethode.

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

Dit komt overeen met soortgelijke instellingen voor postfix.

Bestand "/etc/dovecot/dovecot.conf"

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

Hoofdconfiguratiebestand.
Het belangrijkste is dat we hier aangeven - protocollen toevoegen.

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

apt-get install spamassassin spamc

Laten we de pakketten installeren.

adduser spamd --disabled-login

Laten we een gebruiker toevoegen namens wie.

systemctl enable spamassassin.service

We schakelen de spamassassin-service automatisch in tijdens het laden.

Bestand "/etc/default/spamassassin":

CRON=1

Door het automatisch bijwerken van regels “standaard” in te schakelen.

Bestand “/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

U moet een database “sa” aanmaken in mysql met de gebruiker “sa” met het wachtwoord “password” (vervangen door iets adequaats).

report_safe - hiermee wordt een rapport van spam-e-mail verzonden in plaats van een brief.
use_bayes zijn spamassassin machine learning-instellingen.

De resterende spamassassin-instellingen zijn eerder in het artikel gebruikt.

Algemene instelling "spamassassin".
Over het verplaatsen van nieuwe spam-e-mails naar de IMAP-map “Spam”..
Over een simpele combinatie van Dovecot + SpamAssassin.
Ik raad aan om de spamassasin-leertheorie te lezen bij het verplaatsen van letters in imap-mappen (en ik raad het gebruik ervan niet aan).

============= Een beroep doen op de gemeenschap =============

Ik zou ook graag een idee in de gemeenschap willen gooien over hoe het beveiligingsniveau van doorgestuurde brieven kan worden verhoogd. Omdat ik zo diep verdiept ben in het onderwerp post.

Zodat de gebruiker een paar sleutels kan aanmaken op zijn client (outlook, Thunderbird, browser-plugin, ...). Publiek en prive. Openbaar - stuur naar DNS. Privé - bespaar op de client. Mailservers zouden een openbare sleutel kunnen gebruiken om naar een specifieke ontvanger te verzenden.

En om u met dergelijke brieven tegen spam te beschermen (ja, de mailserver kan de inhoud niet bekijken), moet u 3 regels invoeren:

  1. Verplichte echte DKIM-handtekening, verplichte SPF, verplichte rDNS.
  2. Neuraal netwerk op het gebied van antispamtraining + database daarvoor aan de clientzijde.
  3. Het versleutelingsalgoritme moet zodanig zijn dat de verzendende kant 100 keer meer CPU-vermogen aan versleuteling moet besteden dan de ontvangende kant.

Ontwikkel naast openbare brieven ook een standaardvoorstelbrief ‘om te beginnen met beveiligde correspondentie’. Eén van de gebruikers (mailbox) stuurt een brief met bijlage naar een andere mailbox. De brief bevat een tekstvoorstel om een ​​beveiligd communicatiekanaal voor correspondentie te starten en de publieke sleutel van de eigenaar van de mailbox (met een private sleutel aan de klantzijde).

U kunt zelfs voor elke correspondentie een paar sleutels maken. De ontvangende gebruiker kan dit aanbod accepteren en zijn publieke sleutel (ook speciaal voor deze correspondentie gemaakt) opsturen. Vervolgens verzendt de eerste gebruiker een servicecontrolebrief (gecodeerd met de publieke sleutel van de tweede gebruiker) - bij ontvangst hiervan kan de tweede gebruiker het gevormde communicatiekanaal als betrouwbaar beschouwen. Vervolgens stuurt de tweede gebruiker een controlebrief - en dan kan de eerste gebruiker het gevormde kanaal ook als veilig beschouwen.

Om het onderscheppen van sleutels onderweg tegen te gaan, moet het protocol voorzien in de mogelijkheid om minimaal één publieke sleutel via een flashdrive te verzenden.

En het allerbelangrijkste is dat het allemaal werkt (de vraag is “wie gaat dat betalen?”):
Voer postcertificaten in vanaf $ 10 voor 3 jaar. Hierdoor kan de afzender in de DNS aangeven dat “mijn publieke sleutels daar zijn.” En ze geven u de mogelijkheid om een ​​beveiligde verbinding tot stand te brengen. Tegelijkertijd is het accepteren van dergelijke verbindingen gratis.
Gmail genereert eindelijk inkomsten met zijn gebruikers. Voor $ 10 per 3 jaar - het recht om beveiligde correspondentiekanalen te creëren.

============= Conclusie =============

Om het hele artikel te testen, ging ik voor een maand een dedicated server huren en een domein kopen met een SSL-certificaat.

Maar de levensomstandigheden ontwikkelden zich, zodat deze kwestie twee maanden aanhield.
En dus besloot ik, toen ik weer vrije tijd had, het artikel te publiceren zoals het is, in plaats van het risico te lopen dat de publicatie nog een jaar zou aanslepen.

Als er nogal wat vragen zijn zoals “maar dit is niet voldoende gedetailleerd beschreven”, dan zal er waarschijnlijk kracht zijn om een ​​dedicated server met een nieuw domein en een nieuw SSL-certificaat te nemen en deze nog gedetailleerder te beschrijven en, de meeste Belangrijker nog: identificeer alle ontbrekende belangrijke details.

Ik zou ook graag feedback willen krijgen over ideeën over postcertificaten. Als het idee je bevalt, zal ik proberen de kracht te vinden om een ​​concept voor rfc te schrijven.

Wanneer u grote delen van een artikel kopieert, geef dan een link naar dit artikel op.
Wanneer u naar een andere taal vertaalt, geef dan een link naar dit artikel op.
Ik zal proberen het zelf in het Engels te vertalen en kruisverwijzingen achter te laten.


Bron: www.habr.com

Voeg een reactie