Debian + Postfix + Dovecot + Multidomain + SSL + IPv6 + OpenVPN + Ko'p interfeyslar + SpamAssassin-learn + Bind

Ushbu maqola zamonaviy pochta serverini qanday sozlash haqida.
Postfix + Dovecot. SPF + DKIM + rDNS. IPv6 bilan.
TSL shifrlash bilan. Bir nechta domenlarni qo'llab-quvvatlash bilan - haqiqiy SSL sertifikatiga ega qism.
Antispam himoyasi va boshqa pochta serverlaridan yuqori antispam reytingi bilan.
Bir nechta jismoniy interfeyslarni qo'llab-quvvatlaydi.
OpenVPN bilan, ulanish IPv4 orqali amalga oshiriladi va IPv6 bilan ta'minlaydi.

Agar siz ushbu texnologiyalarning barchasini o'rganishni xohlamasangiz, lekin bunday serverni o'rnatmoqchi bo'lsangiz, unda ushbu maqola siz uchun.

Maqola har bir tafsilotni tushuntirishga urinmaydi. Tushuntirish standart sifatida sozlanmagan yoki iste'molchi nuqtai nazaridan muhim bo'lgan narsalarga o'tadi.

Pochta serverini o'rnatish uchun motivatsiya mening uzoq yillik orzuim edi. Bu ahmoqona tuyulishi mumkin, lekin IMHO, bu sizning sevimli brendingizdan yangi mashinani orzu qilishdan ko'ra yaxshiroqdir.

IPv6 ni o'rnatish uchun ikkita sabab bor. IT mutaxassisi omon qolish uchun doimiy ravishda yangi texnologiyalarni o'rganishi kerak. Men senzuraga qarshi kurashga o'zimning kamtarona hissamni qo'shmoqchiman.

OpenVPN-ni o'rnatish uchun motivatsiya faqat IPv6-ni mahalliy kompyuterda ishlashga erishishdir.
Bir nechta jismoniy interfeyslarni o'rnatish uchun motivatsiya shundaki, mening serverimda bitta interfeys "sekin, lekin cheksiz" va boshqasi "tez, lekin tarifli".

Bog'lanish sozlamalarini o'rnatishga turtki shundaki, mening provayderim beqaror DNS-serverni taqdim etadi va Google ham ba'zan muvaffaqiyatsizlikka uchraydi. Men shaxsiy foydalanish uchun barqaror DNS serverini xohlayman.

Maqola yozish uchun motivatsiya - men 10 oy oldin qoralama yozganman va uni ikki marta ko'rib chiqqanman. Muallifga muntazam ravishda kerak bo'lsa ham, boshqalarga ham kerak bo'lish ehtimoli yuqori.

Pochta serveri uchun universal yechim yo'q. Ammo men "buni qiling va keyin hamma narsa kerak bo'lganda, ortiqcha narsalarni tashlang" kabi bir narsa yozishga harakat qilaman.

tech.ru kompaniyasida Colocation serveri mavjud. OVH, Hetzner, AWS bilan solishtirish mumkin. Ushbu muammoni hal qilish uchun tech.ru bilan hamkorlik qilish ancha samarali bo'ladi.

Serverda Debian 9 o'rnatilgan.

Serverda ikkita interfeys `eno2` va `eno1` mavjud. Birinchisi cheksiz, ikkinchisi esa mos ravishda tezdir.

`eno3` interfeysida XX.XX.XX.X0 va XX.XX.XX.X1 va XX.XX.XX.X2 va `eno1` interfeysida XX.XX.XX.X5 2 ta statik IP manzillari mavjud. .

Mavjud XXXX:XXXX:XXXX:XXXX::/64 "eno6" interfeysiga tayinlangan IPv1 manzillar hovuzi va undan XXXX:XXXX:XXXX:XXXX:1:2::/96 mening so'rovim bo'yicha "eno2" ga tayinlangan.

`domain3.com`, `domain1.com`, `domain2.com` 3 ta domen mavjud. `domain1.com` va `domain3.com` uchun SSL sertifikati mavjud.

Mening pochta qutimni bog'lamoqchi bo'lgan Google hisobim bor[elektron pochta bilan himoyalangan]` (pochtani qabul qilish va to'g'ridan-to'g'ri gmail interfeysidan pochta jo'natish).
Pochta qutisi bo'lishi kerak[elektron pochta bilan himoyalangan]`, men Gmail-da ko'rmoqchi bo'lgan xatning nusxasi. Va ` nomidan biror narsa yuborish imkoniyati kamdan-kam uchraydi[elektron pochta bilan himoyalangan]` veb-interfeys orqali.

Pochta qutisi bo'lishi kerak[elektron pochta bilan himoyalangan]`, Ivanov iPhone-dan foydalanadi.

Yuborilgan elektron pochta xabarlari barcha zamonaviy antispam talablariga javob berishi kerak.
Umumiy tarmoqlarda shifrlashning eng yuqori darajasi bo'lishi kerak.
Xat yuborish va qabul qilish uchun IPv6 qo'llab-quvvatlanishi kerak.
Hech qachon elektron pochta xabarlarini o'chirmaydigan SpamAssassin bo'lishi kerak. Va u sakrab tushadi yoki o'tkazib yuboriladi yoki IMAP "Spam" jildiga yuboriladi.
SpamAssassin avtomatik o'rganishni sozlash kerak: agar xatni Spam jildiga ko'chirsam, u bundan o'rganadi; agar men xatni Spam jildidan ko'chirsam, u bundan o'rganadi. SpamAssassin treningi natijalari xatning Spam jildiga tushishiga ta'sir qilishi kerak.
PHP skriptlari berilgan serverdagi istalgan domen nomidan pochta joβ€˜natish imkoniyatiga ega boβ€˜lishi kerak.
IPv6-ga ega bo'lmagan mijozda IPv6-dan foydalanish imkoniyatiga ega openvpn xizmati bo'lishi kerak.

Avval siz interfeyslarni va marshrutlashni sozlashingiz kerak, shu jumladan IPv6.
Keyin siz IPv4 orqali ulanadigan va mijozga statik-haqiqiy IPv6 manzilini taqdim etadigan OpenVPN-ni sozlashingiz kerak bo'ladi. Ushbu mijoz serverdagi barcha IPv6 xizmatlariga va Internetdagi istalgan IPv6 resurslariga kirish huquqiga ega bo'ladi.
Keyin Postfix-ni harflar + SPF + DKIM + rDNS va shunga o'xshash boshqa kichik narsalarni yuborish uchun sozlashingiz kerak bo'ladi.
Keyin Dovecot-ni sozlashingiz va Multidomain-ni sozlashingiz kerak bo'ladi.
Keyin siz SpamAssassin-ni sozlashingiz va treningni sozlashingiz kerak bo'ladi.
Nihoyat, Bind-ni o'rnating.

============= Ko'p interfeysli ============

Interfeyslarni sozlash uchun siz buni β€œ/etc/network/interfaces” da yozishingiz kerak.

# 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

Ushbu sozlamalar tech.ru saytidagi har qanday serverda qo'llanilishi mumkin (qo'llab-quvvatlash bilan biroz muvofiqlashtirilgan holda) va u darhol kerak bo'lganda ishlaydi.

Agar Hetzner, OVH uchun shunga o'xshash narsalarni o'rnatish tajribangiz bo'lsa, u erda boshqacha. Qiyinroq.

eno1 - β„–1 tarmoq kartasining nomi (sekin, lekin cheksiz).
eno2 - β„–2 tarmoq kartasining nomi (tezkor, lekin tarif bilan).
tun0 - OpenVPN virtual tarmoq kartasining nomi.
XX.XX.XX.X0 - eno4 da IPv1 #1.
XX.XX.XX.X1 - eno4 da IPv2 #1.
XX.XX.XX.X2 - eno4 da IPv3 #1.
XX.XX.XX.X5 - eno4 da IPv1 #2.
XX.XX.XX.1 - IPv4 shlyuzi.
XXXX:XXXX:XXXXX:XXXX::/64 - butun server uchun IPv6.
XXXX:XXXX:XXXX:XXXX:1:2::/96 - eno6 uchun IPv2, tashqaridan hamma narsa eno1 ga kiradi.
XXXX:XXXX:XXXX:XXXX::1 β€” IPv6 shlyuzi (ta'kidlash joizki, buni boshqacha qilish mumkin/kerak. IPv6 kalitini ko'rsating).
dns-nameservers - 127.0.0.1 ko'rsatilgan (chunki bog'lash mahalliy sifatida o'rnatilgan) va 213.248.1.6 (bu tech.ru saytidan).

β€œjadval eno1t” va β€œjadval eno2t” – bu marshrut-qoidalarning ma’nosi shundan iboratki, eno1 -> orqali kiruvchi trafik u orqali chiqib ketadi va eno2 -> orqali kirgan trafik u orqali chiqib ketadi. Shuningdek, server tomonidan boshlangan ulanishlar eno1 orqali o'tadi.

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

Ushbu buyruq bilan biz "jadval eno1t" -> belgilangan har qanday qoidaga to'g'ri keladigan tushunarsiz trafik eno1 interfeysiga yuborilishini belgilaymiz.

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

Ushbu buyruq bilan biz server tomonidan boshlangan har qanday trafik eno1 interfeysiga yo'naltirilishi kerakligini aniqlaymiz.

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

Ushbu buyruq bilan biz trafikni belgilash qoidalarini o'rnatamiz.

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

Ushbu blok eno4 interfeysi uchun ikkinchi IPv1 ni belgilaydi.

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

Ushbu buyruq bilan biz OpenVPN mijozlaridan XX.XX.XX.X4dan tashqari mahalliy IPv0 ga yo'nalishni o'rnatamiz.
Nima uchun bu buyruq barcha IPv4 uchun etarli ekanligini hali ham tushunmayapman.

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

Bu erda biz interfeysning o'zi uchun manzilni o'rnatamiz. Server uni "chiqish" manzili sifatida ishlatadi. Hech qanday tarzda qayta ishlatilmaydi.

Nima uchun ":1:1::" juda murakkab? Shunday qilib, OpenVPN to'g'ri ishlaydi va faqat buning uchun. Bu haqda keyinroq.

Gateway mavzusida - bu shunday ishlaydi va bu yaxshi. Ammo to'g'ri yo'l bu erda server ulangan kalitning IPv6-ni ko'rsatishdir.

Biroq, agar men buni qilsam, negadir IPv6 ishlashni to'xtatadi. Bu, ehtimol, qandaydir tech.ru muammosi.

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

Bu interfeysga IPv6 manzilini qo'shmoqda. Agar sizga yuzta manzil kerak bo'lsa, bu faylda yuzta qatorni bildiradi.

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

Men buni aniq qilish uchun barcha interfeyslarning manzillari va pastki tarmoqlarini qayd etdim.
eno1 - bo'lishi kerak "/64" - chunki bu bizning butun manzillar hovuzimiz.
tun0 - pastki tarmoq eno1 dan kattaroq bo'lishi kerak. Aks holda, OpenVPN mijozlari uchun IPv6 shlyuzini sozlash mumkin bo'lmaydi.
eno2 - pastki tarmoq tun0 dan kattaroq bo'lishi kerak. Aks holda, OpenVPN mijozlari mahalliy IPv6 manzillariga kira olmaydi.
Aniqlik uchun men 16 ta pastki tarmoq qadamini tanladim, lekin agar xohlasangiz, hatto "1" qadamni ham qilishingiz mumkin.
Shunga ko'ra, 64+16 = 80 va 80+16 = 96.

Keyinchalik aniqlik uchun:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY - eno1 interfeysidagi muayyan saytlar yoki xizmatlarga tayinlanishi kerak bo'lgan manzillar.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY - eno2 interfeysidagi muayyan saytlar yoki xizmatlarga tayinlanishi kerak bo'lgan manzillar.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY - OpenVPN mijozlariga tayinlanishi yoki OpenVPN xizmat manzillari sifatida ishlatilishi kerak bo'lgan manzillar.

Tarmoqni sozlash uchun serverni qayta ishga tushirish mumkin bo'lishi kerak.
IPv4 o'zgarishlari bajarilganda olinadi (uni ekranga o'rashni unutmang - aks holda bu buyruq serverdagi tarmoqni shunchaki buzadi):

/etc/init.d/networking restart

"/etc/iproute2/rt_tables" faylining oxiriga qo'shing:

100 eno1t
101 eno2t

Busiz "/etc/network/interfaces" faylida maxsus jadvallardan foydalana olmaysiz.
Raqamlar noyob va 65535 dan kichik bo'lishi kerak.

IPv6 o'zgarishlarini qayta yuklamasdan osongina o'zgartirish mumkin, ammo buning uchun siz kamida uchta buyruqni o'rganishingiz kerak:

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

β€œ/etc/sysctl.conf” sozlamalari

# 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

Bu mening serverimning "sysctl" sozlamalari. Bir muhim narsani ta'kidlab o'taman.

net.ipv4.ip_forward = 1

Busiz OpenVPN umuman ishlamaydi.

net.ipv6.ip_nonlocal_bind = 1

Interfeys o'rnatilgandan so'ng darhol IPv6 (masalan, nginx) ni ulashga harakat qilgan har bir kishi xatoga yo'l qo'yadi. Bu manzil mavjud emas.

Bunday vaziyatdan qochish uchun bunday sozlash amalga oshiriladi.

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

Ushbu IPv6 sozlamalarisiz, OpenVPN mijozidan trafik dunyoga chiqmaydi.

Boshqa sozlamalar ahamiyatsiz yoki ular nima uchun ekanligini eslay olmayman.
Ammo har qanday holatda, men uni "xuddi shunday" qoldiraman.

Ushbu faylga kiritilgan o'zgarishlar serverni qayta ishga tushirmasdan olinishi uchun siz quyidagi buyruqni bajarishingiz kerak:

sysctl -p

"Jadval" qoidalari haqida batafsil ma'lumot: habr.com/post/108690

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

OpenVPN IPv4 iptablessiz ishlamaydi.

Mening iptables VPN uchun shunday:

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 - mahalliy mashinaning statik IPv4 manzilim.
10.8.0.0/24 - IPv4 openvpn tarmog'i. Openvpn mijozlari uchun IPv4 manzillari.
Qoidalarning izchilligi muhim ahamiyatga ega.

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

Bu cheklovdir, shuning uchun faqat men statik IP-dan OpenVPN-dan foydalanishim mumkin.

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

OpenVPN mijozlari va Internet o'rtasida IPv4 paketlarini yuborish uchun siz ushbu buyruqlardan birini ro'yxatdan o'tkazishingiz kerak.

Turli xil holatlar uchun variantlardan biri mos kelmaydi.
Ikkala buyruq ham mening ishim uchun mos keladi.
Hujjatlarni o'qib chiqqandan so'ng, men birinchi variantni tanladim, chunki u kamroq CPU ishlatadi.

Qayta ishga tushirilgandan so'ng barcha iptables sozlamalarini olish uchun ularni biron bir joyda saqlashingiz kerak.

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

Bunday nomlar tasodifan tanlanmagan. Ular "iptables-persistent" paketi tomonidan qo'llaniladi.

apt-get install iptables-persistent

Asosiy OpenVPN paketini o'rnatish:

apt-get install openvpn easy-rsa

Keling, sertifikatlar uchun shablonni o'rnatamiz (qiymatlaringizni almashtiring):

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

Keling, sertifikat shablonlari sozlamalarini tahrir qilaylik:

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

Server sertifikatini yarating:

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

Keling, yakuniy "client-name.opvn" fayllarini yaratish qobiliyatini tayyorlaylik:

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

Keling, barcha fayllarni bitta opvn fayliga birlashtiradigan skript tayyorlaylik.

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

Birinchi OpenVPN mijozini yaratish:

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

β€œ~/client-configs/files/client-name.ovpn” fayli mijoz qurilmasiga yuboriladi.

iOS mijozlari uchun siz quyidagi nayrangni bajarishingiz kerak bo'ladi:
"tls-auth" tegining mazmuni izohsiz bo'lishi kerak.
Shuningdek, "tls-auth" yorlig'i oldiga "kalit-yo'nalish 1" ni qo'ying.

Keling, OpenVPN server konfiguratsiyasini sozlaymiz:

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

Bu har bir mijoz uchun statik manzilni o'rnatish uchun kerak (kerak emas, lekin men undan foydalanaman):

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

Eng qiyin va asosiy tafsilot.

Afsuski, OpenVPN mijozlar uchun IPv6 shlyuzini mustaqil ravishda qanday sozlashni hali bilmaydi.
Buni har bir mijoz uchun "qo'lda" yuborishingiz kerak.

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

β€œ/etc/openvpn/server-clientconnect.sh” fayli:

#!/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

β€œ/etc/openvpn/server-clientdisconnect.sh” fayli:

#!/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

Ikkala skript ham β€œ/etc/openvpn/variables” faylidan foydalanadi:

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

Nega bunday yozilganini eslashim qiyin.

Endi tarmoq maskasi = 112 g'alati ko'rinadi (u erda 96 bo'lishi kerak).
Va prefiks g'alati, u tun0 tarmog'iga mos kelmaydi.
Lekin yaxshi, men uni avvalgidek qoldiraman.

cipher DES-EDE3-CBC

Bu hamma uchun emas - men ulanishni shifrlashning ushbu usulini tanladim.

OpenVPN IPv4 ni sozlash haqida ko'proq bilib oling.

OpenVPN IPv6 ni sozlash haqida ko'proq bilib oling.

============= Postfiks =============

Asosiy paketni o'rnatish:

apt-get install postfix

O'rnatish vaqtida "Internet sayt" ni tanlang.

Mening "/etc/postfix/main.cf"im shunday ko'rinadi:

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

Keling, ushbu konfiguratsiyaning tafsilotlarini ko'rib chiqaylik.

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

Xabrovsk aholisining so'zlariga ko'ra, ushbu blokda "noto'g'ri ma'lumotlar va noto'g'ri tezislar" mavjud.Faoliyatim boshlanganidan atigi 8 yil o'tgach, men SSL qanday ishlashini tushuna boshladim.

Shuning uchun men SSL dan qanday foydalanishni tasvirlab berish erkinligidan foydalanaman ("Bu qanday ishlaydi?" va "U nima uchun ishlaydi?" Degan savollarga javob bermasdan).

Zamonaviy shifrlashning asosi kalit juftligini (ikkita juda uzun belgilar qatori) yaratishdir.

Bitta "kalit" shaxsiy, ikkinchisi esa "ommaviy". Biz shaxsiy kalitni juda ehtiyotkorlik bilan sir tutamiz. Biz ochiq kalitni hammaga tarqatamiz.

Ochiq kalitdan foydalanib, siz matn qatorini shifrlashingiz mumkin, shunda faqat shaxsiy kalit egasi uni parolini hal qila oladi.
Xo'sh, bu texnologiyaning butun asosidir.

1-qadam - https saytlari.
Saytga kirishda brauzer veb-serverdan sayt https ekanligini bilib oladi va shuning uchun ochiq kalit so'raydi.
Veb-server umumiy kalitni beradi. Brauzer http-so'rovni shifrlash va yuborish uchun ochiq kalitdan foydalanadi.
Http-so'rov mazmunini faqat shaxsiy kalitga ega bo'lganlar o'qiy oladi, ya'ni faqat so'rov yuborilgan server.
Http so'rovida kamida URI mavjud. Shuning uchun, agar mamlakat butun saytga emas, balki ma'lum bir sahifaga kirishni cheklamoqchi bo'lsa, https saytlari uchun buni qilish mumkin emas.

2-qadam - shifrlangan javob.
Veb-server yo'lda osongina o'qilishi mumkin bo'lgan javobni taqdim etadi.
Yechim juda oddiy - brauzer mahalliy ravishda har bir https sayti uchun bir xil shaxsiy-ommaviy kalitlar juftligini yaratadi.
Va saytning ochiq kalitiga so'rov bilan birga u o'zining mahalliy ochiq kalitini yuboradi.
Veb-server uni eslab qoladi va http-javob yuborayotganda uni ma'lum bir mijozning ochiq kaliti bilan shifrlaydi.
Endi http-javob faqat mijoz brauzerining shaxsiy kalitining egasi (ya'ni mijozning o'zi) tomonidan shifrlanishi mumkin.

3-bosqich - umumiy kanal orqali xavfsiz ulanishni o'rnatish.
2-misolda zaiflik bor - xayrixohlarning http-so'rovini ushlashiga va ochiq kalit haqidagi ma'lumotlarni tahrirlashga hech narsa to'sqinlik qilmaydi.
Shunday qilib, vositachi aloqa kanali o'zgarmaguncha yuborilgan va qabul qilingan xabarlarning barcha mazmunini aniq ko'radi.
Buni hal qilish juda oddiy - brauzerning ochiq kalitini veb-serverning ochiq kaliti bilan shifrlangan xabar sifatida yuboring.
Keyin veb-server avval "sizning ochiq kalitingiz shunday" kabi javob yuboradi va bu xabarni xuddi shu ochiq kalit bilan shifrlaydi.
Brauzer javobni ko'rib chiqadi - agar "sizning ochiq kalitingiz shunday" xabari olinsa - bu ushbu aloqa kanali xavfsiz ekanligiga 100% kafolatdir.
Bu qanchalik xavfsiz?
Bunday xavfsiz aloqa kanalining yaratilishi ping*2 tezligida sodir bo'ladi. Masalan, 20ms.
Buzg'unchi oldindan tomonlardan birining shaxsiy kalitiga ega bo'lishi kerak. Yoki bir necha millisekundda shaxsiy kalitni toping.
Bitta zamonaviy shaxsiy kalitni buzish superkompyuterda o'nlab yillar davom etadi.

4-qadam - ochiq kalitlarning umumiy ma'lumotlar bazasi.
Shubhasiz, bu butun hikoyada tajovuzkor uchun mijoz va server o'rtasidagi aloqa kanalida o'tirish imkoniyati mavjud.
Mijoz o'zini server, server esa mijoz sifatida ko'rsatishi mumkin. Va ikkala yo'nalishda ham bir juft kalitga taqlid qiling.
Keyin tajovuzkor barcha trafikni ko'radi va trafikni "tahrirlash" imkoniyatiga ega bo'ladi.
Masalan, pul jo'natish manzilini o'zgartiring yoki onlayn-bankingdan parolni ko'chirib oling yoki "e'tirozli" kontentni bloklang.
Bunday hujumchilarga qarshi kurashish uchun ular har bir https sayti uchun ochiq kalitlarga ega bo'lgan umumiy ma'lumotlar bazasini o'ylab topishdi.
Har bir brauzer 200 ga yaqin shunday ma'lumotlar bazasi mavjudligini "biladi". Bu har bir brauzerda oldindan o'rnatilgan bo'ladi.
"Bilim" har bir sertifikatning ochiq kaliti bilan ta'minlanadi. Ya'ni, har bir maxsus sertifikatlashtirish organiga ulanish soxta bo'lishi mumkin emas.

Endi https uchun SSL-dan qanday foydalanish haqida oddiy tushuncha mavjud.
Agar siz miyangizni ishlatsangiz, maxsus xizmatlar ushbu tuzilmadagi biror narsani qanday buzishi mumkinligi aniq bo'ladi. Ammo bu ularga dahshatli harakatlar talab qiladi.
Va NSA yoki Markaziy razvedka boshqarmasidan kichikroq tashkilotlar - hatto VIPlar uchun ham mavjud himoya darajasini buzish deyarli mumkin emas.

Men ssh ulanishlari haqida ham qo'shaman. U erda ochiq kalitlar yo'q, shuning uchun nima qila olasiz? Muammo ikki yo'l bilan hal qilinadi.
ssh-by-parol varianti:
Birinchi ulanish vaqtida ssh mijozi bizda ssh serveridan yangi ochiq kalit borligi haqida ogohlantirishi kerak.
Va keyingi ulanishlar paytida, agar "ssh serveridan yangi ochiq kalit" ogohlantirishi paydo bo'lsa, bu ular sizni tinglashga harakat qilishlarini anglatadi.
Yoki siz birinchi ulanishingizda tinglangansiz, ammo endi siz server bilan vositachilarsiz muloqot qilasiz.
Aslida, telefon orqali tinglash fakti osongina, tez va qiyinchiliksiz aniqlanganligi sababli, bu hujum faqat ma'lum bir mijoz uchun maxsus holatlarda qo'llaniladi.

ssh-kalit varianti:
Biz flesh-diskni olamiz, unga ssh serveri uchun shaxsiy kalitni yozamiz (buning uchun shartlar va juda ko'p muhim nuanslar mavjud, lekin men foydalanish bo'yicha ko'rsatmalar emas, balki ta'lim dasturini yozyapman).
Biz ochiq kalitni ssh mijozi bo'ladigan mashinada qoldiramiz va biz ham uni sir saqlaymiz.
Biz flesh-diskni serverga olib kelamiz, uni joylashtiramiz, shaxsiy kalitni nusxalaymiz va flesh-diskni yoqamiz va kulni shamolga sochamiz (yoki hech bo'lmaganda uni nol bilan formatlaymiz).
Hammasi shu - bunday operatsiyadan keyin bunday ssh ulanishini buzish mumkin bo'lmaydi. Albatta, 10 yildan keyin superkompyuterda trafikni ko'rish mumkin bo'ladi - lekin bu boshqa voqea.

Oftopik uchun uzr so'rayman.

Endi nazariya ma'lum. Men sizga SSL sertifikatini yaratish jarayoni haqida gapirib beraman.

"Openssl genrsa" dan foydalanib, biz ochiq kalit uchun shaxsiy kalit va "bo'shliqlar" yaratamiz.
Biz "blankalarni" uchinchi tomon kompaniyasiga yuboramiz, unga eng oddiy sertifikat uchun taxminan 9 dollar to'laymiz.

Bir necha soatdan so'ng biz ushbu uchinchi tomon kompaniyasidan "ommaviy" kalitimiz va bir nechta ochiq kalitlar to'plamini olamiz.

Nima uchun uchinchi tomon kompaniyasi mening ochiq kalitimni ro'yxatdan o'tkazish uchun to'lashi kerak - bu alohida savol, biz buni bu erda ko'rib chiqmaymiz.

Endi yozuvning ma'nosi aniq:

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

β€œ/etc/ssl” jildida ssl muammolari uchun barcha fayllar mavjud.
domain1.com - domen nomi.
2018 yil asosiy yaratilish yilidir.
"kalit" - faylning shaxsiy kalit ekanligini ko'rsatish.

Va bu faylning ma'nosi:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com - domen nomi.
2018 yil asosiy yaratilish yilidir.
zanjirlangan - ochiq kalitlar zanjiri mavjudligini belgilash (birinchisi bizning ochiq kalitimiz, qolganlari esa ochiq kalitni chiqargan kompaniyadan olingan).
crt - tayyor sertifikat mavjudligini ko'rsatish (texnik tushuntirishlar bilan ochiq kalit).

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

Ushbu sozlama bu holatda ishlatilmaydi, lekin misol sifatida yoziladi.

Chunki bu parametrdagi xato serveringizdan spam yuborilishiga olib keladi (sizning xohishingizsiz).

Keyin hammaga aybdor emasligingizni isbotlang.

recipient_delimiter = +

Ko'pchilik bilmasligi mumkin, ammo bu elektron pochta xabarlarini tartiblash uchun standart belgi bo'lib, ko'pchilik zamonaviy pochta serverlari tomonidan qo'llab-quvvatlanadi.

Masalan, agar sizda pochta qutingiz bo'lsa "[elektron pochta bilan himoyalangan]"yuborishga harakat qiling"[elektron pochta bilan himoyalangan]- Qarang, bundan nima chiqadi.

inet_protocols = ipv4

Bu chalkash bo'lishi mumkin.

Lekin bu shunchaki shunday emas. Har bir yangi domen sukut bo'yicha faqat IPv4, keyin men har biri uchun alohida IPv6 ni yoqaman.

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

Bu erda biz barcha kiruvchi xatlar kaptarxonaga borishini aniqlaymiz.
Va domen, pochta qutisi, taxallus qoidalari - ma'lumotlar bazasiga qarang.

/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

Endi postfiks pochtani faqat dovecot bilan avtorizatsiya qilingandan keyingina yuborish uchun qabul qilinishi mumkinligini biladi.

Men, albatta, nima uchun bu erda takrorlanganini tushunmayapman. Biz allaqachon "virtual_transport" da kerak bo'lgan hamma narsani ko'rsatdik.

Ammo postfiks tizimi juda eski - ehtimol bu eski kunlarning orqaga qaytishi.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Bu har bir pochta serveri uchun boshqacha tarzda sozlanishi mumkin.

Mening ixtiyorimda 3 ta pochta serverim bor va bu sozlamalar turli xil foydalanish talablari tufayli juda farq qiladi.

Siz uni ehtiyotkorlik bilan sozlashingiz kerak - aks holda spam sizga tushadi yoki undan ham yomoni - sizdan spam chiqadi.

# SPF
policyd-spf_time_limit = 3600

Kiruvchi harflarning SPF darajasini tekshirish bilan bog'liq ba'zi plaginlarni sozlash.

# 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

Sozlama shundan iboratki, biz barcha chiquvchi elektron pochta xabarlari bilan DKIM imzosini taqdim etishimiz kerak.

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

Bu PHP skriptlaridan xat jo'natishda xatlarni yo'naltirishning asosiy tafsilotidir.

β€œ/etc/postfix/sdd_transport.pcre” fayli:

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

Chap tomonda muntazam iboralar mavjud. O'ng tomonda harfni belgilaydigan yorliq mavjud.
Yorliqga muvofiq postfiks - ma'lum bir harf uchun yana bir nechta konfiguratsiya qatorlarini hisobga oladi.

Muayyan harf uchun postfiks qanday aniq qayta sozlanishi "master.cf" da ko'rsatiladi.

4, 5, 6-qatorlar asosiy hisoblanadi. Biz qaysi domen nomidan maktub yuboryapmiz, biz ushbu belgini qo'yamiz.
Ammo eski koddagi PHP skriptlarida "dan" maydoni har doim ham ko'rsatilmaydi. Keyin foydalanuvchi nomi yordamga keladi.

Maqola allaqachon keng ko'lamli - men nginx+fpm ni o'rnatish orqali chalg'itishni xohlamayman.

Qisqacha aytganda, har bir sayt uchun biz o'z linux-foydalanuvchi egasini o'rnatamiz. Va shunga ko'ra sizning fpm-hovuzingiz.

Fpm-pool php ning istalgan versiyasidan foydalanadi (bir serverda siz php ning turli versiyalarini va hatto qo'shni saytlar uchun turli php.ini dan muammosiz foydalanishingiz mumkin bo'lsa juda yaxshi).

Shunday qilib, ma'lum bir Linux foydalanuvchisi "www-domain2" domen2.com veb-saytiga ega. Ushbu saytda dan maydonini ko'rsatmasdan elektron pochta xabarlarini yuborish uchun kod mavjud.

Shunday qilib, bu holatda ham, xatlar to'g'ri yuboriladi va hech qachon spamga tushmaydi.

Mening "/etc/postfix/master.cf"im shunday ko'rinadi:

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

Fayl to'liq taqdim etilmagan - u allaqachon juda katta.
Men faqat nima o'zgarganligini ta'kidladim.

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}

Bular spamassasin bilan bog'liq sozlamalar, bu haqda keyinroq.

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

Biz sizga 587 port orqali pochta serveriga ulanishga ruxsat beramiz.
Buning uchun tizimga kirishingiz kerak.

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

SPF tekshiruvini yoqing.

apt-get install postfix-policyd-spf-python

Yuqoridagi SPF tekshiruvlari uchun paketni o'rnatamiz.

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

Va bu eng qiziq narsa. Bu ma'lum bir IPv4/IPv6 manzilidan ma'lum bir domen uchun xat yuborish qobiliyatidir.

Bu rDNS uchun qilingan. rDNS - IP-manzil bo'yicha satrni qabul qilish jarayoni.
Pochta uchun esa bu xususiyat helo elektron pochta yuborilgan manzilning rDNS-ga to'liq mos kelishini tasdiqlash uchun ishlatiladi.

Agar helo xat yuborilgan elektron pochta domeniga mos kelmasa, spam ball beriladi.

Helo rDNS-ga mos kelmaydi - juda ko'p spam ball beriladi.
Shunga ko'ra, har bir domen o'z IP manziliga ega bo'lishi kerak.
OVH uchun - konsolda rDNS-ni ko'rsatish mumkin.
tech.ru uchun - muammo qo'llab-quvvatlash orqali hal qilinadi.
AWS uchun muammo qo'llab-quvvatlash orqali hal qilinadi.
"inet_protocols" va "smtp_bind_address6" - biz IPv6 qo'llab-quvvatlashini yoqamiz.
IPv6 uchun siz rDNS-ni ham ro'yxatdan o'tkazishingiz kerak.
"syslog_name" - va bu jurnallarni o'qish qulayligi uchun.

Sertifikatlarni sotib oling Bu yerda tavsiya qilaman.

Bu yerda postfix+dovecot havolasini sozlash.

SPF ni sozlash.

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

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

MySQL-ni sozlash, paketlarni o'zi o'rnatish.

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

disable_plaintext_auth = yes
auth_mechanisms = plain login

Avtorizatsiya faqat shifrlangan.

β€œ/etc/dovecot/conf.d/10-mail.conf” fayli

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

Bu erda biz harflar uchun saqlash joyini ko'rsatamiz.

Men ularni fayllarda saqlashni va domen bo'yicha guruhlanishini xohlayman.

"/etc/dovecot/conf.d/10-master.conf" fayli

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

Bu kaptarxonaning asosiy konfiguratsiya fayli.
Bu erda biz himoyalanmagan ulanishlarni o'chirib qo'yamiz.
Va xavfsiz ulanishlarni yoqing.

"/etc/dovecot/conf.d/10-ssl.conf" fayli

ssl = required
ssl_cert = </etc/nginx/ssl/domain1.com.2018.chained.crt
ssl_key = </etc/nginx/ssl/domain1.com.2018.key
local XX.XX.XX.X5 {
  ssl_cert = </etc/nginx/ssl/domain2.com.2018.chained.crt
  ssl_key =  </etc/nginx/ssl/domain2.com.2018.key
}

ssl o'rnatilmoqda. Biz ssl kerakligini ko'rsatamiz.
Va sertifikatning o'zi. Va muhim tafsilot "mahalliy" direktivdir. Qaysi mahalliy IPv4 ga ulanishda qaysi SSL sertifikatidan foydalanish kerakligini bildiradi.

Aytgancha, IPv6 bu erda sozlanmagan, men bu kamchilikni keyinroq tuzataman.
XX.XX.XX.X5 (domen2) - sertifikat yo'q. Mijozlarni ulash uchun domain1.com manzilini ko'rsatish kerak.
XX.XX.XX.X2 (domen3) - sertifikat mavjud, mijozlarni ulash uchun domain1.com yoki domain3.com ni belgilashingiz mumkin.

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

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Bu kelajakda spamassassin uchun kerak bo'ladi.

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

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Bu antispam plaginidir. "Spam" jildiga / o'tkazish vaqtida spamassasinni o'rgatish uchun kerak.

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

protocol pop3 {
}

Xuddi shunday fayl mavjud.

β€œ/etc/dovecot/conf.d/20-lmtp.conf” fayli

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

Lmtp sozlanmoqda.

"/etc/dovecot/conf.d/90-antispam.conf" fayli

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
}

Spam jildiga/o'tkazish vaqtida Spamassasin o'quv sozlamalari.

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

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

Kiruvchi harflar bilan nima qilish kerakligini ko'rsatadigan fayl.

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

require ["fileinto", "mailbox"];

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

Faylni kompilyatsiya qilishingiz kerak: "sievec default.sieve".

"/etc/dovecot/conf.d/auth-sql.conf.ext" fayli

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

Avtorizatsiya uchun sql fayllarini belgilash.
Va faylning o'zi avtorizatsiya usuli sifatida ishlatiladi.

"/etc/dovecot/dovecot-sql.conf.ext" fayli

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';

Bu postfiks uchun o'xshash sozlamalarga mos keladi.

"/etc/dovecot/dovecot.conf" fayli

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

Asosiy konfiguratsiya fayli.
Muhimi, biz bu erda ko'rsatamiz - protokollarni qo'shing.

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

apt-get install spamassassin spamc

Keling, paketlarni o'rnatamiz.

adduser spamd --disabled-login

Kimning nomidan foydalanuvchini qo'shamiz.

systemctl enable spamassassin.service

Yuklanganda spamassassin xizmatini avtomatik yuklashni yoqamiz.

"/etc/default/spamassassin" fayli:

CRON=1

Qoidalarni "sukut bo'yicha" avtomatik yangilashni yoqish orqali.

β€œ/etc/spamassassin/local.cf” fayli:

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

MySQL da β€œsa” maΚΌlumotlar bazasini β€œsa” foydalanuvchisi β€œparol” paroli bilan yaratishingiz kerak (adekvat narsa bilan almashtiring).

report_safe - bu xat o'rniga spam elektron pochta xabarini yuboradi.
use_bayes - spamassassin mashinasini o'rganish sozlamalari.

Qolgan spamassassin sozlamalari maqolaning boshida ishlatilgan.

Umumiy sozlamalar "spamassassin".
Yangi Spam xatlarni IMAP "Spam" jildiga ko'chirish haqida.
Dovecot + SpamAssassin ning oddiy kombinatsiyasi haqida.
Imap papkalarida harflarni ko'chirishda spamassasin o'rganish nazariyasini o'qishni maslahat beraman (va undan foydalanishni tavsiya etmayman).

============= Jamiyatga murojaat =============

Men hamjamiyatga yuborilgan xatlarning xavfsizlik darajasini qanday oshirish haqida fikr bildirmoqchiman. Men pochta mavzusiga juda chuqur kirib qolganman.

Shunday qilib, foydalanuvchi o'z mijozida bir juft kalit yaratishi mumkin (outlook, thunderbird, brauzer plaginlari, ...). Jamoat va xususiy. Ommaviy - DNS-ga yuborish. Shaxsiy - mijozga tejash. Pochta serverlari ma'lum bir qabul qiluvchiga yuborish uchun ochiq kalitdan foydalanishi mumkin edi.

Va bunday xatlar bilan spamdan himoya qilish uchun (ha, pochta serveri tarkibni ko'ra olmaydi) - siz 3 ta qoidani kiritishingiz kerak bo'ladi:

  1. Majburiy haqiqiy DKIM imzosi, majburiy SPF, majburiy rDNS.
  2. Antispam o'qitish mavzusidagi neyron tarmoq + mijoz tomonida buning uchun ma'lumotlar bazasi.
  3. Shifrlash algoritmi shunday bo'lishi kerakki, jo'natuvchi tomon qabul qiluvchi tomonga qaraganda shifrlash uchun protsessor quvvatini 100 baravar ko'p sarflashi kerak.

Ommaviy xatlarga qo'shimcha ravishda, "xavfsiz yozishmalarni boshlash uchun" standart taklif xatini ishlab chiqing. Foydalanuvchilardan biri (pochta qutisi) boshqa pochta qutisiga ilova bilan xat yuboradi. Maktubda yozishmalar uchun xavfsiz aloqa kanalini va pochta qutisi egasining ochiq kalitini (mijoz tomonida shaxsiy kalit bilan) ishga tushirish bo'yicha matn taklifi mavjud.

Hatto har bir yozishma uchun maxsus ikkita kalit yasashingiz mumkin. Qabul qiluvchi foydalanuvchi ushbu taklifni qabul qilishi va o'zining ochiq kalitini yuborishi mumkin (shuningdek, ushbu yozishmalar uchun maxsus qilingan). Keyinchalik, birinchi foydalanuvchi xizmatni nazorat qilish xatini yuboradi (ikkinchi foydalanuvchining ochiq kaliti bilan shifrlangan) - uni olgandan so'ng, ikkinchi foydalanuvchi shakllangan aloqa kanalini ishonchli deb hisoblashi mumkin. Keyinchalik, ikkinchi foydalanuvchi nazorat xatini yuboradi - keyin birinchi foydalanuvchi ham tuzilgan kanalni xavfsiz deb hisoblashi mumkin.

Yo'lda kalitlarni ushlab turishga qarshi kurashish uchun protokol flesh-disk yordamida kamida bitta ochiq kalitni uzatish imkoniyatini ta'minlashi kerak.

Va eng muhimi, barchasi ishlaydi (savol "kim to'laydi?"):
10 yil uchun 3 dollardan boshlanadigan pochta sertifikatlarini kiriting. Bu jo'natuvchiga DNS-da "mening ochiq kalitlarim shu erda" ekanligini ko'rsatishga imkon beradi. Va ular sizga xavfsiz ulanishni boshlash imkoniyatini beradi. Shu bilan birga, bunday ulanishlarni qabul qilish bepul.
gmail nihoyat o'z foydalanuvchilarini monetizatsiya qilmoqda. 10 yil uchun 3 dollar uchun - xavfsiz yozishma kanallarini yaratish huquqi.

============= Xulosa =============

To'liq maqolani sinab ko'rish uchun men bir oyga maxsus serverni ijaraga olmoqchi edim va SSL sertifikati bilan domen sotib olmoqchi edim.

Ammo hayot sharoitlari rivojlanib, bu masala 2 oyga cho'zildi.
Shunday qilib, yana bo'sh vaqtim bo'lgach, nashrning yana bir yilga cho'zilib ketishi xavfidan ko'ra, maqolani avvalgidek chop etishga qaror qildim.

Agar "lekin bu etarli darajada batafsil tavsiflanmagan" kabi savollar juda ko'p bo'lsa, unda yangi domen va yangi SSL sertifikatiga ega bo'lgan maxsus serverni olish va uni yanada batafsilroq tavsiflash va ko'pchilik muhimi, barcha etishmayotgan muhim tafsilotlarni aniqlang.

Shuningdek, pochta sertifikatlari haqidagi g'oyalar haqida fikr-mulohazalarni olmoqchiman. Agar sizga g'oya yoqsa, men rfc uchun qoralama yozish uchun kuch topishga harakat qilaman.

Maqolaning katta qismlarini nusxalashda ushbu maqolaga havola bering.
Boshqa tilga tarjima qilganda, ushbu maqolaga havolani taqdim eting.
Men o'zim uni ingliz tiliga tarjima qilishga harakat qilaman va o'zaro havolalar qoldiraman.


Manba: www.habr.com

a Izoh qo'shish