Ten artykuł dotyczy tego, jak skonfigurować nowoczesny serwer pocztowy.
Postfix + Dovecot. SPF + DKIM + rDNS. Z IPv6.
Z szyfrowaniem TSL. Z obsługą wielu domen – część z certyfikatem SSL.
Z ochroną przed spamem i wysokim wskaźnikiem antyspamowym wśród innych serwerów pocztowych.
Z obsługą wielu fizycznych interfejsów.
Z OpenVPN, do którego łączymy się przez IPv4, a który zapewnia IPv6.
Jeśli nie chcesz uczyć się wszystkich tych technologii, ale chcesz skonfigurować taki serwer – ten artykuł jest dla Ciebie.
Artykuł nie zawiera prób wyjaśnienia każdego szczegółu. Wyjaśnienia dotyczą tego, co zostało skonfigurowane nienormatywnie lub jest istotne z perspektywy użytkownika.
Motywacją do skonfigurowania serwera pocztowego jest moja długa marzenie. Może to brzmi głupio, ale IMHO, to znacznie lepsze niż marzenie o nowym samochodzie ulubionej marki.
Motywacja do skonfigurowania IPv6 jest podwójna. Specjalista IT musi stale uczyć się nowych technologii, aby przetrwać. Chciałbym wnieść swój skromny wkład w walkę z cenzurą.
Motywacja do skonfigurowania OpenVPN - tylko po to, aby IPv6 działał na lokalnej maszynie.
Motywacja do skonfigurowania wielu fizycznych interfejsów – mam na serwerze jeden interfejs „wolny, ale bez limitu”, a drugi „szybki, ale z taryfą”.
Motywacja do skonfigurowania Bind - mój dostawca oferuje niestabilny serwer DNS, a Google również czasem ma awarie. Chcę stabilnego serwera DNS do użytku osobistego.
Motywacja do napisania artykułu - szkic został napisany 10 miesięcy temu, a ja zaglądałem do niego już dwa razy. Jeśli nawet autor tego regularnie potrzebuje - to istnieje duża szansa, że inni też będą potrzebować.
Nie ma uniwersalnego rozwiązania dla serwera pocztowego. Ale postaram się napisać coś w rodzaju „zróbcie to w ten sposób, a gdy wszystko będzie działać jak należy – wyrzućcie to, co zbędne”.
Mam serwer kolokacyjny w firmie tech.ru. Można go porównać z OVH, Hetzner, AWS. Dla rozwiązania tego zadania współpraca z tech.ru będzie znacznie bardziej efektywna.
Na serwerze zainstalowany jest Debian 9.
Na serwerze są 2 interfejsy `eno1` i `eno2`. Pierwszy jest bez limitu, a drugi szybki odpowiednio.
Mam 3 statyczne adresy IP, XX.XX.XX.X0 oraz XX.XX.XX.X1 i XX.XX.XX.X2 na interfejsie `eno1` oraz XX.XX.XX.X5 na interfejsie `eno2`.
Mam pulę adresów IPv6 XXXX:XXXX:XXXX:XXXX::/64, które są przypisane do interfejsu `eno1`, a z niego XXXX:XXXX:XXXX:XXXX:1:2::/96 na moją prośbę przypisano do `eno2`.
Posiadam 3 domeny `domain1.com`, `domain2.com`, `domain3.com`. Dla `domain1.com` i `domain3.com` dostępny jest certyfikat SSL.
Posiadam konto Google, które chciałbym powiązać z skrzynką pocztową `vasya.pupkin@domain1.com` (odbieranie i wysyłanie wiadomości bezpośrednio z interfejsu Gmail).
Powinna być skrzynka pocztowa `support@domain2.com`, z której chcę mieć kopię wiadomości w Gmailu. Chciałbym również czasami wysłać coś w imieniu `support@domain2.com` przez interfejs webowy.
Powinna być skrzynka pocztowa `ivanov@domain3.com`, z której będzie korzystał Iwanow z swojego iPhone'a.
Wysyłane wiadomości muszą spełniać wszystkie nowoczesne wymagania dotyczące antyspamu.
Powinien być najwyższy poziom szyfrowania przewidziany w publicznych sieciach.
Powinna być obsługa IPv6 zarówno do wysyłania, jak i odbierania wiadomości.
Powinien być SpamAssassin, który nigdy nie usunie wiadomości. Powinien jedynie odrzucać, omijać lub wysyłać do folderu IMAP 'Spam'.
Powinno być skonfigurowane auto-uczenie SpamAssassin: jeśli przeniosę wiadomość do folderu 'Spam' — powinno nauczyć się tego; jeśli przeniosę wiadomość z folderu 'Spam' — również powinno się nauczyć. Wyniki uczenia SpamAssassin powinny wpływać na trafność wiadomości w folderze 'Spam'.
Skrypty PHP powinny być w stanie wysyłać e-maile w imieniu dowolnej domeny na tym serwerze.
Powinien być serwis OpenVPN, z możliwością korzystania z IPv6 na kliencie, który nie ma IPv6.
Najpierw należy skonfigurować interfejsy i trasowanie, w tym IPv6.
Następnie trzeba będzie skonfigurować OpenVPN, który będzie łączył się przez IPv4 i zapewniał klientowi statyczny, rzeczywisty adres IPv6. Ten klient będzie miał dostęp do wszystkich usług IPv6 na serwerze oraz do wszelkich zasobów IPv6 w Internecie.
Następnie trzeba będzie skonfigurować Postfix do wysyłania wiadomości + SPF + DKIM + rDNS i inne podobne szczegóły.
Następnie trzeba będzie skonfigurować Dovecot i ustawić Multidomain.
Następnie trzeba będzie skonfigurować SpamAssassin i ustawić uczenie.
Na zakończenie zainstalować Bind.
============= Multi-interfejsy =============
Aby skonfigurować interfejsy, należy wpisać to w "/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::/80Te ustawienia można stosować na każdym serwerze w tech.ru (po niewielkim uzgodnieniu z pomocą techniczną) i od razu będzie działać jak należy.
Jeśli chodzi o doświadczenie w konfiguracji podobnych rzeczy dla Hetzner, OVH — tam jest inaczej. Trudniej.
eno1 — to nazwa karty sieciowej #1 (wolna, ale bez limitu).
eno2 — to nazwa karty sieciowej #2 (szybka, ale z taryfą).
tun0 — to jest nazwa wirtualnej karty sieciowej 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 — brama IPv4.
XXXX:XXXX:XXXX:XXXX::/64 — IPv6 dla całego serwera.
XXXX:XXXX:XXXX:XXXX:1:2::/96 — IPv6 dla eno2, a wszystkie inne połączenia przechodzą przez eno1.
XXXX:XXXX:XXXX:XXXX::1 — brama IPv6 (warto zauważyć, że można/należy to zrobić inaczej. Wskazać IPv6 przełącznika).
dns-nameservers — wskazane są 127.0.0.1 (ponieważ bind jest zainstalowany lokalnie) i 213.248.1.6 (to jest od tech.ru).
„table eno1t” i „table eno2t” — istotą tych reguł routingu jest to, aby ruch, który wszedł przez eno1, opuszczał go, a ruch, który wszedł przez eno2, opuszczał go. A także połączenia inicjowane przez serwer opuszczały przez eno1.
ip route add default via XX.XX.XX.1 table eno1tTą komendą określamy, że każdy nieznany ruch, który pasuje do jakiejkolwiek reguły oznaczonej „table eno1t” — kierowany jest do interfejsu eno1.
ip route add XX.XX.XX.0/24 dev eno1 src XX.XX.XX.X0 table eno1tTą komendą określamy, że każdy ruch inicjowany przez serwer ma być kierowany do interfejsu eno1.
ip rule add table eno1t from XX.XX.XX.X0
ip rule add table eno1t to XX.XX.XX.X0Tą komendą określamy same reguły oznaczania ruchu.
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.X2Ten blok definiuje drugi adres IPv4 dla interfejsu eno1.
ip route add 10.8.0.0/24 dev tun0 src XX.XX.XX.X1 table eno1t Tą komendą określamy trasę od klientów OpenVPN do lokalnych IPv4 z wyjątkiem XX.XX.XX.X0.
Dlaczego ta komenda wystarcza dla wszystkich IPv4 — nadal nie rozumiem.
iface eno1 inet6 static
address XXXX:XXXX:XXXX:XXXX:1:1::/64
gateway XXXX:XXXX:XXXX:XXXX::1Określamy adres dla samego interfejsu. Serwer będzie go używał jako „adres wychodzący”. Nie będzie wykorzystywany w żaden inny sposób.
Dlaczego podano „:1:1::” tak skomplikowanie? Aby OpenVPN działał poprawnie i tylko w tym celu. O tym więcej później.
Co do bramy — działa, więc w porządku. Ale poprawnie — tutaj trzeba wskazać IPv6 przełącznika, do którego jest podłączony serwer.
Jednakże dlaczego IPv6 przestaje działać, gdy to robię. Prawdopodobnie to jakieś fiksacje tech.ru.
ip -6 addr add XXXX:XXXX:XXXX:XXXX:1:1:1:1/64 dev $IFACETo dodanie adresu IPv6 do interfejsu. Jeśli potrzebujesz setek adresów — oznacza to setki linii w tym pliku.
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::/80Zaznaczyłem adresy i podsieci wszystkich interfejsów, aby było to czytelne.
eno1 — musi mieć obowiązkowo „/64” — ponieważ to cały nasz pul adresów.
tun0 — podsieć musi być obowiązkowo większa niż eno1. W przeciwnym razie nie będzie można skonfigurować bramy IPv6 dla klientów OpenVPN.
eno2 — podsieć musi być obowiązkowo większa niż tun0. W przeciwnym razie klienci OpenVPN nie będą mogli uzyskać dostępu do lokalnych adresów IPv6.
Aby to zobrazować, wybrałem krok podsieci 16, ale w razie potrzeby można nawet ustawić krok równy „1”.
Odpowiednio 64+16 = 80, a 80+16 = 96.Dla jeszcze większej klarowności:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — to adresy, które powinny być przypisane do konkretnych witryn lub usług na interfejsie eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — to adresy, które powinny być przypisane do konkretnych witryn lub usług na interfejsie eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — to adresy, które powinny być przypisane klientom OpenVPN lub używane jako adresy serwisowe OpenVPN.
Do konfiguracji sieci — musi być możliwość ponownego uruchomienia serwera.
Zmiany IPv4 są przyjmowane podczas wykonywania (koniecznie owinąć w screen — w przeciwnym razie to polecenie po prostu zrzuci sieć na serwerze):
/etc/init.d/networking restartDo pliku „/etc/iproute2/rt_tables” dodać na końcu:
100 eno1t
101 eno2t Bez tego nie można używać niestandardowych tabel w pliku „/etc/network/interfaces”.
Numery muszą być unikalne i mniejsze niż 65535.
Zmiany IPv6 można łatwo wprowadzać bez ponownego uruchamiania, ale w tym celu trzeba nauczyć się przynajmniej trzech poleceń:
ip -6 addr ...
ip -6 route ...
ip -6 neigh ...Konfiguracja „/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 = 1To ustawienia „sysctl” mojego serwera. Zaznaczam to jako ważne.
net.ipv4.ip_forward = 1Bez tego OpenVPN nie będzie działać.
net.ipv6.ip_nonlocal_bind = 1Każdy, kto spróbuje bindować IPv6 (na przykład nginx) zaraz po tym, jak interfejs został przypisany — otrzyma błąd. Oznacza to, że taki adres jest niedostępny.
Aby uniknąć takiej sytuacji, stosuje się takie ustawienie.
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1Bez tych ustawień ruch IPv6 od klientów OpenVPN nie wychodzi w świat.
Inne ustawienia albo nie mają znaczenia, albo nie pamiętam, po co są.
Ale na wszelki wypadek zostawiam „jak jest”.
Aby zmiany w tym pliku zostały wprowadzone bez ponownego uruchamiania serwera — należy wykonać polecenie:
sysctl -pBardziej szczegółowo o zasadach „tabeli”:
============= OpenVPN =============
OpenVPN IPv4 nie działa bez iptables.
Moje iptables do VPN wyglądają tak:
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 mój statyczny adres IPv4 lokalnej maszyny.
10.8.0.0/24 — sieć IPv4 openvpn. Adresy IPv4 dla klientów openvpn.
Kolejność reguł jest ważna.
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 DROPTo ograniczenie, aby tylko ja ze swojego statycznego IP mógł skorzystać z OpenVPN.
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
-- lub --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADEAby umożliwić przesyłanie pakietów IPv4 między klientami OpenVPN a internetem — należy zastosować jedną z tych komend.
W różnych przypadkach jedna z opcji nie odpowiada.
Dla mojego przypadku obie komendy są odpowiednie.
Po zapoznaniu się z dokumentacją wybrałem pierwszą opcję, ponieważ zużywa mniej CPU.
Aby wszystkie ustawienia iptables zostały załadowane po restarcie — muszą zostać gdzieś zapisane.
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6Takie nazwy nie są przypadkowe. Używa ich pakiet «iptables-persistent».
apt-get install iptables-persistentInstalacja głównego pakietu OpenVPN:
apt-get install openvpn easy-rsaUstawimy szablon dla certyfikatów (podstawiając swoje wartości):
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
ln -s openssl-1.0.0.cnf openssl.cnfEdytujemy ustawienia szablonu certyfikatów:
mcedit vars# To są domyślne wartości dla pól
# które będą umieszczone w certyfikacie.
# Nie pozostawiaj żadnego z tych pól pustych.
export KEY_COUNTRY="PL"
export KEY_PROVINCE="Kraków"
export KEY_CITY="Dębice"
export KEY_ORG="Własne"
export KEY_EMAIL="admin@domena1.com"
export KEY_OU="VPN"
# Pole Subject X509
export KEY_NAME="serwer"
...Tworzymy certyfikat serwera:
cd ~/openvpn-ca
source vars
./clean-all
./build-ca
./build-key-server server
./build-dh
openvpn --genkey --secret keys/ta.keyPrzygotujemy możliwość tworzenia finalnych plików „client-name.opvn”:
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-CBCPrzygotujemy skrypt, który połączy wszystkie pliki w jeden plik opvn.
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}.ovpnTworzymy pierwszego klienta OpenVPN:
cd ~/openvpn-ca
source vars
./build-key client-name
cd ~/client-configs
./make_config.sh client-namePlik „~/client-configs/files/client-name.ovpn” wysyłamy na urządzenie klienta.
Dla klientów iOS będzie trzeba wykonać sztuczkę:
Zawartość tagu «tls-auth» powinna być bez komentarzy.
Należy również dodać «key-direction 1» bezpośrednio przed tagiem «tls-auth».
Skonfigurujmy konfigurację serwera OpenVPN:
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-CBCTo jest potrzebne, aby przypisać statyczny adres każdemu klientowi (nie jest to obowiązkowe, ale ja to stosuję):
# Client config dir
client-config-dir /etc/openvpn/ccdNajtrudniejszy i kluczowy szczegół.
Niestety OpenVPN jeszcze nie potrafi samodzielnie konfigurować bramy IPv6 dla klientów.
Trzeba to ręcznie przekazywać dla każdego 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"Plik «/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 eno1Plik «/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 eno1Oba skrypty korzystają z pliku «/etc/openvpn/variables»:
# Subnet
prefix=XXXX:XXXX:XXXX:XXXX:2:
# netmask
prefixlen=112Dlaczego tu tak napisano — trudno mi przypomnieć.
Obecnie wygląda dziwnie netmask = 112 (tutaj powinno być 96).
I prefix dziwny, nie odpowiada sieci tun0.
Ale dobrze, zostawiam «jak jest».
cipher DES-EDE3-CBCTo kwestia gustu — wybrałem taki sposób szyfrowania połączenia.
============= Postfix =============
Instalacja głównego pakietu:
apt-get install postfixPodczas instalacji wybrać «internet-site».
Mój «/etc/postfix/main.cf» wygląda tak:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# Dołączenie .domain to zadanie MUA.
append_dot_mydomain = no
readme_directory = no
# Zobacz http://www.postfix.org/COMPATIBILITY_README.html -- domyślnie 2 przy
# świeżych instalacjach.
compatibility_level = 2
# Parametry TLS
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 przechowywania
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
# Ustawienia SMTP-Auth
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
# Adres IP na domenę
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcrePrzyjrzyjmy się szczegółom tej konfiguracji.
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.keyWedług użytkowników Habr ten blok zawiera `dezinformację i nieprawdziwe tezy`.Dopiero po 8 latach mojej kariery zacząłem rozumieć, jak działa SSL.
Dlatego pozwolę sobie opisać, jak korzystać z SSL (nie odpowiadając na pytania „Jak to działa?” i „Dlaczego to działa?”).
Podstawą współczesnego szyfrowania jest stworzenie pary kluczy (dwie bardzo długie ciągi znaków).
Jeden „klucz” jest prywatny, a drugi klucz „publiczny”. Prywatny klucz przechowujemy starannie w sekrecie. Klucz publiczny rozdawany jest wszystkim chętnym.
Za pomocą klucza publicznego można zaszyfrować ciąg tekstu w taki sposób, że odszyfrować go może tylko właściciel klucza prywatnego.
I oto cała podstawa technologii.Krok №1 — strony https.
Przeglądarka przy próbie połączenia z witryną otrzymuje od serwera WWW informację, że strona jest https i dlatego pyta o klucz publiczny.
Serwer WWW przekazuje klucz publiczny. Przeglądarka wykorzystując klucz publiczny szyfruje żądanie http i je wysyła.
Zawartość żądania http może odczytać tylko ten, kto ma klucz prywatny, czyli tylko serwer, do którego następuje zapytanie.
Żądanie http zawiera przynajmniej URI. Dlatego jeśli w danym kraju próbują ograniczyć dostęp nie do całej witryny, a do konkretnej strony — to dla witryn https jest to niemożliwe.Krok nr 2 — zaszyfrowana odpowiedź.
Serwer WWW daje odpowiedź, którą z łatwością mogą odczytać po drodze.
Rozwiązanie jest niezwykle proste — przeglądarka lokalnie tworzy taką samą parę kluczy prywatny-publiczny dla każdej witryny https.
Razem z żądaniem klucza publicznego witryny wysyła swój lokalny klucz publiczny.
Serwer WWW zapamiętuje go i przy wysyłaniu odpowiedzi http szyfruje tę odpowiedź identyfikującym kluczem publicznym konkretnego klienta.
Teraz odpowiedź http może odszyfrować tylko posiadacz klucza prywatnego przeglądarki klienta (czyli sam klient).Krok nr 3 — ustanowienie zabezpieczonego połączenia przez publiczny kanał.
W przykładzie nr 2 istnieje luka — nic nie uniemożliwia niepowołanym osobom przechwycenia żądania http i edytowania informacji o kluczu publicznym.
W ten sposób pośrednik będzie mógł doskonale widzieć całą zawartość wysyłanych i odbieranych wiadomości, dopóki nie zmieni się kanał komunikacji.
Walka z tym jest niezwykle prosta — wystarczy wysłać klucz publiczny przeglądarki jako wiadomość zaszyfrowaną kluczem publicznym serwera WWW.
Serwer WWW wówczas na początku wysyła odpowiedź w stylu „twój klucz publiczny jest taki” i szyfruje tę wiadomość tym samym kluczem publicznym.
Przeglądarka sprawdza odpowiedź — jeśli z wiadomością „twój klucz publiczny jest taki” — to daje to 100% gwarancję, że ten kanał komunikacji jest bezpieczny.
Jak bardzo bezpieczny?
Samo stworzenie takiego bezpiecznego kanału komunikacji przebiega w czasie ping*2. Na przykład 20ms.
Cyberprzestępca musi albo wcześniej mieć klucz prywatny jednej ze stron. Albo złamać klucz prywatny w kilka milisekund.
Złamanie jednego nowoczesnego klucza prywatnego zajmie dziesięciolecia na superkomputerze.Krok nr 4 — publiczna baza danych kluczy publicznych.
Oczywiście, że w całej tej historii istnieje możliwość dla cyberprzestępcy siedzącego na kanale komunikacyjnym między klientem a serwerem.
Możliwość przedstawienia się klientowi jako serwerowi, a serwerowi jako klientowi. I zasymulować parę kluczy w obie strony.
Wtedy napastnik będzie widział cały ruch i będzie miał możliwość 'przeeditowania' ruchu.
Na przykład zmienić adres, dokąd wysyłać pieniądze lub skopiować hasło do bankowości internetowej, bądź zablokować 'niepożądane' treści.
Aby walczyć z takimi napastnikami, stworzono publiczną bazę danych z publicznymi kluczami dla każdej strony https.
Każda przeglądarka 'wie' o istnieniu około 200 takich baz danych. Jest to wbudowane w każdą przeglądarkę.
'Wiedza' jest potwierdzona publicznym kluczem każdego certyfikatu. Oznacza to, że połączenie z każdym konkretnym centrum certyfikacji nie może być sfałszowane.Teraz istnieje proste zrozumienie, jak korzystać z SSL dla https.
Jeśli użyjesz trochę wyobraźni — stanie się jasne, jak agencje specjalne mogą w tym schemacie coś złamać. Ale będzie to wymagało ogromnych wysiłków z ich strony.
A dla organizacji mniejszych od NSA czy CIA — praktycznie niemożliwe jest złamanie obecnego poziomu ochrony nawet dla VIP-ów.Dodatkowo dodam o połączeniach ssh. Nie ma tam żadnych publicznych kluczy, co zrobić. Problem rozwiązujemy na dwa sposoby.
Opcja ssh-po-hasło:
Podczas pierwszego połączenia klient ssh musi ostrzec, że mamy nowy publiczny klucz od serwera ssh.
A podczas dalszych połączeń, jeśli pojawi się ostrzeżenie 'nowy publiczny klucz od serwera ssh' — oznacza to, że próbują cię podsłuchiwać.
Lub podczas pierwszego połączenia byłeś podsłuchiwany, a teraz rozmawiasz z serwerem bez pośredników.
Właściwie z powodu łatwości, szybkości i braku wysiłku w odkrywaniu faktu podsłuchu — ta metoda atakowania stosowana jest tylko w wyjątkowych przypadkach pod konkretnego klienta.Opcja ssh-po-kluczu:
Bierzemy pamięć flash, zapisujemy na niej klucz prywatny dla serwera ssh (są na to terminy i mnóstwo istotnych szczegółów, ale piszę o edukacji, a nie instrukcji użytkowania).
Publiczny klucz zostawiamy na maszynie, gdzie będzie klient ssh i również trzymamy go w sekrecie.
Przynosimy pamięć flash do serwera, wkładamy, kopiujemy klucz prywatny, a pamięć flash palimy i rozsypujemy proch po wietrze (lub przynajmniej formatujemy, wypełniając zerami).
I to wszystko — po takiej operacji niemożliwe będzie złamanie takiego połączenia ssh. Oczywiście po około 10 latach na superkomputerze można by było zobaczyć ruch — ale to osobna historia.Przepraszam za offtop.
A więc, teraz gdy znamy teorię. Opowiem o procesie tworzenia certyfikatu ssl.
Za pomocą «openssl genrsa» tworzymy klucz prywatny i «szablony» dla klucza publicznego.
«szablony» wysyłamy do zewnętrznej firmy, której płacimy około $9 za najprostszy certyfikat.
Po kilku godzinach otrzymujemy od tej zewnętrznej firmy nasz «klucz publiczny» oraz zestaw kilku innych kluczy publicznych.
Dlaczego płacimy zewnętrznej firmie za przygotowanie mojego klucza publicznego — to osobne pytanie, tutaj tego nie rozważamy.
Teraz jasne, o co chodzi w napisie:
smtpd_tls_key_file=\/etc\/ssl\/domain1.com.2018.key W folderze «\/etc\/ssl» znajdują się wszystkie pliki dotyczące ssl.
domain1.com — nazwa domeny.
2018 — rok utworzenia kluczy.
«key» — oznaczenie, że plik jest kluczem prywatnym.
A sens tego pliku:
smtpd_tls_cert_file=\/etc\/ssl\/domain1.com.2018.chained.crt
domain1.com — nazwa domeny.
2018 — rok utworzenia kluczy.
chained — oznaczenie, że jest to łańcuch kluczy publicznych (pierwszy — nasz klucz publiczny, a pozostałe — otrzymane od firmy, która wydała klucz publiczny).
crt — oznaczenie, że jest to gotowy certyfikat (klucz publiczny z wyjaśnieniami technicznymi).
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1To ustawienie w tym przypadku nie jest używane, ale napisane dla przykładu.
Ponieważ błąd w tym parametrze doprowadzi do wysyłania spamu z twojego serwera (bez twojej woli).
Potem udowadniaj wszystkim, że nie jesteś winny.
recipient_delimiter = +Możliwe, że wielu nie wie, więc to jest standardowy symbol do segregacji wiadomości, a to wspiera większość nowoczesnych serwerów pocztowych.
Na przykład, jeśli masz skrzynkę pocztową «username@gmail.com», spróbuj wysłać do «username+spam@gmail.com» — zobacz, co z tego wyjdzie.
inet_protocols = ipv4Może to wprowadzać w błąd.
Ale nie jest to przypadek. Każda nowa domena — domyślnie tylko IPv4, potem włączam IPv6 dla każdej z osobna.
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 Tutaj ustawiamy, że cały przychodzący ruch e-mailowy idzie do dovecot.
A zasady dla domen, skrzynek pocztowych, aliasów — sprawdzać w bazie danych.
/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 = yesTeraz postfix wie, że może przyjmować pocztę do dalszego wysyłania tylko po autoryzacji z dovecot.
Nie do końca rozumiem, po co to tutaj dublować. Przecież już wskazaliśmy w „virtual_transport” wszystko, co potrzeba.
Ale system postfix jest bardzo stary — prawdopodobnie to jest pozostałość z dawnych czasów.
smtpd_recipient_restrictions =
...
smtpd_helo_restrictions =
...
smtpd_client_restrictions =
...To trzeba skonfigurować indywidualnie dla każdego serwera pocztowego.
Mam trzy serwery pocztowe, a te ustawienia są bardzo różne ze względu na różne wymagania użytkowania.
Konfigurację trzeba robić starannie — inaczej spam wleje się do was lub, co gorsza, spam zacznie wychodzić od was.
# SPF
policyd-spf_time_limit = 3600Konfiguracja dla jakiegoś wtyczki związanej z weryfikacją SPF przychodzących wiadomości.
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sockUstawienie, że wszystkie wychodzące wiadomości musimy zaopatrzyć podpisem DKIM.
# IP address per domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcreTo kluczowy detal w trasowaniu wiadomości przy wysyłaniu ich z skryptów php.
Plik „/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:Po lewej stronie — wyrażenia regularne. Po prawej — etykieta, którą oznacza się wiadomość.
Postfix zgodnie z etykietą — uwzględni jeszcze kilka linii konfiguracji dla konkretnej wiadomości.Jak dokładnie zostanie przekonfigurowany postfix dla konkretnej wiadomości — będzie wskazane w „master.cf”.
Linie 4, 5, 6 — są najważniejsze. Od jakiej domeny wysyłamy wiadomość — taką etykietę stawiamy.
Jednak nie zawsze w skryptach php w starym kodzie wskazane jest pole „from”. Wtedy z pomocą przychodzi nazwa użytkownika.Artykuł jest i tak obszerny — nie chciałbym odciągać uwagi na konfigurację nginx+fpm.
Krótko — dla każdej strony ustalamy swojego właściciela linux-usera. I odpowiednio swoje fpm-pool.
Fpm-pool wykorzystuje dowolną wersję php (to wspaniałe, gdy na jednym serwerze bez problemu dla sąsiednich stron można używać różnych wersji php i nawet różnych php.ini).
Tak więc konkretny linux-user „www-domain2” ma stronę domain2.com. Na tej stronie znajduje się kod wysyłania wiadomości bez wskazania pola from.
Nawet w takim przypadku wiadomości będą wychodzić poprawnie i nigdy nie trafią do spamu.
Mój „/etc/postfix/master.cf” wygląda tak:
...
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 Plik nie został w całości przedstawiony — jest już bardzo duży.
Zaznaczyłem tylko to, co zostało zmienione.
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}To ustawienia związane ze spamassassin, więcej o tym później.
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 Zezwalamy na połączenie z serwerem pocztowym przez port 587.
W tym celu konieczna jest autoryzacja.
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spfWłączamy sprawdzanie SPF.
apt-get install postfix-policyd-spf-pythonZainstalujemy pakiet do sprawdzania SPF.
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-domain1A to najciekawsze. To możliwość wysyłania wiadomości dla konkretnej domeny z konkretnego adresu IPv4/IPv6.
Robi się to w celu rDNS. rDNS polega na uzyskiwaniu pewnego ciągu na podstawie adresu IP.
A dla poczty ta możliwość jest wykorzystywana do potwierdzenia, że helo dokładnie odpowiada rDNS tego adresu, z którego wysłano e-mail.Jeśli helo nie odpowiada domenie poczty, w imieniu której wysłano wiadomość — przyznawane są punkty spamowe.
Helo nie odpowiada rDNS — przyznawane są duże punkty spamowe.
W związku z tym dla każdej domeny musi być własny adres IP.
Dla OVH — w konsoli jest możliwość wskazania rDNS.
Dla tech.ru — kwestia rozwiązywana jest przez wsparcie.
Dla AWS — kwestie są rozwiązywane przez wsparcie.
„inet_protocols” i „smtp_bind_address6” — to włączamy wsparcie dla IPv6.
Dla IPv6 również trzeba ustawić rDNS.
„syslog_name” — to dla wygody czytania logów.
Kupowanie certyfikatów .
.
============= Dovecot =============
apt-get install dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql dovecot-antispamKonfiguracja mysql, instalujemy same pakiety.
Plik „/etc/dovecot/conf.d/10-auth.conf”
disable_plaintext_auth = yes
auth_mechanisms = plain loginAutoryzacja tylko w zaszyfrowanej formie.
Plik „/etc/dovecot/conf.d/10-mail.conf”
mail_location = maildir:/var/mail/vhosts/%d/%nTutaj wskażemy miejsce przechowywania wiadomości.
Chcę, aby były przechowywane w plikach i grupowane według domen.
Plik „/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 jest główny plik ustawień dovecot.
Tutaj wyłączamy niechronione połączenia.
I włączamy połączenia zabezpieczone.
Plik „/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
}Konfigurujemy ssl. Ustalamy, że ssl — jest obowiązkowe.
I sam certyfikat. Ważny szczegół — dyrektywa „local”. Wskazuje, przy połączeniu do którego lokalnego IPv4 — jaki certyfikat ssl używać.Zresztą IPv6 nie jest tutaj skonfigurowany, poprawię to niedługo.
XX.XX.XX.X5 (domain2) — nie ma certyfikatu. Do połączenia klientów należy podać domain1.com.
XX.XX.XX.X2 (domain3) — certyfikat jest, do połączenia klientów można podać domain1.com lub domain3.com.
Plik „/etc/dovecot/conf.d/15-lda.conf”
protocol lda {
mail_plugins = $mail_plugins sieve
}To będzie potrzebne później dla spamassassin.
Plik „/etc/dovecot/conf.d/20-imap.conf”
protocol imap {
mail_plugins = $mail_plugins antispam
}To jest wtyczka antispam. Potrzebna do nauki spamassassing w momencie przenoszenia do/z folderu „Spam”.
Plik „/etc/dovecot/conf.d/20-pop3.conf”
protocol pop3 {
}Po prostu taki plik istnieje.
Plik „/etc/dovecot/conf.d/20-lmtp.conf”
protokół lmtp {
mail_plugins = $mail_plugins sieve
postmaster_address = admin@domain1.com
}Konfiguracja lmtp.
Plik „/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
}Ustawienia uczenia spamassassin w momencie przenoszenia do/z folderów „Spam”.
Plik „/etc/dovecot/conf.d/90-sieve.conf”
plugin {
sieve = ~/ .dovecot.sieve
sieve_dir = ~/sieve
sieve_after = /var/lib/dovecot/sieve/default.sieve
}Plik, w którym określono, co robić z przychodzącymi wiadomościami.
Plik „/var/lib/dovecot/sieve/default.sieve”
require ["fileinto", "mailbox"];
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Spam";
}Należy skompilować plik: „sievec default.sieve”.
Plik „/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
} Wskazanie plików sql do autoryzacji.
A sam plik — jako sposób autoryzacji.
Plik „/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 odpowiada podobnym ustawieniom dla postfix.
Plik „/etc/dovecot/dovecot.conf”
protocols = imap lmtp pop3
listen = *, ::
dict {
}
!include conf.d/*.conf
!include_try local.conf Główny plik konfiguracyjny.
Ważne jest to, co tutaj wskazujemy-dodajemy protokoły.
============= SpamAssassin =============
apt-get install spamassassin spamcZainstalujemy pakiety.
adduser spamd --disabled-loginDodamy użytkownika, w imieniu którego.
systemctl enable spamassassin.serviceWłączamy automatyczne uruchamianie serwisu spamassassin przy starcie.
Plik „/etc/default/spamassassin”:
CRON=1Włączamy automatyczne aktualizacje reguł „domyślnie”.
Plik „/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 passwordNależy utworzyć w bazie danych mysql „sa” z użytkownikiem „sa” z hasłem „password” (zastąpić na coś odpowiedniego).
report_safe — zamiast wiadomości będzie wysyłany raport o wiadomości spamowej.
use_bayes — to ustawienia uczenia maszynowego spamassassin.
Pozostałe ustawienia spamassassin były stosowane wcześniej w artykule.
.
.
.
.
============= Kontakt ze społecznością =============
Chciałbym jeszcze zgłosić pomysł do społeczności na temat zwiększenia poziomu bezpieczeństwa przesyłanych wiadomości. Skoro tak głęboko zająłem się tematem poczty.
Aby użytkownik mógł na swoim kliencie (Outlook, Thunderbird, wtyczka przeglądarki itd.) utworzyć parę kluczy. Klucz publiczny - wysłać do DNS. Klucz prywatny - zachować na kliencie. Serwery pocztowe miałyby umieć stosować klucz publiczny do wysyłania do konkretnego odbiorcy.
A w celu ochrony przed spamem przy takich listach (tak, serwer pocztowy nie będzie mógł sprawdzić treści) - trzeba wprowadzić 3 zasady:
- Obowiązkowy prawdziwy podpis DKIM, obowiązkowy SPF, obowiązkowy rDNS.
- Sieć neuronowa na temat szkolenia w zakresie przeciwdziałania spamowi + baza danych po jej stronie klienta.
- Algorytm szyfrowania powinien być taki, aby strona wysyłająca musiała wykorzystać 100 razy więcej mocy CPU na szyfrowanie niż strona odbierająca.
Oprócz publicznych wiadomości - opracować standard wiadomości-propozycji 'rozpocznij zabezpieczoną korespondencję'. Jeden z użytkowników (skrzynka pocztowa) wysyła do drugiej skrzynki pocztowej wiadomość z załącznikiem. W wiadomości znajduje się tekst-propozycja rozpoczęcia zabezpieczonego kanału komunikacji oraz klucz publiczny właściciela skrzynki pocztowej (prywatny klucz znajduje się po stronie klienta).
Można nawet tworzyć parę kluczy specjalnie dla każdej korespondencji. Użytkownik-odbiorca może zaakceptować tę propozycję i wysłać swój klucz publiczny (też stworzony specjalnie dla tej korespondencji). Następnie pierwszy użytkownik wysyła kontrolną wiadomość (szyfrowaną kluczem publicznym drugiego użytkownika) - po jej otrzymaniu drugi użytkownik może uznać, że utworzony kanał komunikacji jest niezawodny. Potem drugi użytkownik wysyła kontrolną wiadomość - i wtedy pierwszy użytkownik również może uznać, że utworzony kanał jest zabezpieczony.
Aby zapobiec przechwytywaniu kluczy w drodze - w protokole należy przewidzieć możliwość przesłania przynajmniej jednego klucza publicznego za pomocą pendrive'a.
I najważniejsze - żeby to wszystko działało (pytanie 'kto za to zapłaci?'):
Wprowadzenie certyfikatów e-mailowych kosztujących od 10 USD na 3 lata, które umożliwią nadawcy wskazanie w DNS, że „moje klucze publiczne znajdują się tam”. Będą one pozwalały na rozpoczęcie bezpiecznego połączenia, a przy tym przyjmowanie takich połączeń za darmo.
Gmail w końcu monetyzuje swoich użytkowników. Za 10 USD na 3 lata — prawo do tworzenia chronionych kanałów korespondencyjnych.
============= Podsumowanie =============
Aby przetestować cały artykuł, planowałem wynająć serwer dedykowany na miesiąc i kupić domenę z certyfikatem SSL.
Jednak okoliczności życiowe sprawiły, że ten temat się przedłużył o 2 miesiące.
I oto, gdy znów pojawiło się wolne czas — postanowiłem opublikować artykuł tak jak jest, zamiast ryzykować, że publikacja opóźni się o kolejny rok.
Jeśli pojawi się wystarczająco dużo pytań typu „tutaj nie opisano wystarczająco szczegółowo” — to prawdopodobnie znajdę siły, żeby wynająć dedykowany serwer z nową domeną i nowym certyfikatem SSL oraz jeszcze dokładniej opisać i co najważniejsze — odkryć wszystkie pominięte istotne szczegóły.
Chciałbym także uzyskać opinie na temat pomysłu dotyczącego certyfikatów e-mailowych. Jeśli pomysł przypadnie do gustu — postaram się znaleźć siły, aby napisać szkic dla RFC.
Podczas kopiowania dużych fragmentów artykułu — podaj link do tego artykułu.
Podczas tłumaczenia na jakikolwiek inny język — podaj link do tego artykułu.
Na język angielski sam postaram się przetłumaczyć i zostawię wzajemne linki.
Źródło: habr.com
