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

Ta článek popisuje, jak nastavit moderní e-mailový server.
Postfix + Dovecot. SPF + DKIM + rDNS. S IPv6.
S šifrováním TSL. S podporou několika domén — část s pravým SSL certifikátem.
S antispamovou ochranou a vysokým antispamovým hodnocením u jiných e-mailových serverů.
S podporou několika fyzických rozhraní.
S OpenVPN, jehož připojení je přes IPv4, a který poskytuje IPv6.

Pokud se nechcete zabývat těmito technologiemi, ale chcete takový server nastavit — pak je tento článek pro vás.

Článek se nepokouší vysvětlit každý detail. Vysvětlení se týká toho, co je nastaveno nestandardně nebo důležité z pohledu uživatele.

Motivace nastavit e-mailový server — můj dávný sen. Možná to zní hloupě, ale IMHO, je to mnohem lepší, než snít o novém autě své oblíbené značky.

Motivace nastavit IPv6 — jsou dvě. IT specialistovi je třeba neustále se učit novým technologiím, aby přežil. Chci přispět svým skromným dílem k boji proti cenzuře.

Motivace nastavit OpenVPN — pouze proto, aby IPv6 fungoval na lokálním stroji.
Motivace nastavit několik fyzických rozhraní — mám na serveru jedno rozhraní „pomalé, ale bez limitu“, a druhé „rychlé, ale s tarifem“.

Motivace nastavit Bind — můj poskytovatel nabízí nestabilní DNS server, a Google také někdy selhává. Chci stabilní DNS server pro osobní použití.

Motivace napsat článek — návrh byl napsán před 10 měsíci a já jsem se na něj už dvakrát podíval. Když to autor potřebuje pravidelně — je velká šance, že to bude potřebovat i někdo jiný.

Neexistuje univerzální řešení pro e-mailový server. Ale pokusím se napsat něco jako „udělejte to takto a poté, co všechno bude fungovat jak má — vyhoďte zbytečné“.

Mám server Colocation u společnosti tech.ru. Existuje možnost porovnat to s OVH, Hetzner, AWS. Pro řešení tohoto úkolu bude mnohem efektivnější spolupracovat právě s tech.ru.

Na serveru je nainstalován Debian 9.

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

Mám 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`.

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

Obstaja 3 domene `domain1.com`, `domain2.com`, `domain3.com`. Za `domain1.com` in `domain3.com` je na voljo SSL potrdilo.

Imam Google račun, na katerega bi rad povezaval e-poštni naslov `vasya.pupkin@domain1.com` (sprejemanje in pošiljanje e-pošte neposredno iz vmesnika Gmail).
Potrebujem e-poštni naslov `support@domain2.com`, kopijo katerega bi rad videl v Gmailu. Občasno moram imeti možnost pošiljati e-pošto v imenu `support@domain2.com` prek spletnega vmesnika.

Potrebujem e-poštni naslov `ivanov@domain3.com`, ki ga bo uporabljal Ivanov s svojega iPhona.

Poslana sporočila morajo ustrezati vsem sodobnim zahtevam proti neželeni pošti.
Mora biti najvišja raven šifriranja, ki je predvidena v javnih omrežjih.
Mora biti podpora za IPv6, tako za pošiljanje kot prejemanje e-pošte.
Mora biti SpamAssassin, ki nikoli ne bo brisal sporočil. Lahko jih bo vrnil ali jih poslal v IMAP mapo 'Spam'.
Mora biti nastavljeno samodejno učenje SpamAssassin: če premaknem sporočilo v mapo 'Spam' — se nauči tega; če premaknem sporočilo iz mape 'Spam' — se tudi nauči. Rezultati učenja SpamAssassin morajo vplivati na dostopnost sporočila v mapo 'Spam'.
PHP skripte morajo znati pošiljati e-pošto v imenu katere koli domene na tem strežniku.
Mora biti openvpn storitev, ki omogoča uporabo IPv6 na odjemalcu, ki nima IPv6.

Najprej je treba nastaviti vmesnike in usmerjanje, vključno z IPv6.
Nato je treba nastaviti OpenVPN, ki se bo povezoval prek IPv4 in odjemalcu dodelil statični pravi IPv6 naslov. Ta odjemalec bo imel dostop do vseh IPv6 storitev na strežniku in dostop do vseh IPv6 virov na internetu.
Nato je treba nastaviti Postfix za pošiljanje e-pošte + SPF + DKIM + rDNS in druge podobne malenkosti.
Nato je treba nastaviti Dovecot in konfigurirati večdomeno.
Nato je treba nastaviti SpamAssassin in konfigurirati učenje.
Na koncu namestiti Bind.

============= Več vmesnikov =============

Za nastavitev vmesnikov je treba vpisati to v ‘/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

Te nastavitve se lahko uporabljajo na vsakem strežniku v tech.ru (s majhnim usklajevanjem s podporo) in takoj bodo delovale kot je treba.

Če imate izkušnje z nastavitvijo podobnih stvari za Hetzner, OVH — je tam drugače. Težje.

eno1 — to je ime omrežne kartice #1 (počasna, a brez omejitev).
eno2 — to je ime omrežne kartice #2 (hitro, a s tarifo).
tun0 — ime virtualne mrežne kartice 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 za ceo server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 — IPv6 za eno2, a sve ostalo dolazi u eno1.
XXXX:XXXX:XXXX:XXXX::1 — IPv6 gateway (treba napomenuti da ovde treba ili može biti drugačije. Navesti IPv6 switch-a).
dns-nameservers — navedeni 127.0.0.1 (jer je bind instaliran lokalno) i 213.248.1.6 (to je od tech.ru).

«table eno1t» i «table eno2t» — smisao ovih route-rule je da saobraćaj koji ulazi kroz eno1 izađe kroz eno1, a saobraćaj koji ulazi kroz eno2 izađe kroz eno2. Takođe, veze pokrenute od strane servera odlaze kroz eno1.

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

Ovom komandom postavljamo da svaki nepoznati saobraćaj koji pripada bilo kojem pravilu sa oznakom «table eno1t» ode u interfejs eno1.

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

Ovom komandom postavljamo da svaki saobraćaj pokrenut od strane servera ide u interfejs eno1.

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

Ovom komandom postavljamo sama pravila za obeležavanje saobraćaja.

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

Ovaj blok postavlja drugi IPv4 za interfejs eno1.

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

Ovom komandom postavljamo route od OpenVPN klijenata do lokalnih IPv4 osim XX.XX.XX.X0.
Zašto je ovo dovoljno za sve IPv4 — još uvek ne razumem.

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

Ovde postavljamo adresu za sam interfejs. Server će je koristiti kao «izlaznu» adresu. Više se neće koristiti.

Zašto je navedeno «:1:1::» tako složeno? Da bi OpenVPN pravilno funkcionisao i samo za to. O tome više kasnije.

Što se tiče gateway-a — tako to radi i u redu je. Ali ispravno — ovde treba navesti IPv6 switch-a kojem je server povezan.

Međutim, iznenađujuće je da IPv6 prestaje da radi ako to uradim. Možda je to neka čudnost od tech.ru.

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

Ovo dodavanje IPv6 adrese na interfejs. Ako je potrebno sto adresa — znači sto redova u ovom fajlu.

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

Obeležio sam adrese i podmreže svih interfejsa, da bude pregledno.
eno1 — mora biti «/64» — ker je to celoten naš pool naslovov.
tun0 — podmreža mora biti nujno večja od eno1. V nasprotnem primeru ne bo mogoče nastaviti IPv6 gateway za stranke OpenVPN.
eno2 — podmreža mora biti nujno večja od tun0. V nasprotnem primeru stranke OpenVPN ne bodo mogle dostopati do lokalnih IPv6 naslovov.
Za jasnost sem izbral korak podmreže 16, a lahko bi izbral tudi korak «1».
Da bi bilo jasno: 64+16 = 80, 80+16 = 96.

Za še večjo jasnost:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — to so naslovi, ki morajo biti dodeljeni določenim spletnim mestom ali storitvam na vmesniku eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — to so naslovi, ki morajo biti dodeljeni določenim spletnim mestom ali storitvam na vmesniku eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — to so naslovi, ki morajo biti dodeljeni strankam OpenVPN ali uporabljeni kot službeni naslovi OpenVPN.

Za nastavitev omrežja — mora biti možnost znova zagnati strežnik.
IPv4 spremembe se ujamejo ob izvajanju (obvezno dati v screen — drugače ta ukaz preprosto zruši omrežje na strežniku):

/etc/init.d/networking restart

V datoteko «/etc/iproute2/rt_tables» dodajte na konec:

100 eno1t
101 eno2t

Brez tega ne moremo uporabiti po meri tabel v datoteki «/etc/network/interfaces».
Številke morajo biti edinstvene in manjše od 65535.

IPv6 spremembe se zlahka spremenijo brez ponovnega zagona, a za to se je potrebno naučiti vsaj treh ukazov:

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

Nastavitev «/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 so nastavitve «sysctl» mojega strežnika. Opozarjam na pomembno.

net.ipv4.ip_forward = 1

Brez tega OpenVPN ne bo deloval.

net.ipv6.ip_nonlocal_bind = 1

Vsakdo, ki poskusi narediti bind IPv6 (na primer nginx) takoj po tem, ko je bil vmesnik dodeljen — bo prejel napako. Da tak naslov ni na voljo.

Da bi se izognili tej situaciji, se izvede taka nastavitev.

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

Brez teh nastavitev IPv6 promet s strani stranke OpenVPN ne bo prišel v svet.

Druga nastavitev ali ni relevantna ali se ne spomnim, zakaj so.
Ampak za vsak primer puščam «kot je».

Da bi spremembe te datoteke začele veljati brez ponovnega zagona strežnika — je treba izvesti ukaz:

sysctl -p

Bolj podrobno o pravilih «table»: habr.com/post/108690

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

OpenVPN IPv4 ne deluje brez iptables.

Moji iptables so takšni za 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 je moj statični IPv4 naslov lokalnog računala.
10.8.0.0/24 je IPv4 mreža openvpn. IPv4 adresa za klijente openvpn.
Redosled pravila je važan.

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

Ovo je ograničenje da samo ja mogu da koristim OpenVPN sa svog statičnog IP.

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

Za preusmeravanje IPv4 paketa između OpenVPN klijenata i interneta — potrebno je uneti jednu od ovih komandi.

Za različite slučajeve jedna od opcija ne odgovara.
Za moj slučaj obe komande odgovaraju.
Pročitao sam dokumentaciju i izabrao prvu opciju jer troši manje CPU.

Da bi se sve iptables postavke aktivirale nakon ponovnog pokretanja — potrebno ih je negde sačuvati.

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

Ova imena nisu izabrana slučajno. Koristi ih paket „iptables-persistent“.

apt-get install iptables-persistent

Instalacija osnovnog paketa OpenVPN:

apt-get install openvpn easy-rsa

Konfigurišemo šablon za sertifikate (upisati svoje vrednosti):

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

Izmenjujemo postavke šablona sertifikata:

mcedit vars

...
# Ovo su podrazumevane vrednosti za polja
# koja će biti smeštena u sertifikat.
# Ne ostavljajte nijedno od ovih polja prazno.
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"
...

Kreiramo serverski sertifikat:

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

Pripremamo mogućnost za kreiranje konačnih „client-name.opvn“ datoteka:

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

Pripremamo skriptu koja će spojiti sve datoteke u jedan opvn fajl.

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

Kreiramo prvog OpenVPN klijenta:

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

Fajl „~/client-configs/files/client-name.ovpn“ šaljemo na uređaj klijenta.

Za iOS klijente biće potrebno napraviti trik:
Sadržaj taga „tls-auth“ mora biti bez komentara.
Takođe, postavite „key-direction 1“ odmah pre taga „tls-auth“.

Konfigurišemo OpenVPN server:

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 potrebno da se postavi statička adresa svakom klijentu (nije obavezno, ali ja koristim):

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

Najkompleksniji i ključni detalj.

Nažalost, OpenVPN još ne može samostalno da postavi IPv6 gateway za klijente.
Moramo "ručno" proslediti ovo za svakog klijenta.

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

Fajl „\/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

Fajl „\/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 skripta koriste fajl „\/etc\/openvpn\/variables“:

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

Zašto ovde ovako piše — ne mogu se setiti.

Trenutno izgleda čudno netmask = 112 (ovde bi trebalo da bude 96).
I prefix je čudan, ne odgovara mreži tun0.
Ali, dobro, ostavljam „kako jeste“.

cipher DES-EDE3-CBC

To je stvar ličnog izbora — odabrao sam ovakav način enkripcije veze.

Detaljnije o podešavanju OpenVPN IPv4.

Detaljnije o podešavanju OpenVPN IPv6.

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

Instalacija glavnog paketa:

apt-get install postfix

Tokom instalacije odabrati „internet-site“.

Moj „\/etc\/postfix\/main.cf“ izgleda ovako:

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

# dodavanje .domain je zadatak MUA.
append_dot_mydomain = no

readme_directory = no

# Vidi http://www.postfix.org/COMPATIBILITY_README.html -- podrazumeva se 2 na
# svežim instalacijama.
compatibility_level = 2

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

# Tip skladištenja
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 podešavanja
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 po domenu
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcre

Pogledajmo detalje ove konfiguracije.

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

Prema mišljenju članova Habr-a, ovaj deo sadrži `dezinformacije i netačne teze`.Tek nakon 8 godina od početka svoje karijere počeo sam da razumem kako funkcioniše SSL.

Zato ću preuzeti hrabrost da opišem kako koristiti SSL (ne odgovarajući na pitanja 'Kako ovo funkcioniše?' i 'Zašto ovo funkcioniše?').

Osnova savremenog šifrovanja je stvaranje para ključeva (dve veoma duge string sa simbolima).

Jedan 'kljuc' je privatni, dok je drugi ključno 'javni'. Privatni ključ čuvamo veoma pažljivo u tajnosti. Javni ključ delimo svima koji žele.

Pomoću javnog ključa može se enkriptovati niz tekst, tako da samo vlasnik privatnog ključa može da ga dekriptuje.
To je osnova tehnologije.

Korak br. 1 — https sajtovi.
Preglednik, kada se obrati sajtu, saznaje od web servera da je sajt https i zato traži javni ključ.
Web server provides the public key. The browser uses the public key to encrypt the http-request and sends it.
The content of the http-request can only be read by someone who has the private key, that is, only the server to which the request is made.
The http-request contains at least the URI. Therefore, if a country tries to restrict access not to the entire site, but to a specific page — it is impossible to do so for https sites.

Step #2 — encrypted response.
The web server provides a response that can be easily read along the way.
The solution is straightforward — the browser locally generates such a pair of private-public keys for each https site.
And along with the request for the site's public key, it sends its local public key.
The web server remembers it and when sending the http-response, encrypts it with the public key of the specific client.
Now the http-response can only be decrypted by the holder of the client's browser's private key (that is, the client themselves).

Step #3 — establishing a secure connection over a public channel.
In example #2, there is a vulnerability — nothing prevents malicious actors from intercepting the http-request and editing the information about the public key.
Thus, the intermediary will be able to see all content of the sent and received messages until the communication channel is changed.
It is very simple to combat this — just send the browser's public key as a message encrypted with the web server's public key.
The web server will first send a response of the type 'your public key is like this' and encrypts this message with that same public key.
The browser checks the response — if the message 'your public key is like this' came, then it is a 100% guarantee that this communication channel is secure.
How secure is it?
The establishment of such a secure communication channel occurs at a speed of ping*2. For example, 20ms.
An attacker must either already possess the private key of one of the parties or crack the private key within a couple of milliseconds.
Hacking a modern private key would take decades on a supercomputer.

Step #4 — a public database of public keys.
It is evident that in this entire story, there is a possibility for an attacker sitting on the communication channel between the client and the server.
Možnost, da se stranka predstavi kot strežnik, in strežnik kot stranka. In simulirati par ključev v obe smeri.
Takrat bodo napadalci videli ves promet in imeli možnost, da 'spremenijo' promet.
Na primer, spremeniti naslov, kamor pošiljati denar, ali kopirati geslo za spletno banko ali blokirati 'neprijeten' content.
Za boj proti takšnim napadalcem so izumili javno bazo podatkov z javnimi ključi za vsako https spletno stran.
Vsak brskalnik 've' za obstoj približno 200 takšnih baz podatkov. To je prednastavljeno v vsakem brskalniku.
To 'znanje' je potrjeno z javnim ključem vsakega certifikata. To pomeni, da je povezavo z vsakim konkretnim centrom za certificiranje nemogoče ponarediti.

Sedaj imamo preprosto razumevanje, kako uporabljati SSL za https.
Če malo premisliš, postane jasno, kako lahko varnostne službe v tej konstrukciji nekaj razvnamejo. Ampak stalo jih bo ogromno truda.
Organizacijam, ki so manjše od NSA ali CIA, je praktično nemogoče zlomiti obstoječo raven zaščite, tudi za VIP.

Še dodam o ssh povezavah. Tam ni javnih ključev, kako biti. Vprašanje se rešuje na dva načina.
Možnost ssh-po-geslu:
Ob prvem povezovanju mora ssh-stranka obvestiti, da imamo tukaj nov javni ključ od ssh-strežnika.
In pri nadaljnjih povezovanjih, če se prikaže opozorilo 'nov javni ključ od ssh-strežnika' — bo to pomenilo, da vas poskušajo prisluškovati.
Ali so vas pri prvem povezovanju prisluškovali, zdaj pa se pogovarjate s strežnikom brez posrednikov.
Lastno zato, ker je dejstvo prisluškovanja enostavno, hitro in brez truda razkriti — tega napada se uporablja samo v posebnih primerih proti konkretnemu odjemalcu.

Možnost ssh-po-kljucu:
Vzeti USB ključek, nanj zapišemo zasebni ključ za ssh-strežnik (za to obstajajo izrazi in kup pomembnih podrobnosti, ampak pišem za izobraževanje, ne navodila za uporabo).
Javni ključ pustimo na napravi, kjer bo ssh-stranka, in ga prav tako obdržimo v skrivnosti.
Srečamo se s USB-ključkom na strežniku, vstavimo, kopiramo zasebni ključ, ključek zažgemo in razpršimo prašek po vetru (ali vsaj formatiramo z izpolnjenjem z ničlami).
In conclusion, after such an operation it will be impossible to hijack an SSH connection. Of course, in about ten years, a supercomputer might be able to analyze the traffic, but that's a separate story.

I apologize for the off-topic.

So now that the theory is known, I’ll talk about the flow of creating an SSL certificate.

Using "openssl genrsa", we create a private key and "templates" for the public key.
"Templates" are sent to a third-party company, for which we pay about $9 for the simplest certificate.

In a couple of hours, we receive our "public" key and a set of several other public keys from this third-party company.

The question of why we need to pay the third-party company to issue my public key is a separate one; we won't discuss that here.

Now it’s clear what the inscription means:

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

In the directory "/etc/ssl", all files related to SSL are stored.
domain1.com — the name of the domain.
2018 — the year the keys were created.
"key" — indicates that the file is a private key.

And the meaning of this file:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com — the name of the domain.
2018 — the year the keys were created.
chained — indicates that this is a chain of public keys (the first one is our public key, and the rest are from the company that issued the public key).
crt — indicates that this is a ready certificate (public key with technical explanations).

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

This setting is not used in this case, but is stated for illustration.

Because an error in this parameter will lead to your server sending spam (without your consent).

Then you’ll have to prove to everyone that you are not guilty.

recipient_delimiter = +

Many may not know this; it is a standard symbol for email address tagging, supported by most modern mail servers.

For example, if you have the email "username@gmail.com", try sending to "username+spam@gmail.com" — see what happens.

inet_protocols = ipv4

This may be confusing.

But there’s a reason for it. Every new domain defaults to IPv4 only, then IPv6 is enabled individually for each.

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

Here we specify that all incoming mail is sent to Dovecot.
And the rules for domain, mailbox, alias — check in the database.

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

user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

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

user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'

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

user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'

# SMTP-Auth settings
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

Sedaj postfix ve, da lahko sprejme elektronsko pošto za nadaljnje pošiljanje le z avtentikacijo dovecota.

Res mi ni povsem jasno, zakaj to ponavljamo. Že smo navedli vse v 'virtual_transport'.

Ampak sistem postfix je zelo star — morda so to le zakrpe iz starih časov.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

To je treba nastaviti za vsak poštni strežnik posebaj.

Imam na voljo tri poštne strežnike in ti nastavitve so zelo različne zaradi različnih zahtev pri uporabi.

Nastaviti je treba previdno — sicer bo spam pritekel k vam ali še huje — spam bo pritekel od vas.

# SPF
policyd-spf_time_limit = 3600

Nastavitev za nek dodatek, povezan s preverjanjem SPF prihajajočih sporočil.

# 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

Nastavitev, da moramo vse odhodne e-pošte opremiti z DKIM podpisom.

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

To je ključna podrobnost pri usmerjanju e-pošte, ko pošiljamo sporočila iz PHP skriptov.

Datoteka '/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:

Na levi so regularni izrazi. Na desni je oznaka, s katero je označeno sporočilo.
Postfix bo za oznako upošteval še nekaj vrstic konfiguracije za konkretno sporočilo.

Kako bo postfix ponovno konfiguriran za konkretno sporočilo, bo navedeno v 'master.cf'.

Vrstice 4, 5, 6 — te so ključne. Kakšnega domene pošiljamo sporočilo — takšno oznako tudi postavimo.
Vendar pa v PHP skriptih v starejšem kodu ne vedno navedemo polja 'from'. Takrat pride v pomoč uporabniško ime.

Članek je že tako obsežen — ne bi se rad zadrževal pri nastavitvi nginx+fpm.

Na kratko — za vsako spletno mesto določimo svojega lastnika linux-user. In seveda svoj fpm-pool.

Fpm-pool uporablja katerokoli različico php (to je odlično, ko lahko na istem strežniku brez težav za sosednje spletne strani uporabimo različne različice php in celo različne php.ini).

Tako ima konkreten linux-user 'www-domain2' spletno stran domain2.com. Na tej spletni strani je koda za pošiljanje sporočil brez navedbe polja 'from'.

Tudi v tem primeru bodo sporočila pravilno poslana in nikoli ne bodo pristala v spamu.

Moj '/etc/postfix/master.cf' izgleda tako:

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

Datoteka nije u potpunosti prikazana — već je vrlo velika.
Istaknuo sam samo ono što je izmijenjeno.

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}

Ovo su podešavanja vezana uz spamassassin, o njemu kasnije.

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

Omogućavamo pristup mail serveru putem porta 587.
Za to je nužno autorizovati se.

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

Aktiviramo provjeru SPF.

apt-get install postfix-policyd-spf-python

Instalirat ćemo paket za SPF provjere.

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 ovo je najzanimljivije. Ovo je mogućnost slanja poruka za određenu domenu s određenom IPv4/IPv6 adresom.

To se radi radi rDNS-a. rDNS — to je dobijanje neke string vrednosti po IP adresi.
I za e-poštu, ova mogućnost se koristi za potvrdu da helo tačno odgovara rDNS-u te adrese s koje je poslat e-mail.

Ako helo ne odgovara domenu e-pošte, u ime kojeg je poslana poruka — dodaju se spam poeni.

Helo ne odgovara rDNS-u — dodaje se mnogo spam poena.
Prema tome, za svaku domenu mora biti vlastita IP adresa.
Za OVH — u konzoli postoji mogućnost postavljanja rDNS-a.
Za tech.ru — preko podrške se rešava pitanje.
Za AWS — preko podrške se rešava pitanje.
«inet_protocols» in «smtp_bind_address6» - to enable IPv6 support.
It is also necessary to specify rDNS for IPv6.
«syslog_name» - this is for easier log reading.

Purchase certificates I recommend this place.

Postfix + Dovecot setup is here.

Setting up SPF.

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

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

MySQL configuration, we install the packages ourselves.

File «/etc/dovecot/conf.d/10-auth.conf»

disable_plaintext_auth = yes
auth_mechanisms = plain login

Authorization only in encrypted form.

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

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

Here we will specify the mail storage location.

I want them to be stored in files and grouped by domains.

File «/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 {
  }
}

This is the main configuration file for Dovecot.
Here we disable unprotected connections.
And enable secure connections.

File «/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
}

We configure SSL. Indicating that SSL is mandatory.
And the certificate itself. An important detail is the directive «local». It specifies which SSL certificate to use when connecting to a specific local IPv4.

By the way, IPv6 is not set up here; I'll correct this oversight some other time.
XX.XX.XX.X5 (domain2) - no certificate. For client connections, domain1.com must be specified.
XX.XX.XX.X2 (domain3) - certificate exists; clients can connect using domain1.com or domain3.com.

File «/etc/dovecot/conf.d/15-lda.conf»

protocol lda {
  mail_plugins = $mail_plugins sieve
}

This will be necessary later for SpamAssassin.

File «/etc/dovecot/conf.d/20-imap.conf»

protocol imap {
  mail_plugins = $mail_plugins antispam
}

This is the antispam plugin. It is needed for training SpamAssassin during the transfer in/out of the «Spam» folder.

File «/etc/dovecot/conf.d/20-pop3.conf»

protocol pop3 {
}

There is simply such a file.

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

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

Nastavitev lmtp.

Datoteka «/etc/dovecot/conf.d/90-antispam.conf»

vtičnik {
  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
}

Nastavitve usposabljanja spamassasin ob premikanju v/iz mape «Spam».

Datoteka «/etc/dovecot/conf.d/90-sieve.conf»

vtičnik {
  sieve = ~/ .dovecot.sieve
  sieve_dir = ~/sieve
  sieve_after = /var/lib/dovecot/sieve/default.sieve
}

Datoteka, v kateri je navedeno, kaj storiti z dohodnimi sporočili.

Datoteka «/var/lib/dovecot/sieve/default.sieve»

zahteva ["fileinto", "mailbox"];

če glava :vsebuje "X-Spam-Flag" "DA" {
        fileinto :ustvari "Spam";
}

Treba je skompilirati datoteko: «sievec default.sieve».

Datoteka «/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
}

Navedba sql datotek za avtorizacijo.
In sama datoteka — kot način avtorizacije.

Datoteka «/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 ustreza podobnim nastavitvam za postfix.

Datoteka «/etc/dovecot/dovecot.conf»

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

Glavna datoteka za konfiguracijo.
Pomembno je, da tu določimo-dodamo protokole.

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

apt-get install spamassassin spamc

Namestimo pakete.

adduser spamd --disabled-login

Dodamo uporabnika, pod katerim bo deloval.

systemctl enable spamassassin.service

Omogočimo samodejni zagon storitve spamassassin ob zagonu.

Datoteka «/etc/default/spamassassin»:

CRON=1

Omogočimo samodejno posodabljanje pravil «privzeto».

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

Treba je ustvariti bazo podatkov mysql «sa» z uporabnikom «sa» in geslom «password» (zamenjati z nečim smiselnejšim).

report_safe — to pomeni, da se namesto elektronskega sporočila pošlje poročilo o sporočilu, ki je označeno kot spam.
use_bayes — to so nastavitve strojnega učenja spamassasin.

Preostale nastavitve spamassassin so bile že uporabljene v prejšnjem članku.

Splošna nastavitev «spamassassin».
O premikanju novih spam sporočil v IMAP mapo «Spam».
O preprosti povezavi Dovecot + SpamAssassin.
Priporočam, da preberete teorijo usposabljanja spamassassin pri premikanju sporočil v imap mape (in ne priporočam za uporabo).

============= Obrnite se na skupnost =============

Ravno tako bi rad dodal idejo v skupnost o tem, kako povečati raven zaščite prenesenih e-poštnih sporočil. Ko sem se tako poglobil v temo e-pošte.

Da bi imel uporabnik na svojem odjemalcu (Outlook, Thunderbird, vtičnik za brskalnik, ...) možnost ustvariti par ključev. Javni in zasebni. Javni — poslati v DNS. Zasebni — shraniti na odjemalcu. E-poštni strežniki bi znali uporabiti javni ključ za pošiljanje določenemu prejemniku.

In za zaščito pred spamom pri takih e-poštnih sporočilih (da, e-poštni strežnik ne bo mogel preveriti vsebine) bo treba uvesti 3 pravila:

  1. Obvezna pravi DKIM podpis, obvezni SPF, obvezni rDNS.
  2. Nevronska mreža za učenje proti spamu + baza podatkov na strani odjemalca.
  3. Algoritem za šifriranje bi moral biti tak, da bi morala pošiljajoča stran porabiti 100-krat več CPU moči za šifriranje kot sprejemajoča stran.

Poleg javnih e-poštnih sporočil — razviti standard o e-pošti-predlogu za 'začetek zaščitene komunikacije'. Eden od uporabnikov (e-poštni predal) pošlje drugemu e-poštnemu predalu sporočilo z priponko. V sporočilu je besedilo-predlog za začetek zaščitenega komunikacijskega kanala za dopisovanje in javni ključ lastnika e-poštnega predala (zasebni ključ pa na strani odjemalca).

Lahko bi celo ustvarili nekaj ključev posebej za vsako korespondenco. Uporabnik-prejemnik lahko sprejme to ponudbo in pošlje svoj javni ključ (tudi ustvarjen posebej za to korespondenco). Nato prvi uporabnik pošlje servisno kontrolno sporočilo (šifrirano z javnim ključem drugega uporabnika) — pri prejemu katerega lahko drugi uporabnik šteje, da je oblikovan komunikacijski kanal zanesljiv. Nato drugi uporabnik pošlje kontrolno sporočilo — in tako lahko prvi uporabnik prav tako šteje, da je oblikovan kanal zaščiten.

Za boj proti ujetju ključev na poti — je treba v protokolu predvideti možnost prenosa vsaj enega javnega ključa s pomočjo USB ključka.

In najpomembnejše — da vse to deluje (vprašanje 'kdaj bo to plačano?'):
Vnesite elektronske certifikate po ceni od 10 $ za 3 leta. Ti bodo omogočili pošiljatelju, da v DNS-u navede, da „moji javni ključi so tam“. In omogočili bodo začetek zaščitene povezave. Hkrati pa bo sprejemanje takšnih povezav brezplačno.
gmail končno monetizira svoje uporabnike. Za 10 $ v 3 letih - pravico do ustvarjanja zaščitenih kanalov za komunikacijo.

============= Zaključek =============

Za testiranje celotnega članka sem nameraval najeti namenski strežnik za mesec dni in kupiti domeno z SSL certifikatom.

Toda življenjske okoliščine so se tako zapletle, da se je ta postopek zavlekel za 2 meseca.
In ko je spet prišlo do prostega časa - sem se odločil objaviti članek tak, kot je, in ne tvegati, da bo objava odložena še za eno leto.

Če bo dovolj vprašanj tipa „tu ni dovolj podrobno opisano“ - potem se verjetno najdejo moči, da vzamem namenski strežnik z novo domeno in novim SSL certifikatom ter še podrobneje opišem in predvsem - razkrijem vse spregledane pomembne podrobnosti.

Prav tako bi želel prejeti mnenja o ideji o elektronskih certifikatih. Če se bo ideja odobrila - bom poskušal najti moči, da napišem osnutek za RFC.

Pri kopiranju velikih delov članka - navedite povezavo na ta članek.
Pri prevodu v kateri koli drug jezik - navedite povezavo na ta članek.
V angleski jezik se bom sam potrudil prevesti in pustil bom medsebojne povezave.


Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster