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

Tento článek se zabývá tím, jak nastavit moderní poštovní server.
Postfix + Dovecot. SPF + DKIM + rDNS. S IPv6.
Se šifrováním TSL. S podporou více domén — část s pravým SSL certifikátem.
S antispamovou ochranou a vysokým antispamovým hodnocením u jiných poštovních serverů.
S podporou více fyzických rozhraní.
S OpenVPN, připojením přes IPv4, které poskytuje IPv6.

Pokud nechcete studovat všechny tyto technologie, ale chcete nastavit takový server — pak je tento článek pro vás.

V článku chybí pokusy vysvětlit každý detail. Vysvětlení směřuje k tomu, co je nastaveno nestandardně nebo je důležité z pohledu uživatele.

Motivací nastavit poštovní server — můj dlouholetý sen. Možná to zní hloupě, ale IMHO, je to mnohem lepší, než snít o novém autě oblíbené značky.

Motivací nastavit IPv6 — dva důvody. IT specialisté se musí neustále učit nové technologie, aby přežili. Chci přispět svým skromným dílem k boji proti cenzuře.

Motivací pro nastavení OpenVPN — pouze pro to, aby IPv6 fungoval na místním zařízení.
Motivací k nastavení několika fyzických rozhraní — na mém serveru je jedno rozhraní "pomalé, ale neomezené", a druhé "rychlé, ale s tarifem".

Motivací k nastavení Bind — můj poskytovatel nabízí nestabilní DNS server a google také občas selhává. Chci stabilní DNS server pro osobní použití.

Motivací napsat článek — návrh byl sepsán před 10 měsíci a už jsem se do něj dvakrát podíval. Pokud to autor potřebuje pravidelně, je velká pravděpodobnost, že to bude potřeba i ostatním.

Neexistuje univerzální řešení pro poštovní server. Ale pokusím se napsat něco jako "udělejte to takto a potom, když to všechno bude fungovat, zbavte se nadbytečného".

Existuje server Colocation u společnosti tech.ru. Je možné porovnat s OVH, Hetzner, AWS. Pro řešení této úlohy by bylo mnohem efektivnější spolupráce právě s tech.ru.

Na serveru je nainstalován Debian 9.

Na serveru jsou 2 rozhraní `eno1` a `eno2`. První je neomezené, a druhé rychlé.

Jsou k dispozici 3 statické IP adresy, XX.XX.XX.X0, XX.XX.XX.X1 a XX.XX.XX.X2 na rozhraní `eno1` a XX.XX.XX.X5 na rozhraní `eno2`.

Je k dispozici XXXX:XXXX:XXXX:XXXX::/64 blok IPv6 adres, které jsou přiřazeny na rozhraní `eno1` a z něj XXXX:XXXX:XXXX:XXXX:1:2::/96 na `eno2` na mou žádost.

Máme 3 domény `domain1.com`, `domain2.com`, `domain3.com`. Pro `domain1.com` a `domain3.com` je k dispozici SSL certifikát.

Máme google účet, do kterého chceme připojit e-mailovou adresu `vasya.pupkin@domain1.com` (přijímání a odesílání e-mailů přímo z rozhraní gmailu).
Měla by existovat e-mailová adresa `support@domain2.com`, jejíž kopii e-mailu chci vidět v gmailu. A příležitostně mít možnost něco odeslat jménem `support@domain2.com` prostřednictvím webového rozhraní.

Měla by existovat e-mailová adresa `ivanov@domain3.com`, kterou bude používat Ivanov na svém iPhonu.

Odesílané e-maily by měly splňovat všechny moderní požadavky na ochranu proti spamu.
Měla by být zajištěna nejvyšší úroveň šifrování v veřejných sítích.
Měla by být podpora IPv6 jak pro odesílání, tak pro přijímání e-mailů.
Měl by být SpamAssassin, který nikdy neodstraní e-maily. Místo toho by měl e-maily buď vrátit, nebo je přeskočit, nebo poslat do IMAP složky „Spam“.
Mělo by být nastaveno automatické učení SpamAssassin: pokud přesunu e-mail do složky „Spam“, měl by se na tom naučit; pokud přesunu e-mail ze složky „Spam“, měl by se na tom také naučit. Výsledky učení SpamAssassin by měly ovlivňovat umístění e-mailu do složky „Spam“.
PHP skripty by měly být schopny posílat e-maily jménem jakékoli domény na tomto serveru.
Měl by být openvpn servis s možností používat IPv6 na klientovi, který nemá IPv6.

Nejprve je potřeba nastavit rozhraní a směrování včetně IPv6.
Poté bude potřeba nastavit OpenVPN, který se spojí přes IPv4 a poskytne klientovi statickou, skutečnou IPv6 adresu. Tento klient bude mít přístup ke všem IPv6 službám na serveru a ke všem IPv6 zdrojům na internetu.
Poté bude potřeba nastavit Postfix pro odesílání e-mailů + SPF + DKIM + rDNS a další podobné drobnosti.
Poté bude potřeba nastavit Dovecot a nakonfigurovat Multidomain.
Poté bude potřeba nastavit SpamAssassin a naučit ho.
Na závěr nainstalovat Bind.

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

Pro nastavení rozhraní je potřeba napsat toto do „/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

Tato nastavení lze aplikovat na jakýkoli server v tech.ru (s drobným schválením s podporou) a začne to okamžitě fungovat, jak má.

Pokud máte zkušenosti s nastavením podobných věcí pro Hetzner, OVH - tam je to jinak. Složitější.

eno1 je název síťové karty #1 (pomalý, ale bez limitu).
eno2 je název síťové karty #2 (rychlý, ale s tarifem).
tun0 — název virtuální síťové karty od OpenVPN.
XX.XX.XX.X0 — IPv4 #1 na eno1.
XX.XX.XX.X1 — IPv4 #2 na eno1.
XX.XX.XX.X2 — IPv4 #3 na eno1.
XX.XX.XX.X5 — IPv4 #1 na eno2.
XX.XX.XX.1 — IPv4 gateway.
XXXX:XXXX:XXXX:XXXX::/64 — IPv6 pro celý server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 — IPv6 pro eno2, vše ostatní přichází přes eno1.
XXXX:XXXX:XXXX:XXXX::1 — IPv6 gateway (je třeba poznamenat, že zde lze/mělo by se to udělat jinak. Uvést IPv6 switche).
dns-nameservers — jsou nastaveny na 127.0.0.1 (protože je nainstalován bind lokálně) a 213.248.1.6 (to je od tech.ru).

«table eno1t» a «table eno2t» — smysl těchto pravidel route je, aby provoz přicházející přes eno1 odešel také přes něj, zatímco provoz přicházející přes eno2 odešel také přes něj. A také spojení iniciovaná serverem by měla odcházet přes eno1.

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

Tímto příkazem nastavujeme, že každý neznámý provoz, který spadá pod jakékoliv pravidlo označené jako «table eno1t», bude směrován do rozhraní eno1.

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

Tímto příkazem nastavujeme, že veškerý provoz iniciovaný serverem bude směrován do rozhraní eno1.

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

Tímto příkazem definujeme pravidla pro značkování provozu.

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

Tento blok definuje druhou IPv4 pro rozhraní eno1.

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

Tímto příkazem určujeme trasu od klientů OpenVPN do místních IPv4 kromě XX.XX.XX.X0.
Proč je tento příkaz dostačující pro všechny IPv4 — stále nechápu.

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

Zde nastavujeme adresu pro samotné rozhraní. Server ji bude používat jako «výchozí» adresu. Jinak už nebude jinak používána.

Proč je uvedeno «:1:1::» tak složitě? Aby OpenVPN fungovalo správně a jen pro to. O tom později více.

Ohledně gateway — funguje to tak, jak má. Ale správně — zde by mělo být uvedeno IPv6 switche, ke kterému je server připojen.

Avšak proč IPv6 přestává fungovat, pokud to takto dělám. Asi to jsou nějaké vrtochy tech.ru.

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

To je přidání IPv6 adresy na rozhraní. Pokud je potřeba sto adres — pak je potřeba sto řádků v tomto souboru.

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

Označil jsem adresy a podsítě všech rozhraní, aby to bylo přehledné.
eno1 — musí mít vždy "\/64" — protože to je celý náš pool adresů.
tun0 — podsíť musí být vždy větší než eno1. Jinak nebude možné nastavit IPv6 bránu pro klienty OpenVPN.
eno2 — podsíť musí být vždy větší než tun0. Jinak se klienti OpenVPN nebudou moci připojit k místním IPv6 adresám.
Pro přehlednost jsem zvolil krok podsítě 16, ale pokud chcete, můžete dokonce použít krok "1".
Tedy 64+16 = 80, a 80+16 = 96.

Pro ještě větší přehlednost:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — to jsou adresy, které by měly být přiřazeny konkrétním webům nebo službám na rozhraní eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — to jsou adresy, které by měly být přiřazeny konkrétním webům nebo službám na rozhraní eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — to jsou adresy, které by měly být přiřazeny klientům OpenVPN nebo používány jako služební adresy OpenVPN.

Pro nastavení sítě — musí být možnost restartovat server.
Změny IPv4 se provádějí při provedení (musí být zapouzdřeno do screen — jinak tato příkaz jednoduše zruší síť na serveru):

/etc/init.d/networking restart

Do souboru "\/etc\/iproute2\/rt_tables" přidejte na konec:

100 eno1t
101 eno2t

Bez tohoto nelze použít vlastní tabulky v souboru "\/etc\/network\/interfaces".
Čísla musí být unikátní a menší než 65535.

Změny IPv6 se mění snadno bez restartu, ale k tomu se musíte naučit alespoň tři příkazy:

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

Nastavení "\/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

To jsou nastavení "sysctl" mého serveru. Vyznačuji důležitost.

net.ipv4.ip_forward = 1

Bez tohoto nebude OpenVPN fungovat vůbec.

net.ipv6.ip_nonlocal_bind = 1

Každý, kdo se pokusí obindovat IPv6 (např. nginx) hned poté, co se rozhraní uvedlo do provozu — dostane chybu, že taková adresa není dostupná.

Aby se předešlo takové situaci, provádí se toto nastavení.

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

Bez těchto nastavení IPv6 provoz od klienta OpenVPN nevyjde do světa.

Další nastavení se buď netýkají věci, nebo si nepamatuji, proč jsou.
Ale pro jistotu je nechávám "tak jak jsou".

Aby se změny tohoto souboru projevily bez restartu serveru — je třeba provést příkaz:

sysctl -p

Podrobněji o pravidlech "tabulky": habr.com\/post\/108690

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

OpenVPN IPv4 nefunguje bez iptables.

Mám následující iptables pro 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 — to je moje statická IPv4 adresa místního počítače.
10.8.0.0/24 — IPv4 síť openvpn. IPv4 adresy pro klienty openvpn.
Pořadí pravidel je důležité.

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

To je omezení, aby pouze já mohl využívat OpenVPN ze své statické IP.

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
  -- nebo --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADE

Pro přesměrování IPv4 paketů mezi klienty OpenVPN a internetem — je třeba zapsat jeden z těchto příkazů.

Pro různé situace jeden z variant nevyhovuje.
V mém případě vyhovují obě příkazy.
Po prostudování dokumentace jsem si vybral první variantu, protože spotřebovává méně CPU.

Aby všechna nastavení iptables byla načtena po restartu — je třeba je někde uložit.

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

Takové názvy nebyly zvoleny náhodně. Používá je balíček „iptables-persistent“.

apt-get install iptables-persistent

Instalace hlavního balíčku OpenVPN:

apt-get install openvpn easy-rsa

Nastavíme šablonu pro certifikáty (doplnit své hodnoty):

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

Upravením nastavení šablony certifikátů:

mcedit vars

...
# Toto jsou výchozí hodnoty pro pole
# která budou umístěna v certifikátu.
# Nenechávejte žádné z těchto polí prázdná.
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Own"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"

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

Vytvoření serverového certifikátu:

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

Připravíme možnost vytvářet konečné „client-name.opvn“ soubory:

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

Připravíme skript, který bude spojovat všechny soubory do jednoho opvn souboru.

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

Vytvoření prvního klienta OpenVPN:

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

Soubor „~/client-configs/files/client-name.ovpn“ posíláme na zařízení klienta.

Pro klienty iOS bude nutné provést trik:
Obsah tagu „tls-auth“ by měl být bez komentářů.
A také je třeba umístit „key-direction 1“ ihned před tag „tls-auth“.

Nastavíme konfiguraci OpenVPN serveru:

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

To je potřeba k tomu, aby každému klientovi přiřadil statickou adresu (není povinné, ale já to používám):

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

Nejkomplexnější a klíčová část.

Bohužel OpenVPN ještě neumí automaticky nastavovat IPv6 bránu pro klienty.
Musí se to „ručně“ předávat pro každého klienta.

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

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

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

Oba skripty používají soubor „/etc/openvpn/variables“:

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

Proč je to napsané takto — nedokážu si vzpomenout.

Teď to vypadá podivně netmask = 112 (mělo by být 96).
A prefix je podivný, neodpovídá síti tun0.
Ale dobrá, nechávám to „jak to je“.

cipher DES-EDE3-CBC

To je na vkusu — zvolil jsem tento způsob šifrování spojení.

Podrobněji o nastavení OpenVPN IPv4.

Podrobněji o nastavení OpenVPN IPv6.

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

Instalace hlavního balíčku:

apt-get install postfix

Při instalaci vyberte „internet-site“.

Můj „/etc/postfix/main.cf“ vypadá takto:

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

# Přidání .domény je úkolem MUA.
append_dot_mydomain = no

readme_directory = no

# Viz http://www.postfix.org/COMPATIBILITY_README.html -- ve výchozím nastavení 2 na
# čerstvých instalacích.
compatibility_level = 2

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

# Typ uložiště
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 nastavení
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 adresa na doménu
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcre

Podívejme se na detaily této konfigurace.

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

Podle názoru uživatelů na Habr tento blok obsahuje `dezinformace a nesprávné teze`.Až po 8 letech od začátku mé kariéry jsem začal chápat, jak SSL funguje.

Proto se odvážím popsat, jak používat SSL (aniž bych odpovídal na otázky «Jak to funguje?» a «Proč to funguje?»).

Základem moderního šifrování je vytváření páru klíčů (dvě velmi dlouhé řetězce znaků).

Jeden „klíč“ je soukromý, druhý klíč je „veřejný“. Soukromý klíč pečlivě uchováváme v tajnosti. Veřejný klíč rozdáváme všem zájemcům.

Pomocí veřejného klíče lze zašifrovat řetězec textu tak, aby ho mohl dešifrovat pouze vlastník soukromého klíče.
A to je celá podstata technologie.

Krok č. 1 — https stránky.
Při přístupu k webu prohlížeč zjistí od webového serveru, že stránka je https, a proto žádá o veřejný klíč.
Webový server poskytuje veřejný klíč. Prohlížeč pomocí veřejného klíče šifruje http-žádost a odesílá ji.
Obsah http-žádosti může přečíst pouze ten, kdo má privátní klíč, tedy pouze server, na který se posílá dotaz.
Http-žádost obsahuje minimálně URI. Proto, pokud se v zemi pokouší omezit přístup ne k celému webu, ale k určité stránce — pro https weby je to nemožné.

Krok č. 2 — zašifrovaná odpověď.
Webový server dává odpověď, kterou mohou snadno přečíst na cestě.
Řešení je velmi jednoduché — prohlížeč si lokálně formuje podobnou dvojici privátního a veřejného klíče pro každý https web.
A spolu s požadavkem veřejného klíče webu odesílá svůj lokální veřejný klíč.
Webový server si ho zapamatuje a při odeslání http-odpovědi šifruje tímto veřejným klíčem konkrétního klienta.
Nyní může http-odpověď dešifrovat pouze držitel privátního klíče prohlížeče klienta (tedy sám klient).

Krok č. 3 — vytvoření zabezpečeného spojení přes veřejný kanál.
V příkladu č. 2 je zranitelnost — nic nebrání zlým úmyslům zachytit http-žádost a upravit informace o veřejném klíči.
Takže prostředník bude mít přehled o celém obsahu odesílaných a přijatých zpráv, dokud se nezmění komunikační kanál.
Boj proti tomu je velmi jednoduchý — stačí odeslat veřejný klíč prohlížeče jako zprávu zašifrovanou veřejným klíčem webového serveru.
Webový server pak nejprve odešle odpověď typu „tvůj veřejný klíč je takovýto“ a zašifruje tuto zprávu tímto veřejným klíčem.
Prohlížeč kontroluje odpověď — pokud přišla zpráva „tvůj veřejný klíč je takovýto“ — je to 100% záruka, že tento komunikační kanál je bezpečný.
Jak bezpečný je?
Vytvoření takového bezpečného komunikačního kanálu probíhá rychlostí ping*2. Například 20 ms.
Útočník by měl buď předem mít privátní klíč jedné ze stran. Nebo by měl za pár milisekund uhodnout privátní klíč.
Prolomení jednoho moderního privátního klíče by trvalo desetiletí na superpočítači.

Krok č. 4 — veřejná databáze veřejných klíčů.
Je zřejmé, že v celé této historii existuje možnost pro útočníka sedícího na komunikačním kanálu mezi klientem a serverem.
Možnost, aby se klient představil jako server a server jako klient. A simulovat pár klíčů oběma směry.
Pak útočník uvidí veškerý provoz a bude mít možnost "upravit" tento provoz.
Například změnit adresu, kam odeslat peníze, nebo zkopírovat heslo k online bance, nebo zablokovat "nepohodlný" obsah.
Pro boj s takovými útočníky byla vymyšlena veřejná databáze s veřejnými klíči pro každý http web.
Každý prohlížeč "ví" o existenci přibližně 200 takových databází. To je předinstalováno v každém prohlížeči.
"Znání" je podpořeno veřejným klíčem od každého certifikátu. To znamená, že spojení s každým konkrétním certifikačním centrem nelze falšovat.

Nyní existuje jednoduché pochopení toho, jak používat SSL pro https.
Pokud se zapojí mozek - potom bude jasné, jak speciální služby mohou tuto konstrukci nějak prolomit. Ale bude je to stát monstrózní úsilí.
A pro organizace menší než NSA nebo CIA - je prakticky nemožné prolomit stávající úroveň ochrany, a to ani pro VIP.

Ještě dodám něco o ssh spojení. Tam žádné veřejné klíče nejsou, co tedy dělat. Otázka se řeší dvěma způsoby.
Varianta ssh-podle-hesla:
Při prvním spojení by měl ssh klient varovat, že máme nový veřejný klíč od ssh serveru.
A při dalších spojení, pokud se objeví varování "nový veřejný klíč od ssh serveru" - znamená to, že vás někdo sleduje.
Nebo byl kdysi při prvním spojení sledován, a nyní komunikujete se serverem bez prostředníků.
Vlastně proto, že fakt sledování je snadno, rychle a bez námahy odhalit - tuto techniku používají pouze ve zvláštních případech na konkrétního klienta.

Varianta ssh-podle-klíče:
Vezměte flash disk, zapíšete na něj soukromý klíč pro ssh server (k tomu existují termíny a množství významných nuancí, ale píšu školení, nikoliv návod k použití).
Veřejný klíč necháváme na stroji, kde bude ssh klient a také ho uchováváme v tajnosti.
Přinášíme flash disk k serveru, zasunujeme, kopírujeme soukromý klíč, a flash disk spálíme a rozprášíme popel po větru (nebo alespoň formátujeme s vyplněním nulami).
A je to — po takovém zásahu nebude možné takové ssh spojení prolomit. Samozřejmě za 10 let na superpočítači bude možné sledovat traffic — ale to je jiný příběh.

Omlouvám se za offtopic.

Takže teď, když známe teorii. Pověděla bych o flow vytváření ssl certifikátu.

Pomocí „openssl genrsa“ vytváříme soukromý klíč a „předlohu“ pro veřejný klíč.
„předlohu“ posíláme externí společnosti, které platíme přibližně $9 za nejjednodušší certifikát.

Během pár hodin obdržíme od této externí společnosti náš „veřejný“ klíč a také sadu několika dalších veřejných klíčů.

Proč platit externí společnosti za zpracování mého veřejného klíče — to je jiná otázka, tady ji nebudeme zvažovat.

Teď je jasné, v čem spočívá smysl nápisu:

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

Ve složce „/etc/ssl“ jsou uloženy všechny soubory k otázkám ssl.
domain1.com — název domény.
2018 — rok vytvoření klíčů.
„key“ — označení, že soubor je soukromý klíč.

A smysl tohoto souboru:

smtpd_tls_cert_file= /etc/ssl/domain1.com.2018.chained.crt
domain1.com — název domény.
2018 — rok vytvoření klíčů.
chained — označení, že zde je řetězec veřejných klíčů (první — náš veřejný a ostatní — co přišlo od společnosti, která zpracovala veřejný klíč).
crt — označení, že zde je hotový certifikát (veřejný klíč s technickými vysvětleními).

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

Toto nastavení se v tomto případě nepoužívá, ale je uvedeno jako příklad.

Protože chyba v tomto parametru by vedla k odesílání spamu z vašeho serveru (bez vašeho vědomí).

Pak dokazujte všem, že za to nemůžete.

recipient_delimiter = +

Možná mnozí nevědí, ale to je standardní symbol pro rozdělení příjemců a většina moderních poštovních serverů to podporuje.

Například pokud máte e-mailovou adresu „username@gmail.com“, zkuste poslat na „username+spam@gmail.com“ — uvidíte, co z toho vyjde.

inet_protocols = ipv4

To může být matoucí.

Ale není to bez důvodu. Každá nová doména je ve výchozím nastavení pouze IPv4, poté aktivuji IPv6 pro každou jednotlivě.

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

Tady nastavujeme, že veškerá příchozí pošta jde do dovecotu.
A pravidla pro doménu, schránku, alias — sledovat v databázi.

/etc/postfix/mysql-virtual-mailbox-domains.cf

uživatel = uživatelská pošta
heslo = heslo pošty
hostitelé = 127.0.0.1
dbname = servermail
dotaz = SELECT 1 FROM virtual_domains WHERE name='%s'

/etc/postfix/mysql-virtual-mailbox-maps.cf

uživatel = uživatelská pošta
heslo = heslo pošty
hostitelé = 127.0.0.1
dbname = servermail
dotaz = SELECT 1 FROM virtual_users WHERE email='%s'

/etc/postfix/mysql-virtual-alias-maps.cf

uživatel = uživatelská pošta
heslo = heslo pošty
hostitelé = 127.0.0.1
dbname = servermail
dotaz = 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

Teď postfix ví, že přijímat poštu k dalšímu odeslání lze pouze na základě autorizace s dovecot.

Opravdu mi není jasné, proč to tady znovu zdvojovat. Již jsme uvedli v „virtual_transport“ všechno potřebné.

Ale postfix je velmi starý systém — pravděpodobně se jedná o berle z minulých dob.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

To je nutné konfigurovat pro každý poštovní server individuálně.

Mám k dispozici 3 poštovní servery a tato nastavení se velmi liší kvůli různým požadavkům na použití.

Nastavení je třeba provádět pečlivě — jinak k vám může připlout spam nebo, co je ještě horší, spam může od vás odcházet.

# SPF
policyd-spf_time_limit = 3600

Nastavení pro nějaký plugin související s kontrolou SPF příchozí pošty.

# 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

Nastavení, že všechny odchozí emaily musíme opatřit DKIM podpisem.

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

Toto je klíčový detail v routování emailů při odesílání emailů z php skriptů.

Soubor „/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:

Vlevo — regulární výrazy. Vpravo — značka, kterou je e-mail označen.
Postfix podle značky vezme v úvahu ještě několik konfiguračních řádků pro konkrétní e-mail.

Jak přesně bude postfix znovu nakonfigurován pro konkrétní e-mail — bude uvedeno v „master.cf“.

Řádky 4, 5, 6 — ty jsou hlavní. Od jména domény, z které je e-mail odesílán, se nastavuje taková značka.
Ale ne vždy je v php skriptech ve starém kódu uvedeno pole „from“. Pak pomůže jméno uživatele.

Článek je už tak obsáhlý — nechtěl bych se rozptylovat nastavením nginx+fpm.

Stručně — pro každou webovou stránku nastavujeme svého linux-uživatele jako vlastníka. A odpovídajícím způsobem svůj fpm-pool.

Fpm-pool používá jakoukoli verzi php (to je skvělé, když na jednom serveru lze bez problémů používat různé verze php a dokonce rozdílné php.ini).

Takže daný linux-uživatel „www-domain2“ má stránku domain2.com. Na této stránce je kód pro odesílání e-mailů bez uvedení pole from.

Takže i v takovém případě budou e-maily odcházet správně a nikdy se nedostanou do spamu.

Můj „/etc/postfix/master.cf“ vypadá takto:

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

Soubor není úplný – je to už tak velmi velké.
Zaznamenal jsem pouze to, co bylo změněno.

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}

Toto jsou nastavení týkající se spamassassin, budu o něm později.

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

Umožňujeme připojení k poštovnímu serveru přes port 587.
Je třeba se přihlásit.

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

Zapínáme kontrolu SPF.

apt-get install postfix-policyd-spf-python

Nainstalujeme balíček pro SPF kontroly.

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

A to je nejzajímavější. Je to možnost posílat e-maily pro konkrétní doménu z konkrétní IPv4/IPv6 adresy.

Dělá se to kvůli rDNS. rDNS je získání nějakého řetězce na základě IP adresy.
A pro e-maily se tato možnost používá k potvrzení, že helo přesně odpovídá rDNS té adresy, ze které byl e-mail odeslán.

Pokud helo neodpovídá doméně e-mailu, jménem které byl e-mail odeslán – sbírají se spamové body.

Helo neodpovídá rDNS – sbírá se hodně spamových bodů.
Proto pro každou doménu musí být vlastní IP adresa.
Pro OVH – v konzole je možnost uvést rDNS.
Pro tech.ru – otázka se řeší přes podporu.
Pro AWS – otázka se řeší přes podporu.
„inet_protocols“ a „smtp_bind_address6“ — to zapínáme podporu IPv6.
Pro IPv6 je také potřeba nastavit rDNS.
„syslog_name“ — to je pro pohodlnější čtení logů.

Kupovat certifikáty doporučuji zde.

Nastavení spojení postfix+dovecot zde.

Nastavení SPF.

============= Dovecot =============

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

Nastavení mysql, instalujeme si balíčky.

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

disable_plaintext_auth = yes
auth_mechanisms = plain login

Autentizace pouze v zašifrované podobě.

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

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

Zde uvedeme místo pro ukládání e-mailů.

Chci, aby byly uchovávány v souborech a seskupeny podle domén.

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

To je hlavní soubor nastavení dovecot.
Tady zakážeme nezabezpečená připojení.
A povolíme zabezpečená připojení.

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

Nastavujeme ssl. Uvádíme, že ssl — je povinné.
A samotný certifikát. A důležitý detail — direktiva „local“. Určuje, který ssl certifikát použít při připojení k jakému místnímu IPv4.

Mimochodem, IPv6 tady není nastaven, to napravím někdy později.
XX.XX.XX.X5 (domain2) — certifikát není. Pro připojení klientů je potřeba uvádět domain1.com.
XX.XX.XX.X2 (domain3) — certifikát je, pro připojení klientů lze uvádět domain1.com nebo domain3.com.

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

protocol lda {
  mail_plugins = $mail_plugins sieve
}

To bude v budoucnu potřeba pro spamassassin.

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

protocol imap {
  mail_plugins = $mail_plugins antispam
}

To je antispam plugin. Potřebný pro výuku spamassassin při přesunu do/z složky „Spam“.

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

protocol pop3 {
}

Jednoduše takový soubor existuje.

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

protokol lmtp {
  mail_plugins = $mail_plugins sieve
  postmaster_address = admin@domain1.com
}

Nastavení lmtp.

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

Nastavení učení spamassasinu při přesunu do/z složky „Spam“.

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

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

Soubor, který určuje, co dělat s příchozími e-maily.

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

require ["fileinto", "mailbox"];

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

Je třeba zkompilovat soubor: „sievec default.sieve“.

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

Určení sql souborů pro autorizaci.
A samotný soubor - jako způsob autorizace.

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

To odpovídá podobným nastavením pro postfix.

Soubor „/etc/dovecot/dovecot.conf“

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

Hlavní konfigurační soubor.
Důležité je, že zde uvádíme přidané protokoly.

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

apt-get install spamassassin spamc

Nainstalujeme balíčky.

adduser spamd --disabled-login

Přidáme uživatele pod kterým.

systemctl enable spamassassin.service

Povolujeme automatické spouštění spamassassin služby při nabootování.

Soubor „/etc/default/spamassassin“:

CRON=1

Povolujeme automatické aktualizace pravidel „podle výchozího nastavení.“

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

Je třeba vytvořit v mysql DB „sa“ s uživatelským jménem „sa“ a heslem „password“ (vyměnit za něco smysluplného).

report_safe - místo e-mailu se bude zasílat zpráva o spamovém e-mailu.
use_bayes - to jsou nastavení strojového učení spamassassinu.

Ostatní nastavení spamassassinu byla dříve aplikována podle článku.

Obecné nastavení „spamassassin“.
O přesunu nových spamových e-mailů do IMAP složky „Spam“.
O jednoduchém spojení Dovecot + SpamAssassin.
Doporučuji k přečtení teorii učení spamassassinu při pohybu e-mailů v imap složkách (a nedoporučuji k aplikaci).

============= Obrátení se na komunitu =============

Rád bych přispěl nápadem do komunity o tom, jak zvýšit úroveň zabezpečení přenášených emailů. Když už jsem se tak hluboce ponořil do tématu e-mailů.

Aby si uživatel mohl na svém klientovi (outlook, thunderbird, prohlížečový plugin, …) vytvořit pár klíčů. Veřejný a soukromý. Veřejný — poslat do DNS. Soukromý — uchovávat na klientovi. Poštovní servery by uměly použít veřejný klíč pro odeslání konkrétnímu příjemci.

A pro ochranu před spamem u takových emailů (ano, poštovní server nebude moci prozkoumat obsah) — je potřeba zavést 3 pravidla:

  1. Povinný platný podpis DKIM, povinný SPF, povinný rDNS.
  2. Neuronová síť zaměřená na výuku proti spamu + databáze k ní na straně klienta.
  3. Algoritmus šifrování by měl být takový, že odesílající strana musí na šifrování vynaložit 100krát více výkonu CPU než přijímající strana.

Kromě veřejných emailů — vyvinout standard pro návrh emailu "zahájit zabezpečenou komunikaci". Jeden z uživatelů (emailová schránka) posílá druhému email s přílohou. V emailu je textový návrh na zahájení zabezpečeného kanálu komunikace a veřejný klíč majitele emailové schránky (přitom soukromý klíč na straně klienta).

Můžete dokonce vytvořit pár klíčů speciálně pro každou komunikaci. Uživatel-příjemce může tuto nabídku přijmout a poslat svůj veřejný klíč (také vytvořený speciálně pro tuto komunikaci). Poté první uživatel odešle kontrolní email (zašifrovaný veřejným klíčem druhého uživatele) — při jehož obdržení může druhý uživatel považovat vytvořený komunikační kanál za spolehlivý. Následně druhý uživatel odešle kontrolní email — a pak může první uživatel také považovat vytvořený kanál za zabezpečený.

Pro boj s odposlechem klíčů na cestě — je potřeba v protokolu předpokládat možnost přenosu alespoň jednoho veřejného klíče pomocí flash disk.

A to nejdůležitější — aby to vše fungovalo (otázka "kdo za to zaplatí?"):
Zadejte poštovní certifikáty s cenou od 10 $ na 3 roky. Tyto certifikáty umožní odesílateli uvést do DNS, že "mé veřejné klíče jsou tamhle". A také umožní začít zabezpečené spojení. A budou přijímat taková spojení zdarma.
Gmail konečně monetizuje své uživatele. Za 10 $ na 3 roky - právo vytvářet zabezpečené kanály komunikace.

============= Závěr =============

Pro testování celého článku jsem se chystal pronajmout dedikovaný server na měsíc a zakoupit doménu s SSL certifikátem.

Ale životní okolnosti vedly k tomu, že se tento problém protáhl na 2 měsíce.
A když se mi znovu objevilo volné časové okno - rozhodl jsem se publikovat článek tak, jak je, aniž bych riskoval, že publikace se zpozdí o další rok.

Pokud bude dostatek dotazů typu "tady to není dost podrobně popsáno" - pak asi najdu síly vzít dedikovaný server s novou doménou a novým SSL certifikátem a popsat to ještě podrobněji a hlavně - odhalit všechny opomenuté důležité detaily.

Také bych rád dostal názory na myšlenku o poštovních certifikátech. Pokud se myšlenka zalíbí - pokusím se najít síly napsat návrh pro RFC.

Při kopírování velkých částí článku - uvádějte odkaz na tento článek.
Při překladu do jakéhokoli jiného jazyka - uvádějte odkaz na tento článek.
Na angličtinu se sám pokusím přeložit a ponechám vzájemné odkazy.


Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster