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

Ang artikulong ito ay tungkol sa kung paano mag-set up ng modernong mail server.
Postfix + Dovecot. SPF + DKIM + rDNS. Gamit ang IPv6.
Gamit ang TSL encryption. Sa suporta para sa maraming domain - bahagi ng isang tunay na SSL certificate.
Sa proteksyon ng antispam at mataas na rating ng antispam mula sa iba pang mga mail server.
Sinusuportahan ang maramihang mga pisikal na interface.
Sa OpenVPN, ang koneksyon kung saan ay sa pamamagitan ng IPv4, at nagbibigay ng IPv6.

Kung hindi mo gustong matutunan ang lahat ng mga teknolohiyang ito, ngunit nais mong mag-set up ng ganoong server, kung gayon ang artikulong ito ay para sa iyo.

Ang artikulo ay hindi nagtatangkang ipaliwanag ang bawat detalye. Ang paliwanag ay napupunta sa kung ano ang hindi naka-configure bilang pamantayan o mahalaga mula sa pananaw ng mamimili.

Ang motibasyon na mag-set up ng mail server ay matagal ko nang pangarap. Ito ay maaaring mukhang hangal, ngunit IMHO, ito ay mas mahusay kaysa sa pangangarap ng isang bagong kotse mula sa iyong paboritong brand.

Mayroong dalawang motibasyon para sa pag-set up ng IPv6. Kailangang patuloy na matuto ng mga bagong teknolohiya ang isang IT specialist upang mabuhay. Nais kong gawin ang aking katamtamang kontribusyon sa paglaban sa censorship.

Ang motibasyon para sa pag-set up ng OpenVPN ay para lang gumana ang IPv6 sa lokal na makina.
Ang pagganyak para sa pag-set up ng ilang mga pisikal na interface ay na sa aking server ay mayroon akong isang interface na "mabagal ngunit walang limitasyon" at isa pang "mabilis ngunit may taripa".

Ang motibasyon para sa pag-set up ng mga setting ng Bind ay ang aking ISP ay nagbibigay ng isang hindi matatag na DNS server, at kung minsan ay nabigo din ang google. Gusto ko ng isang matatag na DNS server para sa personal na paggamit.

Pagganyak na magsulat ng isang artikulo - Nagsulat ako ng draft 10 buwan na ang nakakaraan, at dalawang beses ko na itong tiningnan. Kahit na regular itong kailangan ng may-akda, malaki ang posibilidad na kakailanganin din ito ng iba.

Walang pangkalahatang solusyon para sa isang mail server. Ngunit susubukan kong magsulat ng isang bagay tulad ng "gawin ito at pagkatapos, kapag gumagana ang lahat ayon sa nararapat, itapon ang mga karagdagang bagay."

Ang kumpanyang tech.ru ay mayroong Colocation server. Posibleng ihambing sa OVH, Hetzner, AWS. Upang malutas ang problemang ito, ang pakikipagtulungan sa tech.ru ay magiging mas epektibo.

Naka-install ang Debian 9 sa server.

Ang server ay may 2 interface na `eno1` at `eno2`. Ang una ay walang limitasyon, at ang pangalawa ay mabilis, ayon sa pagkakabanggit.

Mayroong 3 static na IP address, XX.XX.XX.X0 at XX.XX.XX.X1 at XX.XX.XX.X2 sa interface ng `eno1` at XX.XX.XX.X5 sa interface ng `eno2` .

Available XXXX:XXXX:XXXX:XXXX::/64 isang pool ng mga IPv6 address na itinalaga sa `eno1` na interface at mula rito XXXX:XXXX:XXXX:XXXX:1:2::/96 ay itinalaga sa `eno2` sa aking kahilingan.

Mayroong 3 domain na `domain1.com`, `domain2.com`, `domain3.com`. Mayroong SSL certificate para sa `domain1.com` at `domain3.com`.

Mayroon akong Google account na gusto kong i-link ang aking mailbox[protektado ng email]` (pagtanggap ng mail at pagpapadala ng mail nang direkta mula sa interface ng gmail).
Dapat mayroong mailbox`[protektado ng email]`, isang kopya ng email kung saan gusto kong makita sa aking gmail. At bihirang makapagpadala ng isang bagay sa ngalan ng `[protektado ng email]` sa pamamagitan ng web interface.

Dapat mayroong mailbox`[protektado ng email]`, na gagamitin ni Ivanov mula sa kanyang iPhone.

Ang mga ipinadalang email ay dapat sumunod sa lahat ng modernong kinakailangan sa antispam.
Dapat mayroong pinakamataas na antas ng pag-encrypt na ibinigay sa mga pampublikong network.
Dapat mayroong suporta sa IPv6 para sa parehong pagpapadala at pagtanggap ng mga sulat.
Dapat mayroong SpamAssassin na hinding-hindi magtatanggal ng mga email. At ito ay talbog o lalaktawan o ipapadala sa folder na "Spam" ng IMAP.
Dapat na i-configure ang awtomatikong pag-aaral ng SpamAssassin: kung ililipat ko ang isang sulat sa folder ng Spam, matututo ito mula rito; kung ililipat ko ang isang liham mula sa folder ng Spam, matututo ito mula rito. Ang mga resulta ng pagsasanay sa SpamAssassin ay dapat makaimpluwensya kung mapupunta ang sulat sa folder ng Spam.
Ang mga script ng PHP ay dapat na makapagpadala ng mail sa ngalan ng anumang domain sa isang ibinigay na server.
Dapat mayroong isang openvpn na serbisyo, na may kakayahang gumamit ng IPv6 sa isang kliyente na walang IPv6.

Una kailangan mong i-configure ang mga interface at pagruruta, kabilang ang IPv6.
Pagkatapos ay kakailanganin mong i-configure ang OpenVPN, na kumonekta sa pamamagitan ng IPv4 at magbibigay sa kliyente ng isang static-real IPv6 address. Ang kliyenteng ito ay magkakaroon ng access sa lahat ng IPv6 services sa server at access sa anumang IPv6 resources sa Internet.
Pagkatapos ay kakailanganin mong i-configure ang Postfix upang magpadala ng mga titik + SPF + DKIM + rDNS at iba pang katulad na maliliit na bagay.
Pagkatapos ay kakailanganin mong i-configure ang Dovecot at i-configure ang Multidomain.
Pagkatapos ay kakailanganin mong i-configure ang SpamAssassin at i-configure ang pagsasanay.
Panghuli, i-install ang Bind.

============= Multi-interface =============

Upang i-configure ang mga interface, kailangan mong isulat ito sa "/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

Ang mga setting na ito ay maaaring ilapat sa anumang server sa tech.ru (na may kaunting koordinasyon sa suporta) at agad itong gagana ayon sa nararapat.

Kung mayroon kang karanasan sa pag-set up ng mga katulad na bagay para sa Hetzner, OVH, iba ito doon. Mas mahirap.

eno1 ay ang pangalan ng network card #1 (mabagal ngunit walang limitasyon).
eno2 ay ang pangalan ng network card #2 (mabilis, ngunit may taripa).
Ang tun0 ay ang pangalan ng virtual network card mula sa OpenVPN.
XX.XX.XX.X0 - IPv4 #1 sa eno1.
XX.XX.XX.X1 - IPv4 #2 sa eno1.
XX.XX.XX.X2 - IPv4 #3 sa eno1.
XX.XX.XX.X5 - IPv4 #1 sa eno2.
XX.XX.XX.1 - IPv4 gateway.
XXXX:XXXX:XXXX:XXXX::/64 - IPv6 para sa buong server.
XXXX:XXXX:XXXX:XXXX:1:2::/96 - IPv6 para sa eno2, lahat ng iba pa mula sa labas ay napupunta sa eno1.
XXXX:XXXX:XXXX:XXXX::1 — IPv6 gateway (karapat-dapat tandaan na ito ay maaari/dapat gawin sa ibang paraan. Tukuyin ang IPv6 switch).
dns-nameservers - 127.0.0.1 ay ipinahiwatig (dahil ang bind ay naka-install nang lokal) at 213.248.1.6 (ito ay mula sa tech.ru).

“table eno1t” at “table eno2t” - ang kahulugan ng mga rutang ito ay ang trapikong pumapasok sa pamamagitan ng eno1 -> ay aalis dito, at ang trapikong pumapasok sa pamamagitan ng eno2 -> ay aalis dito. At ang mga koneksyon na pinasimulan ng server ay dadaan sa eno1.

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

Sa utos na ito, tinukoy namin na ang anumang hindi maintindihang trapiko na napapailalim sa anumang panuntunang may markang “table eno1t” -> ipapadala sa interface ng eno1.

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

Sa utos na ito, tinukoy namin na ang anumang trapiko na pinasimulan ng server ay dapat na idirekta sa interface ng eno1.

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

Sa utos na ito itinakda namin ang mga panuntunan para sa pagmamarka ng trapiko.

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

Tinutukoy ng block na ito ang pangalawang IPv4 para sa interface ng eno1.

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

Sa utos na ito, itinakda namin ang ruta mula sa mga kliyente ng OpenVPN patungo sa lokal na IPv4 maliban sa XX.XX.XX.X0.
Hindi ko pa rin maintindihan kung bakit sapat ang command na ito para sa lahat ng IPv4.

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

Dito namin itinakda ang address para sa mismong interface. Gagamitin ito ng server bilang isang "papalabas" na address. Hindi na muling gagamitin sa anumang paraan.

Bakit napakakomplikado ng ":1:1::"? Upang gumana nang tama ang OpenVPN at para lamang dito. Higit pa tungkol dito mamaya.

Sa paksa ng gateway - ganyan ito gumagana at ayos lang. Ngunit ang tamang paraan ay ipahiwatig dito ang IPv6 ng switch kung saan nakakonekta ang server.

Gayunpaman, sa ilang kadahilanan ay hihinto sa paggana ang IPv6 kung gagawin ko ito. Marahil ito ay isang uri ng problema sa tech.ru.

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

Ito ay nagdaragdag ng IPv6 address sa interface. Kung kailangan mo ng isang daang address, nangangahulugan iyon ng isang daang linya sa file na ito.

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

Nabanggit ko ang mga address at subnet ng lahat ng mga interface para maging malinaw ito.
eno1 - dapat ay "/64" - dahil ito ang aming buong pool ng mga address.
tun0 - ang subnet ay dapat na mas malaki kaysa sa eno1. Kung hindi, hindi posibleng mag-configure ng IPv6 gateway para sa mga kliyente ng OpenVPN.
eno2 - ang subnet ay dapat na mas malaki kaysa sa tun0. Kung hindi, hindi maa-access ng mga kliyente ng OpenVPN ang mga lokal na IPv6 address.
Para sa kalinawan, pumili ako ng subnet na hakbang na 16, ngunit kung nais mo, maaari mo ring gawin ang "1" na hakbang.
Alinsunod dito, 64+16 = 80, at 80+16 = 96.

Para sa mas higit na kalinawan:
Ang XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY ay mga address na dapat italaga sa mga partikular na site o serbisyo sa eno1 interface.
Ang XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY ay mga address na dapat italaga sa mga partikular na site o serbisyo sa eno2 interface.
Ang XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY ay mga address na dapat italaga sa mga kliyente ng OpenVPN o gamitin bilang mga address ng serbisyo ng OpenVPN.

Upang i-configure ang network, dapat na posible na i-restart ang server.
Ang mga pagbabago sa IPv4 ay kinuha kapag naisakatuparan (siguraduhing i-wrap ito sa screen - kung hindi, ang utos na ito ay mag-crash lang sa network sa server):

/etc/init.d/networking restart

Idagdag sa dulo ng file na "/etc/iproute2/rt_tables":

100 eno1t
101 eno2t

Kung wala ito, hindi ka makakagamit ng mga custom na talahanayan sa "/etc/network/interfaces" na file.
Ang mga numero ay dapat na natatangi at mas mababa sa 65535.

Ang mga pagbabago sa IPv6 ay madaling mabago nang hindi nagre-reboot, ngunit para magawa ito kailangan mong matutunan ang hindi bababa sa tatlong utos:

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

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

Ito ang mga setting ng "sysctl" ng aking server. Hayaan akong ituro ang isang bagay na mahalaga.

net.ipv4.ip_forward = 1

Kung wala ito, hindi gagana ang OpenVPN.

net.ipv6.ip_nonlocal_bind = 1

Makakatanggap ng error ang sinumang sumusubok na itali ang IPv6 (halimbawa nginx) pagkatapos na matapos ang interface. Na hindi available ang address na ito.

Upang maiwasan ang ganitong sitwasyon, ginawa ang ganitong setting.

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

Kung wala ang mga setting ng IPv6 na ito, ang trapiko mula sa OpenVPN client ay hindi lalabas sa mundo.

Ang ibang mga setting ay maaaring hindi nauugnay o hindi ko matandaan kung para saan ang mga ito.
Ngunit kung sakali, iniiwan ko ito "as is."

Upang makuha ang mga pagbabago sa file na ito nang hindi nire-reboot ang server, kailangan mong patakbuhin ang command:

sysctl -p

Higit pang mga detalye tungkol sa mga panuntunan sa "talahanayan": habr.com/post/108690

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

Ang OpenVPN IPv4 ay hindi gumagana nang walang iptables.

Ang aking mga iptable ay ganito para sa 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 ang aking static na IPv4 address ng lokal na makina.
10.8.0.0/24 - IPv4 openvpn network. Mga IPv4 address para sa mga openvpn client.
Ang pagkakapare-pareho ng mga patakaran ay mahalaga.

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

Ito ay isang limitasyon upang ako lamang ang makakagamit ng OpenVPN mula sa aking static na IP.

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

Upang maipasa ang mga IPv4 packet sa pagitan ng mga kliyente ng OpenVPN at ng Internet, kailangan mong irehistro ang isa sa mga utos na ito.

Para sa iba't ibang mga kaso, ang isa sa mga pagpipilian ay hindi angkop.
Ang parehong mga utos ay angkop para sa aking kaso.
Matapos basahin ang dokumentasyon, pinili ko ang unang pagpipilian dahil gumagamit ito ng mas kaunting CPU.

Upang makuha ang lahat ng mga setting ng iptables pagkatapos ng pag-reboot, kailangan mong i-save ang mga ito sa isang lugar.

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

Ang ganitong mga pangalan ay hindi pinili ng pagkakataon. Ginagamit ang mga ito ng package na "iptables-persistent".

apt-get install iptables-persistent

Pag-install ng pangunahing OpenVPN package:

apt-get install openvpn easy-rsa

Mag-set up tayo ng template para sa mga certificate (palitan ang iyong mga value):

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

I-edit natin ang mga setting ng template ng certificate:

mcedit vars

...
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Own"
export KEY_EMAIL="[email protected]"
export KEY_OU="VPN"

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

Lumikha ng sertipiko ng server:

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

Ihanda natin ang kakayahang lumikha ng panghuling “client-name.opvn” na mga file:

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

Maghanda tayo ng script na magsasama-sama ng lahat ng mga file sa isang solong opvn file.

mcedit ~/client-configs/make_config.sh
chmod 700 ~/client-configs/make_config.sh

#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} 
    <(echo -e '<ca>') 
    ${KEY_DIR}/ca.crt 
    <(echo -e '</ca>n<cert>') 
    ${KEY_DIR}/.crt 
    <(echo -e '</cert>n<key>') 
    ${KEY_DIR}/.key 
    <(echo -e '</key>n<tls-auth>') 
    ${KEY_DIR}/ta.key 
    <(echo -e '</tls-auth>') 
    > ${OUTPUT_DIR}/.ovpn

Paglikha ng unang OpenVPN client:

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

Ang file na "~/client-configs/files/client-name.ovpn" ay ipinadala sa device ng kliyente.

Para sa mga iOS client kakailanganin mong gawin ang sumusunod na trick:
Ang nilalaman ng tag na "tls-auth" ay dapat na walang mga komento.
At ilagay din ang "key-direction 1" kaagad bago ang "tls-auth" na tag.

I-configure natin ang OpenVPN server config:

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

Ito ay kinakailangan upang magtakda ng isang static na address para sa bawat kliyente (hindi kinakailangan, ngunit ginagamit ko ito):

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

Ang pinakamahirap at pangunahing detalye.

Sa kasamaang palad, hindi pa alam ng OpenVPN kung paano independiyenteng i-configure ang isang IPv6 gateway para sa mga kliyente.
Kailangan mong "manual" na ipasa ito para sa bawat kliyente.

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

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

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

Ang parehong mga script ay gumagamit ng file na "/etc/openvpn/variables":

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

Nahihirapan akong maalala kung bakit ganito ang pagkakasulat.

Ngayon ang netmask = 112 ay mukhang kakaiba (dapat ay 96 doon).
At ang prefix ay kakaiba, hindi ito tumutugma sa tun0 network.
Pero sige, hahayaan ko na lang.

cipher DES-EDE3-CBC

Ito ay hindi para sa lahat - pinili ko ang pamamaraang ito ng pag-encrypt ng koneksyon.

Matuto pa tungkol sa pagse-set up ng OpenVPN IPv4.

Matuto pa tungkol sa pagse-set up ng OpenVPN IPv6.

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

Pag-install ng pangunahing pakete:

apt-get install postfix

Kapag nag-i-install, piliin ang "site sa internet".

Ang aking "/etc/postfix/main.cf" ay ganito ang hitsura:

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

# appending .domain is the MUA's job.
append_dot_mydomain = no

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
smtpd_use_tls=yes
smtpd_tls_auth_only = yes
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1

smtp_tls_security_level = may
smtp_tls_ciphers = export
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_loglevel = 1

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = domain1.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = domain1.com
mydestination = localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4

internal_mail_filter_classes = bounce

# Storage type
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

# SMTP-Auth settings
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
        permit_sasl_authenticated,
        permit_mynetworks,
        #reject_invalid_hostname,
        #reject_unknown_recipient_domain,
        reject_unauth_destination,
        reject_rbl_client sbl.spamhaus.org,
        check_policy_service unix:private/policyd-spf

smtpd_helo_restrictions =
        #reject_invalid_helo_hostname,
        #reject_non_fqdn_helo_hostname,
        reject_unknown_helo_hostname

smtpd_client_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_non_fqdn_helo_hostname,
        permit

# SPF
policyd-spf_time_limit = 3600

# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sock

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

Tingnan natin ang mga detalye ng config na ito.

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

Ayon sa mga residente ng Khabrovsk, ang block na ito ay naglalaman ng "maling impormasyon at maling theses."8 taon lamang pagkatapos ng pagsisimula ng aking karera ay nagsimula akong maunawaan kung paano gumagana ang SSL.

Samakatuwid, gagawin ko ang kalayaang ilarawan kung paano gamitin ang SSL (nang hindi sinasagot ang mga tanong na "Paano ito gumagana?" at "Bakit ito gumagana?").

Ang batayan ng modernong pag-encrypt ay ang paglikha ng isang key pares (dalawang napakahabang string ng mga character).

Ang isang "susi" ay pribado, ang isa pang susi ay "pampubliko". Inilihim namin ang pribadong susi. Ibinabahagi namin ang pampublikong susi sa lahat.

Gamit ang isang pampublikong susi, maaari mong i-encrypt ang isang string ng teksto upang ang may-ari lamang ng pribadong key ang makakapag-decrypt nito.
Well, iyon ang buong batayan ng teknolohiya.

Hakbang #1 - https na mga site.
Kapag nag-a-access sa isang site, nalaman ng browser mula sa web server na ang site ay https at samakatuwid ay humihiling ng pampublikong key.
Ang web server ay nagbibigay ng pampublikong susi. Ginagamit ng browser ang pampublikong key upang i-encrypt ang http-request at ipadala ito.
Ang nilalaman ng isang http-request ay mababasa lamang ng mga may pribadong key, iyon ay, ang server lamang kung saan ginawa ang kahilingan.
Ang http-request ay naglalaman ng hindi bababa sa isang URI. Samakatuwid, kung sinusubukan ng isang bansa na higpitan ang pag-access hindi sa buong site, ngunit sa isang partikular na pahina, imposible itong gawin para sa mga site na https.

Hakbang #2 - naka-encrypt na tugon.
Nagbibigay ang web server ng sagot na madaling mabasa sa kalsada.
Ang solusyon ay napaka-simple - ang browser ay lokal na bumubuo ng parehong private-public key pair para sa bawat https site.
At kasama ng kahilingan para sa pampublikong susi ng site, ipinapadala nito ang lokal na pampublikong susi nito.
Naaalala ito ng web server at, kapag nagpapadala ng http-response, ine-encrypt ito gamit ang pampublikong key ng isang partikular na kliyente.
Ngayon ang http-response ay maaari lamang i-decrypt ng may-ari ng browser private key ng kliyente (iyon ay, ang kliyente mismo).

Hakbang No. 3 - pagtatatag ng secure na koneksyon sa pamamagitan ng pampublikong channel.
Mayroong isang kahinaan sa halimbawa No. 2 - walang pumipigil sa mga may mabuting hangarin mula sa pagharang ng isang http-request at pag-edit ng impormasyon tungkol sa pampublikong key.
Kaya, malinaw na makikita ng tagapamagitan ang lahat ng nilalaman ng ipinadala at natanggap na mga mensahe hanggang sa magbago ang channel ng komunikasyon.
Ang pagharap dito ay napakasimple - ipadala lamang ang pampublikong susi ng browser bilang isang mensaheng naka-encrypt gamit ang pampublikong susi ng web server.
Ang web server pagkatapos ay magpapadala muna ng tugon tulad ng "ang iyong pampublikong key ay ganito" at ine-encrypt ang mensaheng ito gamit ang parehong pampublikong key.
Tinitingnan ng browser ang tugon - kung ang mensaheng "ang iyong pampublikong susi ay ganito" ay natanggap - kung gayon ito ay isang 100% na garantiya na ang channel ng komunikasyon na ito ay ligtas.
Gaano ito ligtas?
Ang mismong paglikha ng naturang secure na channel ng komunikasyon ay nangyayari sa bilis ng ping*2. Halimbawa 20ms.
Ang umaatake ay dapat magkaroon ng pribadong susi ng isa sa mga partido nang maaga. O maghanap ng pribadong key sa loob ng ilang millisecond.
Ang pag-hack ng isang modernong pribadong key ay aabot ng ilang dekada sa isang supercomputer.

Hakbang #4 - pampublikong database ng mga pampublikong susi.
Malinaw, sa buong kuwentong ito ay may pagkakataon para sa isang umaatake na maupo sa channel ng komunikasyon sa pagitan ng kliyente at ng server.
Ang kliyente ay maaaring magpanggap na siya ang server, at ang server ay maaaring magpanggap na siya ang kliyente. At tularan ang isang pares ng mga susi sa magkabilang direksyon.
Pagkatapos ay makikita ng umaatake ang lahat ng trapiko at magagawa niyang "i-edit" ang trapiko.
Halimbawa, palitan ang address kung saan magpapadala ng pera o kopyahin ang password mula sa online banking o i-block ang nilalamang "nakasalungat."
Upang labanan ang gayong mga umaatake, gumawa sila ng isang pampublikong database na may mga pampublikong susi para sa bawat https site.
"Alam" ng bawat browser ang tungkol sa pagkakaroon ng humigit-kumulang 200 na mga database. Ito ay paunang naka-install sa bawat browser.
Ang "Kaalaman" ay sinusuportahan ng isang pampublikong susi mula sa bawat sertipiko. Iyon ay, ang koneksyon sa bawat partikular na awtoridad sa sertipikasyon ay hindi maaaring pekein.

Ngayon ay may simpleng pag-unawa kung paano gamitin ang SSL para sa https.
Kung gagamitin mo ang iyong utak, magiging malinaw kung paano maaaring ma-hack ng mga espesyal na serbisyo ang isang bagay sa istrukturang ito. Ngunit aabutin sila ng napakalaking pagsisikap.
At mga organisasyong mas maliit kaysa sa NSA o CIA - halos imposibleng i-hack ang umiiral na antas ng proteksyon, kahit na para sa mga VIP.

Magdaragdag din ako tungkol sa mga koneksyon sa ssh. Walang mga pampublikong susi doon, kaya ano ang maaari mong gawin? Ang isyu ay nalutas sa dalawang paraan.
Opsyon ssh-by-password:
Sa unang koneksyon, dapat na babalaan ng ssh client na mayroon kaming bagong pampublikong key mula sa ssh server.
At sa mga karagdagang koneksyon, kung ang babala na "bagong pampublikong susi mula sa ssh server" ay lilitaw, nangangahulugan ito na sinusubukan nilang mag-eavesdrop sa iyo.
O na-eavesdrop ka sa iyong unang koneksyon, ngunit ngayon ay nakikipag-ugnayan ka sa server nang walang mga tagapamagitan.
Sa totoo lang, dahil sa ang katunayan na ang katotohanan ng wiretapping ay madali, mabilis at walang kahirap-hirap na inihayag, ang pag-atake na ito ay ginagamit lamang sa mga espesyal na kaso para sa isang partikular na kliyente.

Opsyon ssh-by-key:
Kumuha kami ng flash drive, isulat ang pribadong key para sa ssh server dito (may mga termino at maraming mahahalagang nuances para dito, ngunit sumusulat ako ng isang programang pang-edukasyon, hindi mga tagubilin para sa paggamit).
Iniiwan namin ang pampublikong susi sa makina kung saan naroroon ang ssh client at inilihim din namin ito.
Dinadala namin ang flash drive sa server, ipasok ito, kopyahin ang pribadong key, at sunugin ang flash drive at ikalat ang mga abo sa hangin (o hindi bababa sa i-format ito ng mga zero).
Iyon lang - pagkatapos ng naturang operasyon imposibleng i-hack ang gayong koneksyon sa ssh. Siyempre, sa loob ng 10 taon magiging posible na tingnan ang trapiko sa isang supercomputer - ngunit ibang kuwento iyon.

Humihingi ako ng paumanhin para sa offtopic.

Kaya ngayon na ang teorya ay kilala. Sasabihin ko sa iyo ang tungkol sa daloy ng paggawa ng SSL certificate.

Gamit ang "openssl genrsa" gumawa kami ng pribadong key at "blangko" para sa pampublikong key.
Ipinapadala namin ang "mga blangko" sa isang third-party na kumpanya, kung saan binabayaran namin ang humigit-kumulang $9 para sa pinakasimpleng certificate.

Pagkalipas ng ilang oras, natatanggap namin ang aming "pampublikong" key at isang set ng ilang pampublikong key mula sa kumpanyang ito ng third-party.

Bakit dapat magbayad ang isang third-party na kumpanya para sa pagpaparehistro ng aking pampublikong key ay isang hiwalay na tanong, hindi namin ito isasaalang-alang dito.

Ngayon ay malinaw na kung ano ang kahulugan ng inskripsiyon:

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

Ang folder na "/etc/ssl" ay naglalaman ng lahat ng mga file para sa mga isyu sa ssl.
domain1.com — domain name.
Ang 2018 ay ang taon ng pangunahing paglikha.
"key" - pagtatalaga na ang file ay isang pribadong key.

At ang kahulugan ng file na ito:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com — domain name.
Ang 2018 ay ang taon ng pangunahing paglikha.
chained - pagtatalaga na mayroong isang chain ng mga pampublikong susi (ang una ay ang aming pampublikong susi at ang iba ay kung ano ang nagmula sa kumpanya na nagbigay ng pampublikong susi).
crt - pagtatalaga na mayroong isang handa na sertipiko (pampublikong susi na may mga teknikal na paliwanag).

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

Ang setting na ito ay hindi ginagamit sa kasong ito, ngunit nakasulat bilang isang halimbawa.

Dahil ang isang error sa parameter na ito ay hahantong sa pagpapadala ng spam mula sa iyong server (nang wala ang iyong kalooban).

Pagkatapos ay patunayan sa lahat na wala kang kasalanan.

recipient_delimiter = +

Maaaring hindi alam ng maraming tao, ngunit ito ay isang karaniwang karakter para sa pagraranggo ng mga email, at ito ay sinusuportahan ng karamihan sa mga modernong mail server.

Halimbawa, kung mayroon kang mailbox "[protektado ng email]"subukan mong ipadala sa"[protektado ng email]"Tingnan mo kung ano ang nangyayari.

inet_protocols = ipv4

Ito ay maaaring nakakalito.

Pero hindi lang ganun. Ang bawat bagong domain ay IPv4 lamang bilang default, pagkatapos ay ino-on ko ang IPv6 para sa bawat isa nang hiwalay.

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

Dito namin tinukoy na ang lahat ng papasok na mail ay napupunta sa dovecot.
At ang mga patakaran para sa domain, mailbox, alias - tingnan sa 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

Ngayon alam na ng postfix na ang mail ay maaaring tanggapin para sa karagdagang pagpapadala lamang pagkatapos ng pahintulot sa dovecot.

Hindi ko talaga maintindihan kung bakit ito nadoble dito. Natukoy na namin ang lahat ng kailangan sa “virtual_transport”.

Ngunit ang sistema ng postfix ay napakaluma - marahil ito ay isang pagbabalik mula sa mga lumang araw.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Maaari itong i-configure nang iba para sa bawat mail server.

Mayroon akong 3 mail server sa aking pagtatapon at ang mga setting na ito ay ibang-iba dahil sa iba't ibang mga kinakailangan sa paggamit.

Kailangan mong i-configure ito nang mabuti - kung hindi ay bubuhos ang spam sa iyo, o mas masahol pa - bubuhos ang spam mula sa iyo.

# SPF
policyd-spf_time_limit = 3600

Pagse-set up para sa ilang plugin na nauugnay sa pagsuri sa SPF ng mga papasok na titik.

# 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

Ang setting ay dapat kaming magbigay ng DKIM signature kasama ang lahat ng papalabas na email.

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

Ito ay isang mahalagang detalye sa pagruruta ng sulat kapag nagpapadala ng mga titik mula sa mga script ng PHP.

File "/etc/postfix/sdd_transport.pcre":

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

Sa kaliwa ay mga regular na expression. Sa kanan ay isang label na nagmamarka ng titik.
Postfix alinsunod sa label - ay isasaalang-alang ang ilang higit pang mga linya ng pagsasaayos para sa isang partikular na titik.

Kung paano eksaktong isasaayos ang postfix para sa isang partikular na liham ay ipapahiwatig sa "master.cf".

Ang mga linya 4, 5, 6 ay ang mga pangunahing. Sa ngalan ng kung aling domain kami nagpapadala ng sulat, inilalagay namin ang label na ito.
Ngunit ang field na "mula sa" ay hindi palaging nakasaad sa mga script ng PHP sa lumang code. Pagkatapos ang username ay dumating upang iligtas.

Malawak na ang artikulo - hindi ko nais na magambala sa pamamagitan ng pag-set up ng nginx+fpm.

Sa madaling sabi, para sa bawat site ay nagtatakda kami ng sarili nitong may-ari ng linux-user. At naaayon ang iyong fpm-pool.

Gumagamit ang Fpm-pool ng anumang bersyon ng php (mahusay ito kapag sa parehong server maaari kang gumamit ng iba't ibang bersyon ng php at kahit na iba't ibang php.ini para sa mga kalapit na site nang walang problema).

Kaya, ang isang partikular na linux-user na "www-domain2" ay may website na domain2.com. Ang site na ito ay may code para sa pagpapadala ng mga email nang hindi tinukoy ang mula sa field.

Kaya, kahit na sa kasong ito, ang mga liham ay ipapadala nang tama at hindi kailanman mauuwi sa spam.

Ang aking "/etc/postfix/master.cf" ay ganito ang hitsura:

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

Ang file ay hindi ibinigay nang buo - ito ay napakalaki na.
Napansin ko lang kung ano ang nabago.

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}

Ito ay mga setting na nauugnay sa spamassasin, higit pa sa susunod.

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

Pinapayagan ka naming kumonekta sa mail server sa pamamagitan ng port 587.
Upang gawin ito, kailangan mong mag-log in.

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

Paganahin ang SPF check.

apt-get install postfix-policyd-spf-python

I-install natin ang package para sa mga pagsusuri sa SPF sa itaas.

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

At ito ang pinaka-kagiliw-giliw na bagay. Ito ang kakayahang magpadala ng mga liham para sa isang partikular na domain mula sa isang partikular na IPv4/IPv6 address.

Ginagawa ito para sa kapakanan ng rDNS. Ang rDNS ay ang proseso ng pagtanggap ng string sa pamamagitan ng IP address.
At para sa mail, ginagamit ang feature na ito para kumpirmahin na eksaktong tumutugma ang helo sa rDNS ng address kung saan ipinadala ang email.

Kung hindi tumugma ang helo sa domain ng email sa ngalan kung kanino ipinadala ang sulat, ibibigay ang mga spam point.

Hindi tumutugma ang Helo sa rDNS - maraming spam point ang iginawad.
Alinsunod dito, ang bawat domain ay dapat magkaroon ng sarili nitong IP address.
Para sa OVH - sa console posible na tukuyin ang rDNS.
Para sa tech.ru - ang isyu ay nalutas sa pamamagitan ng suporta.
Para sa AWS, naresolba ang isyu sa pamamagitan ng suporta.
“inet_protocols” at “smtp_bind_address6” - pinapagana namin ang suporta sa IPv6.
Para sa IPv6 kailangan mo ring magrehistro ng rDNS.
"syslog_name" - at ito ay para sa kadalian ng pagbabasa ng mga log.

Bumili ng mga sertipiko Inirerekomenda ko dito.

Pagse-set up ng link ng postfix+dovecot dito.

Pagtatakda ng SPF.

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

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

Pagse-set up ng mysql, pag-install ng mga package mismo.

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

disable_plaintext_auth = yes
auth_mechanisms = plain login

Ang pahintulot ay naka-encrypt lamang.

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

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

Dito ipinapahiwatig namin ang lokasyon ng imbakan para sa mga titik.

Gusto kong maiimbak ang mga ito sa mga file at ipangkat ayon sa domain.

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 {
  }
}

Ito ang pangunahing dovecot configuration file.
Dito hindi namin pinapagana ang mga hindi secure na koneksyon.
At paganahin ang mga secure na koneksyon.

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
}

Pagse-set up ng ssl. Ipinapahiwatig namin na kinakailangan ang ssl.
At ang sertipiko mismo. At isang mahalagang detalye ang "lokal" na direktiba. Isinasaad kung aling SSL certificate ang gagamitin kapag kumokonekta sa kung aling lokal na IPv4.

By the way, IPv6 is not configured here, I'll correct this omission later.
XX.XX.XX.X5 (domain2) - walang certificate. Upang ikonekta ang mga kliyente kailangan mong tukuyin ang domain1.com.
XX.XX.XX.X2 (domain3) - mayroong isang sertipiko, maaari mong tukuyin ang domain1.com o domain3.com upang kumonekta sa mga kliyente.

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

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Kakailanganin ito para sa spamassassin sa hinaharap.

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

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Ito ay isang antispam plugin. Kailangan para sa pagsasanay ng spamassasin sa oras ng paglipat sa/mula sa folder na “Spam”.

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

protocol pop3 {
}

May ganoong file lang.

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

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

Pagse-set up ng lmtp.

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

Mga setting ng pagsasanay sa Spamassasin sa oras ng paglipat sa/mula sa folder ng Spam.

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

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

Isang file na tumutukoy kung ano ang gagawin sa mga papasok na titik.

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

require ["fileinto", "mailbox"];

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

Kailangan mong i-compile ang file: "sievec default.sieve".

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

Pagtukoy ng mga sql file para sa awtorisasyon.
At ang file mismo ay ginagamit bilang isang paraan ng awtorisasyon.

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

Ito ay tumutugma sa mga katulad na setting para sa postfix.

File "/etc/dovecot/dovecot.conf"

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

Pangunahing configuration file.
Ang mahalagang bagay ay ipinapahiwatig namin dito - magdagdag ng mga protocol.

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

apt-get install spamassassin spamc

I-install natin ang mga pakete.

adduser spamd --disabled-login

Magdagdag tayo ng user para kanino.

systemctl enable spamassassin.service

Pinapagana namin ang awtomatikong pag-load ng serbisyo ng spammassassin kapag nag-load.

File "/etc/default/spamassassin":

CRON=1

Sa pamamagitan ng pagpapagana ng awtomatikong pag-update ng mga panuntunan "bilang default".

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

Kailangan mong lumikha ng isang database na "sa" sa mysql kasama ang gumagamit na "sa" na may password na "password" (palitan ng isang bagay na sapat).

report_safe - magpapadala ito ng ulat ng spam na email sa halip na isang sulat.
Ang use_bayes ay mga setting ng pag-aaral ng machine learning na spamassassin.

Ang natitirang mga setting ng spammassassin ay ginamit nang mas maaga sa artikulo.

Pangkalahatang setting na "spamassassin".
Tungkol sa paglilipat ng mga bagong Spam email sa folder na "Spam" ng IMAP.
Tungkol sa isang simpleng kumbinasyon ng Dovecot + SpamAssassin.
Inirerekomenda kong basahin ang teorya ng pag-aaral ng spamassasin kapag naglilipat ng mga titik sa mga folder ng imap (at hindi ko inirerekomenda ang paggamit nito).

============= Apela sa komunidad =============

Gusto ko ring maghagis ng ideya sa komunidad tungkol sa kung paano pataasin ang antas ng seguridad ng mga ipinasa na liham. Dahil masyado akong nalubog sa paksa ng mail.

Upang ang user ay makalikha ng isang pares ng mga susi sa kanyang kliyente (outlook, thunderbird, browser-plugin, ...). Pampubliko at pribado. Pampubliko - ipadala sa DNS. Pribado - makatipid sa kliyente. Ang mga mail server ay maaaring gumamit ng isang pampublikong susi upang ipadala sa isang partikular na tatanggap.

At upang maprotektahan laban sa spam na may ganitong mga titik (oo, hindi makikita ng mail server ang nilalaman) - kakailanganin mong ipakilala ang 3 panuntunan:

  1. Mandatoryong totoong DKIM signature, mandatory SPF, mandatory rDNS.
  2. Isang neural network sa paksa ng antispam na pagsasanay + isang database para dito sa panig ng kliyente.
  3. Ang algorithm ng pag-encrypt ay dapat na ganoon na ang panig ng pagpapadala ay dapat gumastos ng 100 beses na mas maraming lakas ng CPU sa pag-encrypt kaysa sa panig ng pagtanggap.

Bilang karagdagan sa mga pampublikong liham, bumuo ng isang karaniwang liham ng panukala "upang simulan ang ligtas na pagsusulatan." Ang isa sa mga user (mailbox) ay nagpapadala ng sulat na may kalakip sa isa pang mailbox. Ang liham ay naglalaman ng isang panukalang teksto upang magsimula ng isang secure na channel ng komunikasyon para sa pagsusulatan at ang pampublikong susi ng may-ari ng mailbox (na may pribadong susi sa panig ng kliyente).

Maaari ka ring gumawa ng ilang susi na partikular para sa bawat sulat. Maaaring tanggapin ng tatanggap na user ang alok na ito at ipadala ang kanyang pampublikong key (partikular din na ginawa para sa sulat na ito). Susunod, ang unang user ay nagpapadala ng isang service control letter (naka-encrypt gamit ang pampublikong key ng pangalawang user) - sa pagtanggap kung saan ang pangalawang user ay maaaring isaalang-alang ang nabuong channel ng komunikasyon na maaasahan. Susunod, ang pangalawang user ay nagpapadala ng isang control letter - at pagkatapos ay maaari ding isaalang-alang ng unang user na secure ang nabuong channel.

Upang labanan ang pagharang ng mga susi sa kalsada, ang protocol ay dapat magbigay ng posibilidad ng pagpapadala ng hindi bababa sa isang pampublikong susi gamit ang isang flash drive.

At ang pinakamahalagang bagay ay gumagana ang lahat (ang tanong ay "sino ang magbabayad para dito?"):
Maglagay ng mga postal certificate simula sa $10 sa loob ng 3 taon. Na magpapahintulot sa nagpadala na ipahiwatig sa dns na "naroon ang aking mga pampublikong susi." At bibigyan ka nila ng pagkakataong magsimula ng isang secure na koneksyon. Kasabay nito, ang pagtanggap ng mga naturang koneksyon ay libre.
Sa wakas ay pinagkakakitaan ng gmail ang mga gumagamit nito. Para sa $10 bawat 3 taon - ang karapatang lumikha ng mga secure na channel sa pagsusulatan.

============= Konklusyon =============

Upang subukan ang buong artikulo, magrenta ako ng dedikadong server sa loob ng isang buwan at bibili ng domain na may SSL certificate.

Ngunit ang mga pangyayari sa buhay ay nabuo kaya ang isyu na ito ay nag-drag sa loob ng 2 buwan.
At kaya, nang magkaroon ako ng libreng oras muli, nagpasya akong i-publish ang artikulo nang walang kabuluhan, sa halip na ipagsapalaran na ang publikasyon ay mag-drag sa isang taon.

Kung mayroong napakaraming tanong tulad ng "ngunit hindi ito inilalarawan nang may sapat na detalye", malamang na magkakaroon ng lakas na kumuha ng isang dedikadong server na may bagong domain at isang bagong SSL certificate at ilarawan ito nang mas detalyado at, karamihan ang mahalaga, tukuyin ang lahat ng nawawalang mahahalagang detalye.

Gusto ko ring makakuha ng feedback sa mga ideya tungkol sa mga postal certificate. Kung gusto mo ang ideya, susubukan kong maghanap ng lakas para magsulat ng draft para sa rfc.

Kapag kinokopya ang malalaking bahagi ng isang artikulo, magbigay ng link sa artikulong ito.
Kapag nagsasalin sa anumang ibang wika, magbigay ng link sa artikulong ito.
Susubukan kong isalin ito sa Ingles sa aking sarili at mag-iwan ng mga cross-reference.


Pinagmulan: www.habr.com

Magdagdag ng komento