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

この記事では、最新のメールサーバーの設定方法について説明します。
Postfix + Dovecot。SPF + DKIM + rDNS。IPv6対応。
TLS暗号化。複数のドメインをサポート — 実際のSSL証明書を使用した部分。
スパム保護と、他のメールサーバーにおける高いスパム評価。
複数の物理インターフェイスをサポート。
OpenVPN対応、IPv4で接続され、IPv6を提供します。

これらの技術を学びたくないが、そのようなサーバーを設定したい場合、この記事はあなたのためです。

この記事は、各詳細を説明しようとするものではなく、設定が標準でないか、消費者の視点から重要な点について説明します。

メールサーバーを設定する動機 — 私の長年の夢です。バカに聞こえるかもしれませんが、個人的には新しい好きな車の夢を見るよりもずっと良いです。

IPv6を設定する動機は2つあります。IT専門家は新しい技術を常に学ぶ必要があり、生き残るために。検閲との戦いに僅かでも貢献したいです。

OpenVPNの設定動機 — IPv6がローカルマシンで機能するためだけです。
複数の物理インターフェイスを設定する動機 — 私のサーバーには、「遅いが無制限」のインターフェイスと、「速いが制限付き」のインターフェイスがあります。

Bindを設定する動機 — 私のプロバイダーは不安定なDNSサーバーを提供しており、Googleも時々問題があります。個人使用のために安定したDNSサーバーが必要です。

この記事を書く動機 — 原稿は10か月前に書かれ、私はすでに2回見返しています。著者が定期的に必要とする場合、他の人にも必要とされる可能性が高いです。

メールサーバーに対するユニバーサルな解決策はありません。しかし、「こうして設定して、すべてがうまくいったら余分なものを捨ててください」といった形で書くつもりです。

会社tech.ruのColocationサーバーがあります。OVH、Hetzner、AWSと比較する機会があります。この問題を解決するためには、tech.ruとの協力がはるかに効率的です。

サーバーにはDebian 9がインストールされています。

サーバーには2つのインターフェイス `eno1` と `eno2` があり、最初は無制限、次は速いです。

インターフェイス `eno1` に3つの静的IPアドレス、XX.XX.XX.X0、XX.XX.XX.X1、およびXX.XX.XX.X2があり、`eno2`にはXX.XX.XX.X5があります。

インターフェイス `eno1` に割り当てられたXXXX:XXXX:XXXX:XXXX::/64のIPv6アドレスプールがあり、私の依頼によりXXXX:XXXX:XXXX:XXXX:1:2::/96が`eno2`に割り当てられました。

3つのドメイン `domain1.com`、 `domain2.com`、 `domain3.com` があります。 `domain1.com` と `domain3.com` にはSSL証明書があります。

Gmailインターフェイスから直接メールを受信および送信するために、`vasya.pupkin@domain1.com` のメールボックスをリンクさせたいGoogleアカウントがあります。
Պ باید լինեն էլեկտրոնային փոստի ենթակայանը `support@domain2.com`, որի պատճենն ուզում եմ տեսնել իմ gmail-ում: Եվ հազվագյուտ դեպքում ունեմ հնարավորություն ինչ-որ բան ուղարկել `support@domain2.com` անունից վեբ-հարակիցով:

Պ պետք է լինի էլեկտրոնային փոստի ենթակայանը `ivanov@domain3.com`, որով կօգտագործի Իվանով իր iPhone-ից:

Ուղարկվող նամակները պետք է համապատասխանի բոլոր ժամանակակից հակահակաիմաստների պահանջներին:
Պ պետք է լինի լավագույն մակարդակի ծածկագրման, որը նախատեսված է հանրային ցանցերում:
Պ պետք է լինի IPv6-ի աջակցություն և ուղարկելու, և ստանալու նամակների համար:
Պ պետք է լինի SpamAssassin, որը երբեք չի ջնջի նամակները: Այն պետք է կամ վերադարձնի կամ թույլ տա անցնել կամ տալ IMAP «Սպամ» թղթապանակ:
Պ պետք է կարգավորվի SpamAssassin-ի ավտո-ուսուցումը. եթե ես շարժում եմ նամակը «Սպամ» թղթապանակ, ապա պիտի սովորի դրանից; եթե ես շարժում եմ նամակը «Սպամ» թղթապանակից, ապա պիտի սովորի դրանից: SpamAssassin-ի ուսուցանման արդյունքները պետք է ազդեն նամակի «Սպամ» թղթապանակ ընկնելու վրա:
PHP-scriptերը պետք է կարողանան ուղարկել նամակներ ցանկացած ումից մեկ դոմենից այս սերվերում:
Պ պետք է լինի openvpn ծառայություն, որի միջոցով կարելի է օգտագործել IPv6 հաճախորդի հետ, ով չունի IPv6:

Առաջ 먼저 պետք է կարգավորել ինտերֆեյսները և երթևեկությունը, ներառելով IPv6:
Այնուհետև պետք է կարգավորել OpenVPN, որը կկապվի IPv4-ով և կտա հաճախորդինStatics IPv6 հասցե: Այս հաճախորդը կունենա մուտք դեպի բոլոր IPv6 ծառայություններին սերվերում և ներթողները IPv6 ինտերնետի ռեսուրսներին:
Այնուհետև պետք է կարգավորել Postfix նամակների ուղարկման համար + SPF + DKIM + rDNS և մյուս նման մանրարկայությունները:
Այնուհետև պետք է կարգավորել Dovecot և կարգավորել Multidomain:
Այնուհետև պետք է կարգավորել SpamAssassin և կազմակերպել ուսուցումը:
Վերջում պետք է տեղադրել Bind:

============= Կիսահամակարգեր =============

Ինտերֆեյսները կարգավորելու համար պետք է գրել հետևյալը «/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

Այս կարգավորումները կարելի է կիրառել ցանկացած սերվերում tech.ru-ում (մի փոքր համաձայնության հետ աջակցությամբ) և այն անմիջապես կընդուներ այնպես, ինչպես պետք է:

Եթե ունեք նման բաների կարգավորելու փորձ Hetzner-ի, OVH-ի համար՝ այնտեղ այլ կերպ է: Շնորհաբեր:

eno1 — դա է ցանցային քարտի անվանում #1 (հետևակի, բայց առանց սահմանափակման):
eno2 — դա է ցանցային քարտի անվանում #2 (արագ, բայց բարեգործությամբ):
tun0 — դա է OpenVPN-ից վիրտուալ ցանցային քարտի անվանում:
XX.XX.XX.X0 — IPv4 #1 eno1-ում:
XX.XX.XX.X1 — IPv4 #2 eno1-ում:
XX.XX.XX.X2 — IPv4 #3 eno1-ում:
XX.XX.XX.X5 — IPv4 #1 eno2-ում:
XX.XX.XX.1 — IPv4 դարպաս:
XXXX:XXXX:XXXX:XXXX::/64 — IPv6 ամբողջ սերվերին:
XXXX:XXXX:XXXX:XXXX:1:2::/96 — IPv6- ի համար eno2, ամեն ինչ մնացածը մտնում է eno1:
XXXX:XXXX:XXXX:XXXX::1 — IPv6 դարպաս (արժե նշել, որ այստեղ կարելի է/պետք է արվի այլ կերպ: Դրաներին նշեք IPv6-switch):
dns-nameservers — ցույց են տրված 127.0.0.1 (որովհետև տեղադրված է bind տեղական) և 213.248.1.6 (այս tech.ru-ից է):

«table eno1t» և «table eno2t» — այս route-rule-ի իմաստն այն է, որպեսզի ինտերնետային երթևեկությունը անցնի eno1 ճանապարհով, իսկ ինտերնետային երթևեկությունը անցնի eno2 ճանապարհով: Եվ նաև ստեղծվող կապերը նախաձեռնությամբ սերվերի դիմաց պիտի անցնեն eno1:

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

Այս հրամանով մենք սահմանում ենք, որ յուրաքանչյուր անհայտ երթևեկություն, որը ընկել է «table eno1t» նշված ցանկացած կանոնի տակ -> ուղղվում է eno1 ինտերֆեյսին:

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

Այս հրամանով մենք սահմանում ենք, որ ցանկացած երթևեկություն, որը խնդիր է ստեղծած սերվերի կողմից, ուղղվում է eno1 ինտերֆեյսին:

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

Այս հրամանով մենք սահմանում ենք երթևեկության տպման կանոնները:

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

Այս հատվածը սահմանում է երկրորդ IPv4-ն eno1 ինտերֆեյսի համար:

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

Այս հրամանով մենք սահմանում ենք route OpenVPN հաճախորդներից դեպի տեղական IPv4-ի բացառությամբ XX.XX.XX.X0:
Ինչու այս հրամանն աշխատում է բոլոր IPv4-ի համար — ես մինչ այսօր չեմ հասկանում:

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

Այստեղ մենք սահմանում ենք հասցեն հենց իններֆեյսի համար: Սերվերը դա կիրառում է որպես «առնվող» հասցե: Այն չի օգտագործվի այլ կերպ:

Ինչու նշված է «:1:1::» այնքան դժվար է: Դա անհրաժեշտ է, որպեսզի OpenVPN-ը ճիշտ աշխատանքի վստահելի լինի և միայն այս համար: Այս մասին ավելի մանրամասն կասկածներ կան:

Գateway-ի մասին — այսպես աշխատում է և լավ է: Բայց ճիշտը՝ այստեղ պետք է նշել IPv6-ի անցուղին, որի հետ սերվերը միացված է:

Սակայն ինչ որ պատճառով IPv6-ը աշխատանքը դադարում է, երբ ես այսպես անում եմ: Հավանաբար, դա tech.ru-ի խնդիրներ են:

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

Սա IPv6 հասցեի ավելացումն է ինտերֆեյսին: Եթե անհրաժեշտ են հարյուր հասցեներ — նշանակում է մեկ հարյուր տող այս ֆայլում:

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

Շեշտել եմ հասցեներն ու ենթածրագրերի բոլոր ինտերֆեյսների համար, որպեսզի տեսանելի լինի:
eno1 — անպայման պետք է լինի «/64» — քանի որ սա մեր բոլոր հասցեների հավաքածուն է:
tun0 — ենթածանցը պետք է որոշակիորեն լինի մեծ eno1-ից: Այլապես չի լինի հնարավոր կարգավորել IPv6 gateway OpenVPN հաճախորդների համար:
eno2 — ենթածանցը պետք է որոշակիորեն լինի մեծ tun0-ից: Այլապես OpenVPN հաճախորդները չեն կարողանա հասնել տեղական IPv6 հասցեներին:
Հստակության համար ես ընտրել եմ ենթածանցի քայլ 16, բայց ցանկության դեպքում կարելի է նույնիսկ «1» քայլ անել:
Հետեւաբար 64+16 = 80, իսկ 80+16 = 96:

Շարունակելու համար առավելություն՝
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY — դա հասցեները, որոնք պետք է նշանակված լինեն կոնկրետ կայքերին կամ ծառայություններին eno1 ինտերֆեյսում:
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY — դա հասցեները, որոնք պետք է նշանակված լինեն կոնկրետ կայքերին կամ ծառայություններին eno2 ինտերֆեյսում:
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY — դա հասցեները, որոնք պետք է նշանակված լինեն OpenVPN հաճախորդներին կամ օգտագործվել որպես OpenVPN ծառայողական հասցեներ:

Կարծիքով, որ կարելի է վերագործարկել սերվերը:
IPv4 փոփոխությունները կստացվեն, եթե կատարվի (պահանջեք փակել screen-ում՝ այս հրամանը պարզապես կ՛ընկնի սերվերի ցանցը):

/etc/init.d/networking restart

Ֆայլում «/etc/iproute2/rt_tables» ավելացրեք վերջում:

100 eno1t
101 eno2t

Այսպես հնարավոր չէ օգտագործել կաստոմացված table-ը «/etc/network/interfaces» ֆայլում:
Թվեր պետք է լինեն եզակի և նվազագույնը 65535-ից փոքր։

IPv6 փոփոխությունները հեշտությամբ փոխվում են առանց վերագործարկելու, բայց դրա համար պետք է սովորել նվազագույնը երեք հրամաններ․

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

Կարգավորում «/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

Անկախաբար, սա իմ սերվերի «sysctl» կարգավորումն է։ Կարևոր է նշել:

net.ipv4.ip_forward = 1

Այն առանց этого OpenVPN չի գործի։

net.ipv6.ip_nonlocal_bind = 1

Ով էլ փորձի անել bind IPv6 (օրինակ nginx) անմիջապես հետո, երբ անջատիչը կարգավորվել է, կստանա սխալ։ Պարզապես հաստատված հասցեն անհասանելի է։

Այդպիսի իրավիճակներից խուսափելու համար է, որ այդ կարգավորումը կատարվում է։

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

Այս կարգավորումները առանց այդպես OpenVPN հաճախորդի IPv6 տրաֆիկը աշխարհ դուրս չի գալիս։

Այլ կարգավորումները կամ չեն վերաբերվում հարցին կամ չեմ հիշում ինչի համար են։
Բայց բոլոր դեպքերում թողնում եմ «ինչպես կա»։

Այս ֆայլի փոփոխությունները առանց սերվերի վերագործարկելու ներբեռնելու համար անհրաժեշտ է կատարել հրաման․

sysctl -p

Ավելի մանրամասն «table» կանոնների մասին։ habr.com/post/108690

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

OpenVPN IPv4-ը չի գործում առանց iptables-ի։

Ինձ մոտ iptables այսպիսիք են 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 — սա իմ տեղական մեքենայի ստատիկ IPv4 հասցեն է։
10.8.0.0/24 — openvpn-ի IPv4 ցանցը։ IPv4 հասցեներն openvpn հաճախորդների համար։
Կանոնների հաջորդականությունը կարևոր է։

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

Սա սահմանափակում է, որպեսզի միայն ես իմ ստատիկ IP-ով կարողանամ օգտվել OpenVPN-ից։

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

IPv4 փաթեթների փոխանցման համար OpenVPN հաճախորդների և ինտերնետի միջև՝ անհրաժեշտ է գրանցել այս հրամաններից մեկն։

Բազմաթիվ դեպքերի դեպքում մեկն այլընտրանք չի համապատասխանում։
Իմ դեպքի համար երկու հրամանը նույնպես համապատասխանում են։
Ուղեցույցի ուսումնասիրությունից հետո ընտրեցի առաջին տարբերակը, քանի որ դա ավելի քիչ CPU է օգտագործում։

Բոլոր iptables կարգավորումները վերագործարկումից հետո կիրառելու համար անհրաժեշտ է պահպանել դրանք ինչ-որ տեղ։

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

Այս անունները ընտրվել են պատահական չէ։ Դրանք օգտագործում է «iptables-persistent» փաթեթը։

apt-get install iptables-persistent

OpenVPN-ի հիմնական փաթեթի տեղադրում․

apt-get install openvpn easy-rsa

Կարգավորենք սերտիֆիկատների համար ձևանմուշը (միացնել սեփական արժեքները)։

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

Փոփոխենք սերտիֆիկատի ձևանմուշի կարգավորումները․

mcedit vars

...
# Այստեղ գտնվում են սերտիֆիկատի դաշտերի համար արդիական արժեքները։
# Ներքևևեք չլքեք ոչ մի դաշտ։
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Krasnodar"
export KEY_CITY="Dinskaya"
export KEY_ORG="Own"
export KEY_EMAIL="admin@domain1.com"
export KEY_OU="VPN"

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

Ստեղծենք սերվերի սերտիֆիկատը։

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

Կարող եք ստեղծել «client-name.opvn» վերջնական ֆայլեր.

mkdir -p ~\/client-configs\/files
chmod 700 ~\/client-configs\/files
cp \/usr\/share\/doc\/openvpn\/examples\/sample-config-files\/client.conf ~\/client-configs\/base.conf
mcedit ~\/client-configs\/base.conf

# Client mode
client

# Interface tunnel type
dev tun

# TCP protocol
proto tcp-client

# Address/Port of VPN server
remote XX.XX.XX.X0 1194

# Don't bind to local port/address
nobind

# Don't need to re-read keys and re-create tun at restart
persist-key
persist-tun

# Remote peer must have a signed certificate
remote-cert-tls server
ns-cert-type server

# Enable compression
comp-lzo

# Custom
ns-cert-type server
tls-auth ta.key 1
cipher DES-EDE3-CBC

Պատրաստենք սկրիպտ, որը միավորելու է բոլոր ֆայլերը մեկ opvn ֆայլում.

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

#!/bin/bash

# First argument: Client identifier

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

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

Ստեղծում ենք առաջին OpenVPN հաճախորդը:

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

Ֆայլ «~\/client-configs\/files\/client-name.ovpn» ուղարկում ենք հաճախորդի սարքին:

iOS հաճախորդների համար պետք է անել հնարք:
«tls-auth» վանդակների բովանդակությունը պետք է լինի առանց մեկնաբանությունների.
Եվ պետք է տեղադրել «key-direction 1» անմիջապես «tls-auth» վանդակի առաջ.

Համակարգենք OpenVPN սերվերի կոնֆիգը:

cd ~\/openvpn-ca\/keys
cp ca.crt ca.key server.crt server.key ta.key dh2048.pem \/etc\/openvpn
gunzip -c \/usr\/share\/doc\/openvpn\/examples\/sample-config-files\/server.conf.gz | tee \/etc\/openvpn\/server.conf
mcedit \/etc\/openvpn\/server.conf

# Listen port
port 1194

# Protocol
proto tcp-server

# IP tunnel
dev tun0
tun-ipv6
push tun-ipv6

# Master certificate
ca ca.crt

# Server certificate
cert server.crt

# Server private key
key server.key

# Diffie-Hellman parameters
dh dh2048.pem

# Allow clients to communicate with each other
client-to-client

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

# Run client-specific script on connection and disconnection
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/server-clientdisconnect.sh"

# Server mode and client subnets
server 10.8.0.0 255.255.255.0
server-ipv6 XXXX:XXXX:XXXX:XXXX:1:3::/80
topology subnet

# IPv6 routes
push "route-ipv6 XXXX:XXXX:XXXX:XXXX::/64"
push "route-ipv6 2000::/3"

# DNS (for Windows)
# These are OpenDNS
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

# Configure all clients to redirect their default network gateway through the VPN
push "redirect-gateway def1 bypass-dhcp"
push "redirect-gateway ipv6" #For iOS

# Don't need to re-read keys and re-create tun at restart
persist-key
persist-tun

# Ping every 10s. Timeout of 120s.
keepalive 10 120

# Enable compression
comp-lzo

# User and group
user vpn
group vpn

# Log a short status
status openvpn-status.log

# Logging verbosity
##verb 4

# Custom config
tls-auth ta.key 0
cipher DES-EDE3-CBC

Սա անհրաժեշտ է, որպեսզի յուրաքանչյուր հաճախորդի համար սահմանենք կայանային հասցե (անգամ պարտադիր չէ, բայց ես օգտագործում եմ):

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

Ինքնաթիռի ամենաբարդ և հիմնական մանրուքը:

Ցավոք, OpenVPN դեռ չի կարող ինքնաբերաբար կարգավորել IPv6 երթուղի հաճախորդների համար.
Պետք է «համահարթիլ» անցկացնել յուրաքանչյուր հաճախորդի համար.

# 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»:

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

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

Երկու սկրիպտներն էլ օգտագործում են «\/etc\/openvpn\/variables» ֆայլը:

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

Որովհետև այստեղ գրել է այսպես՝ դժվարանում եմ դիմել հիշել.

Այժմ անհավանական է երևում netmask = 112 (այստեղ 96 պետք է լինի).
Եվ սկիզբը տարօրինակ է, չի համապատասխանում tun0 ցանցին.
Բայց լավ, թողնեմ «ինչպես կա».

cipher DES-EDE3-CBC

Սա սիրողի համար է՝ ես ընտրեցի այս միացման շիֆրումը.

Լվացքի OpenVPN IPv4-ի կարգավորումների մասին.

Լվացքի OpenVPN IPv6-ի կարգավորումների մասին.

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

Հիմնական փաթեթի տեղադրում:

apt-get install postfix

Ամբողջացման ժամանակ ընտրել «internet-site».

Իմ «\/etc\/postfix\/main.cf» выглядит так:

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

Համոզվենք, որ այս կոնֆիգի մանրամասները պարզ են:

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

Հաբրոներին ներկայացված է, որ այս հատվածն ունի `հոխորտումներ և սխալ որոշումներ`:Իմ կարիերայի 8 տարվա ընթացքում ես միայն սկսեցի հասկանալ, թե ինչպես է աշխատում SSL:

Ուրեմն, ես կառաջնորդեմ, թե ինչպես օգտագործել SSL (չես առարկի հարցերին «Ինչպե՞ս է սա աշխատում» և «Ինչու է սա աշխատում»):

Современное шифрование строится на создании пары ключей (երկու երկար շարքային նշաններ):

Մի «սովորական» բան, մյուս բանն է «հանրային»: «Pravitn» բանն դրույքով թողնում ենք, իսկ հանրային բանն ամեն մեկին տրամադրում ենք:

Հանրային բաների միջոցով կարելի է կոդավորել տեքստի շարք, այնպես, որ միայն «Pravitn» բանի տերը կարողանա այն քաղել:
Այսպիսով, սա տեխնոլոգիայի հիմունքն է:

Քայլ 1 — https կայքերը:
Բրաուզերը կայքի դիմումը գտնում է Web Server-ից, որ կայքը https է ու հետևաբար հանրային բան է պահանջում:
Web Server-ը տրամադրում է հանրային բան: Բրաուզերը այդ հանրային բանով կոդավորում է http-request-ը և ուղարկում նրան:
Http-request-ը կարող է կարդալ միայն նա, ով ունի «Pravitn» բան, այսինքն այն միայն սերվերը, որին դիմում են:
Http-request-ում առնվազն URI-ն կա: Ուստի, եթե երկրի մեջ փորձում են դատարանի մուտքը սահմանափակել ոչ բոլոր կայքերով, այլ կոնկրետ էջերով, ապա https կայքերն մեծ դժվարություն են բերում այս ավելին:

Քայլ 2 — գաղտնային պատասխան:
Համացանցի սերվերը տալիս է պատասխան, որը հեշտությամբ կարելի է ընթերցել ճանապարհին։
Լուծումը չափազանց պարզ է՝ բրաուզերն ինքն իրենում ձևավորում է այնպես, ինչպես այդ նույն զույգը՝ գաղտնի-հրապարակային բանալի յուրաքանչյուր https կայքի համար։
Եվ միասին https կայքի հանրային բանալիի հարցման հետ ուղարկում է իր տեղական հանրային բանալին։
Համացանցի սերվերը հիշում է այն և http-response ուղարկելու ժամանակ գաղտնագրում է այս հանրային բանալով կոնկրետ հաճախորդի համար։
Այսպիսով http-response-ը կարող է բանալվող միայն այն անձը, ով ունի բրաուզերի գաղտնի բանալին (ինքն ՝ հաճախորդը):

Քայլ №3՝ անվտանգ կապի հաստատումը հանրային ալիքով։
Մասին №2 կան խոցելիություններ՝ ոչինչ չի խանգարում հիանալի մարդկանց հայթայթել http-request-ը և խմբագրել հանրային բանալիի տեղեկատվությունը։
Այսպիսով միջնորդը հրաշալիորեն կտեսնի ուղարկված-ստացված հաղորդումների ամբողջ բովանդակությունը, մինչև կապի ալիքը չի փոխվում։
Դրա դեմ պայքարելը չափազանց պարզ է՝ բավական է ուղարկել բրաուզերում հանրային բանալին որպես հաղորդագրություն, որը գաղտնագրված է համացանցի սերվերի հանրային բանալով։
Համացանցի սերվերը առաջինը 보내ում է «քո հանրային բանալին այսպիսին է» կարգի պատասխան և գաղտնագրում է այս հաղորդագրությունը նույն հանրային բանալով։
Բրաուզերը դիտում է պատասխան՝ եթե եկել է հաղորդագրություն «քո հանրային բանալին այսպիսին է»՝ ապա սա 100% garantías է, որ այս կապի ալիքը անվտանգ է։
Որքան安全?
Այսպիսի անվտանգ կապի ստեղծումը տեղի է ունենում ping*2 արագությամբ։ Օրինակ, 20 մս.
Մոլախաղը նախընտրում է ունենալ մեկի գաղտնի բանալին։ Լիովին բանալին մի քանի միլիվարկյանում ընտրել։
Մի ժամանակակից գաղտնի բանալիի խափանումը կտևի տասնամյակներ սուպեր համակարգչում։

Քայլ №4՝ հանրային բանալիների հանրային DB։
Ակնարգել է, որ այս պատմության մեջ կա պահպանված հնարավորություն՝ անվտանգության միջնորդի ձեռքում գտնվողին, ով գտնվում է կապի ալիքում հաճախորդի և սերվերի միջև։
Հնարավորություն է հաճախորդը ներկայացվի սերվերով, իսկ սերվերը ներկայացվի հաճախորդի։ Եվ կրկին ստեղծել բանալիների զույգը երկու կողմերի համար։
Այսպիսի ժամանակ հանցագործը կտեսնի ամբողջ տրաֆիկը և կունենա հնարավորություն «խմբագրի» տրաֆիկը։
Օրինակ՝ փոխել հասցեն, որտեղ փոխանցելու գումար, կամ պատճենել օնլայն բանկի մուտքի գաղտնաբառը, կամ արգելափակել «անհրաժեշտ» բովանդակությունը։
Այսպիսի հանցագործների դեմ պայքարելու համար մտածել են հանրային DB կազմված հրապարակային բանալիների համար յուրաքանչյուր https կայքի։
Յուրաքանչյուր բրաուզեր «գիտի», որ գոյություն ունի մոտ 200 նման DB։ Դա նախապես տեղադրված է յուրաքանչյուր բրաուզերի մեջ։
Գիտելիքը զորակոչված է յուրաքանչյուր վկայականի հանրային բանալիով։ Այսինքն, յուրաքանչյուր կոնկրետ վկայականի կենտրոնի հետ կապ հաստատելը անհնար է։

Հիմա կա պարզ հասկացողություն, թե ինչպես օգտագործել SSL որպես https։
Եթե մի քիչ մտածեք՝ ապա կհասկանաք, թե ինչպես հատուկ ծառայությունները կարող են այս կառուցվածքում ինչ-որ բան խափանել։ Բայց սա նրանց մեծ ջանքեր կարժենա։
ՀԿ-ներին ու պետական մարմիններին, ինչպիսիք են АНБ-ն կամ ЦРУ-ն, գրեթե անհնար է հարձակվել արդեն առկա պաշտպանության մակարդակի վրա նույնիսկ VIP-երի համար:

Բացի այդ, խոսենք ssh կապերի մասին: Այստեղ ոչ մի հանրային բանալու չունենք, ինչպե՞ս վարվել: Գործողությունը լուծվում է երկու եղանակով:
ssh-ով գաղտնաբառով տարբերակ:
Առաջին կապի ժամանակ ssh-clients պետք է նախազգուշացնեն, որ այստեղ նոր հանրային բանալուն ունեմ ssh-ծառից:
Եվ շարունակական կապերի ժամանակ, եթե հայտնվում է «նոր հանրային բանալու ssh-ծառից» նախազգուշացումը՝ դա կհիշեցնի, որ դուք փորձում են լսել:
Կամ, առաջին կապի ժամանակ դուք լսվել եք, իսկ այժմ դուք հաղորդակցվում եք առանց միջնորդների:
Իրականում, այդ փաստը, որ լսելն հեշտ, արագ և առանց ջանքերի բացահայտվում է, այս հարձակմամբ միայն հատուկ դեպքերում օգտագործվում է՝ որոշակի հաճախորդի համար:

ssh-ով բանալիով տարբերակ:
Վերցնում ենք ֆլեշկա, գրում դրա վրա ssh-ծառի մասնավոր բանալին ( hierfür gibt es термины und куча нюансов, aber я пишу ликбез, а не инструкцию по применению).
Հանրային բանալին թողնում ենք այն մեքենայում, որտեղ կլինի ssh-clients և այն նույնպես պահում ենք գաղտնի:
Ֆլեշկան բերում ենք ծառին, տեղադրում ենք, պատճենում մասնավոր բանալին, իսկ ֆլեշկային այրում ենք և քամուն ենք դնում մոխիրը (ինչպես նվազագույնը ձևակերպում ենք զրոյով):
Դա ամեն ինչ է՝ նման գործողությունից հետո ssh կապը խախտելը անհնար կլինի: Անզեգության, 10 տարի հետո բորհերի վրա կարող կլինի դիտարկել տրաֆիկը՝ բայց դա առանձին պատմություն է:

Ներեցեք ավելորդ թեման:

Այժմ, երբ տեսնում ենք տեսությունը, պատմեմ ssl վկայագրի ստեղծման մասին:

Համար «openssl genrsa» մենք ստեղծում ենք մասնավոր բանալին և «պատրաստուկներ» հանրային բանալու համար:
«Պատրաստուկները» ուղարկում ենք երրորդ ընկերություն, որը վճարում ենք մոտ $9 յուրահատուկ վկայագրի համար:

Մի քանի ժամից ստանում ենք այդ ընկերությունից մեր «Հանրային» բանալին և մի քանի այլ հանրային բանալու հավաքածու:

Ինչու պետք է երրորդ ընկերությանը վճարել իմ հանրային բանալու ձևակերպման համար՝ առանձին հարց է, այստեղ չենք սպասարկում:

Այժմ հասկանալի է, թե ինչն է գրելու իմաստը:

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

Վիճակը «\/etc\/ssl»-ում պահվում են ssl հարցերի բոլոր ֆայլերը:
domain1.com — դոմենի անվանումը:
2018 — բանալու ստեղծման տարին:
«key» — նշում է, որ ֆայլը մասնավոր բանալին է:

Եվ այս ֆայլի իմաստը:

smtpd_tls_cert_file=\/etc\/ssl\/domain1.com.2018.chained.crt
domain1.com — դոմենի անվանումը:
2018 — բանալու ստեղծման տարին:
chained — նշում է, որ այստեղ հանրային բանալուների շղթա է (առաջինը՝ մեր հանրայինը և մնացածը այն, ինչը եկել է ընկերությունից, որը ձևակերպել է հանրային բանալին):
crt — նշում է, որ այստեղ պատրաստի վկայագիր է (հանրային բանալի տեխնիկական բացատրություններով):

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

Այս կարգավորումը այս դեպքում չի օգտագործվում, բայց նշված է օրինակ.uid

Որովհետև այս պարամետրին սխալը կբերի, որ ձեր սերվերից սպամ կուղարկվի (ձեր կամքից դուրս):

Հետագայում բոլորին ապացուցեք, որ դուք մեղավոր չեք:

recipient_delimiter = +

Երբեմն մարդիկ չեն գիտակցում, սակայն սա իմ քաղաքացիությունը դասակարգման ստանդարտ խորհրդանիշ է, և այս հանգույցը աջակցում է ժամանակակից փոստային սերվերների մեծամասնությանը։

Օրինակ, եթե لديك email «username@gmail.com» փորձեք ուղարկի «username+spam@gmail.com» — տեսեք, թե ինչ կընդունվի։

inet_protocols = ipv4

Այն կարող է շփոթեցնող լինել։

Բայց սա ուղղակի չէ։ Ամեն նոր դոմեն — միանշանակ միայն IPv4, հետո ես կգծեմ IPv6 յուրաքանչյուրի համար առանձին։

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

Այստեղ մենք սահմանում ենք, որ բոլոր incoming emails-ը գնում են dovecot-ի։
Եվ կանոնները domain, mailbox, alias ․․․ փնտրել տվյալ բազայում։

/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

Այժմ postfix-ը գիտի, որ երբ կրկին կարող ենք ընդունել փոստը, դա կարելի է անել միայն dovecot-ի պատկանման միջոցով։

Ինձ իսկապես շատ պարզ է, թե ինչու պետք է կրկնել այստեղ։ Մենք արդեն նշել ենք «virtual_transport»-ում ամեն ինչ, ինչ անհրաժեշտ է։

Բայց postfix-ը ամենահին համակարգն է՝ հավանաբար սա ապագա ժամանակներից մնացած հիվանդագին լուծումներ են։

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Սա յուրաքանչյուր փոստային սերվերի համար ինքնուրույն կարգավորվում է։

Իմ խնամակալության տակ կա 3 փոստային սերվեր, և այս կարգավորումները շատ տարբեր են, քանի որ դրանց օգտագործման պահանջները տարբեր են։

Հարկավոր է ուշադիր կարգավորել — այլապես սպամը կդրվի ձեզ մոտ կամ ավելի վատ — սպամը կուղարկվի ձեր կողմից։

# SPF
policyd-spf_time_limit = 3600

Կարգավորումը հենց որեւէ plugin-ի համար, որը կապված է incoming emails-ի SPF ստուգման հետ։

# 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

Կարգավորում, որ բոլոր outgoing emails-ը պետք է ապահովենք DKIM ստորագրությամբ։

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

Այսպիսի բան է, որ կուշտ փոստերի առաքման ժամանակ php սցենարներից emails ուղարկելու ընթացքում գլխավոր տարր է։

Ֆայլ «/etc/postfix/sdd_transport.pcre»:

/^www-domain1@domain1.com$/ domain1:
/^www-domain2@domain1.com$/ domain2:
/^www-domain3@domain1.com$/ domain3:
/@domain1.com$/             domain1:
/@domain2.com$/             domain2:
/@domain3.com$/             domain3:

Ձախում՝ կանոնները։ Դանդաղումներ՝ դրանք, որոնք հասցվում են փոստի։
Postfix-ը, ըստ դանդաղման — հաշվի կդնի ևս մի քանի կարգավորման շարք կոնկրետ փոստի համար։

Ինչպես հատկապես postfix-ը կդասակարգվի կոնկրետ փոստի համար՝ նշված կլինի «master.cf»-ում։

4, 5, 6-րդ տողերը՝ նրանք հիմնականն են։ Որ դոմենից ենք ուղարկում լուսանկարը՝ այդպիսի մետաղանիշ դնում ենք։
Բայց երբեք չէ ֆիլիպային սցենարներում ենթադրվում է, թե ինչպե՞ս է նշվում «from» դաշտը։ Այդ ժամանակ օգնության են գալի ձեր օգտատիրոջ անուն։

Հոդվածն ու այնպես շատ մեծ է — չեմ ցանկանա отвлекаться на настройку nginx+fpm.

Արդյունքում — յուրաքանչյուր կայքի համար սահմանվում է մեր Linux-user սեփականատեր։ Եվ համապատասխանաբար՝ իր fpm-pool-ն է։

Fpm-pool-ը օգտագործում է ցանկացած php տարբերակ (այսինքն հաճելի է, երբ նույն սերվերում առանց խնդիրներ այլ կայքերի համար կարելի է օգտագործել տարբեր php տարբերակ և նույնիսկ տարբեր php.ini)։

Այսպես է, այս linux-user-ի համար «www-domain2» կայքում կա domain2.com կայքը։ Չէ որ այս կայքում կա անվան դիմումի դաշտը բաց թողնելով նամակներ ուղարկելու կոդ։

Այսպես, նույնիսկ այս դեպքում նամակները կուղարկվեն ճիշտ և երբեք չեն попадут սպամի։

Իմ «/etc/postfix/master.cf» այսպիսին է՝

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

Ֆայլը ամբողջությամբ ներկայացված չէ՝ այն և այնպես շատ մեծ է։
Առանցքային նշել եմ միայն այն, ինչ փոփոխված է։

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}

Սա spamassasin-ի հետ կապված կարգավորումն է, որի մասին հետագայում։

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

Թույլ ենք տալիս միանալ փոստային սերվերին 587 պորտի միջոցով։
Այս համար պետք է unbedingt հաստատվել։

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

Միացնում ենք SPF ստուգումը։

apt-get install postfix-policyd-spf-python

Վերը նշված SPF ստուգումների փաթեթը տեղադրենք։

domain1  unix -       -       n       -       -       smtp
   -o smtp_bind_address=XX.XX.XX.X1
   -o smtp_helo_name=domain1.com
   -o inet_protocols=all
   -o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:1:1
   -o syslog_name=postfix-domain1

Սա ամենահետաքրքիրն է։ Սա հնարավորությունն է կոնկրետ դոմենի համար նամակներ ուղարկելու կոնկրետ IPv4/IPv6 հասցեից։

Սա արվում է rDNS-ի համար։ rDNS-ը՝ IP հասցեի համաձայն որևէ տող ստանալ։
Եվ փոստի համար այս հնարավորությունը օգտագործվում է, որպեսզի հաստատվի, որ helo-ն բավական է իրական rDNS-ին, այն հասցեին, որտեղից ուղարկվել է էլփոստը։

Եթե helo-ն չի համապատասխանում փոստի դոմենին, ում անունից ուղարկել են նամակը՝ սփամ միավորներ են տրամադրվում։

Helo-ն չի համապատասխանում rDNS-ին՝ շատ սփամ միավորներ են տրամադրվում։
Ուղղակի ամեն դոմենի համար պետք է իր IP հասցեն լինի։
OVH-ի համար՝ կոնսոլում կա հնարավորություն նշելու rDNS։
tech.ru-ի համար՝ հարցը լուծվում է սփամի միջոցով։
AWS-ի համար՝ հարցը լուծվում է սփամի միջոցով։
«inet_protocols» և «smtp_bind_address6» են՝ սա մեր կողմից IPv6-ի աջակցումը ակտիվացնում ենք։
IPv6-ի համար նույնպես rDNS պետք է ծածկագրել։
«syslog_name»՝ սա գրառումների հեշտ կարդալության համար։

Գնել սերտիֆիկատներ recommend here.

postfix+dovecot-ի կարգավորումը այստեղ է.

SPF-ի կարգավորում։

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

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

mysql-ը հարմարեցնելով, մենք ինքնուրույն ենք տեղադրում փաթեթները:

Ֆայլ «/etc/dovecot/conf.d/10-auth.conf»

disable_plaintext_auth = yes
auth_mechanisms = plain login

Հավաստագրման գործընթացը միայն encrypted ձևաչափով:

Ֆայլ «/etc/dovecot/conf.d/10-mail.conf»

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

Աստեղ կ նշենք նամակների պահման վայրը:

Ես ուզում եմ, որ նրանք պահվեն ֆայլերում և դասավորված լինեն դոմենների ըստ:

Ֆայլ «/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 {
  }
}

Այս մուտքային ֆայլն է նախաուզբռռքման ձեւով:
Այստեղ մենք փոխում ենք անկապ կապերը:
Եվ ակտիվացնում ենք պահպանված կապերը:

Ֆայլ «/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
}

Հարմարեցնում ենք ssl-ը: Ցուցադրում ենք, որ ssl-ն պետք է օգտագործվի:
Եվ ինքն էլ վկայական: Եվ կարևոր մի մանրուք՝ «local» պահանջը: Ցուցադրում է, թե որ տեղական IPv4-ի դեպքում պետք է օգտագործվի տվյալ ssl վկայականը:

Կողմից IPv6 այստեղ չի կարգավորված, ես կահավորեմ այդ բացահայտումը ինչ-որ ժամանակ հետո:
XX.XX.XX.X5 (domain2) — վկայականը չկա: Հաճախորդների կապելը պետք է նշի domain1.com:
XX.XX.XX.X2 (domain3) — վկայականը կա, հաճախորդների կապելը հնարավոր է domain1.com կամ domain3.com օգտագործել:

Ֆայլ «/etc/dovecot/conf.d/15-lda.conf»

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Սա հետագայում պետք է լինի spamassassin-ի համար:

Ֆայլ «/etc/dovecot/conf.d/20-imap.conf»

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Սա antispam plugin-ն է: Անկարչական անհրաժեշտ է spamassassin-ի ուսուցման ժամանակ `Spam` папкայի տեղափոխման ընթացքում:

Ֆայլ «/etc/dovecot/conf.d/20-pop3.conf»

protocol pop3 {
}

Կ simplement такой файл есть:

Ֆայլ «/etc/dovecot/conf.d/20-lmtp.conf»

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

lmtp-ի կարգավորումը:

Ֆայլ «/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
}

spamassassin-ի ուսուցման կարգավորումները `Spam` папկայի տեղափոխման ընթացքում:

Ֆայլ «/etc/dovecot/conf.d/90-sieve.conf»

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

Ֆայլ, որտեղ նշվում է, թե ինչ անել ստացող նամակների հետ:

Ֆայլ «/var/lib/dovecot/sieve/default.sieve»

require ["fileinto", "mailbox"];

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

Պետք է հավաքել ֆայլը՝ «sievec default.sieve»:

Ֆայլ «/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
}

SQL ֆայլերի ցուցում մուտք գործելու համար:
Իսկ ֆայլը՝ որպես մուտքի ձև:

Ֆայլ «/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';

Այսը համապատասխանում է postfix-ի համար նման կարգավորումներին:

Ֆայլ «/etc/dovecot/dovecot.conf»

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

Հիմնական կարգավորման ֆայլ:
Էականն այն է, որ այստեղ համակարգում ենք՝ ավելացնելով պրոտոկոլներ:

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

apt-get install spamassassin spamc

Կառնանք փաթեթները:

adduser spamd --disabled-login

Ավելացնենք օգտվող, որի անունից պետք է:

systemctl enable spamassassin.service

Ամռադրում ենք spamassassin ծառայության ավտոմատ սկսումը:

Ֆայլ «/etc/default/spamassassin»:

CRON=1

Ամռադրել ենք ավտոմատ թարմացման կանոնները՝ «ընդհանուր»:

Ֆայլ «/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

Պետք է անել mysql DB «sa» օգտվողով «sa» հետ՝ գաղտնաբառը «password» (փոխարինել մի բանով, որը հասկանալի է):

report_safe — այսինքն, թե ինչ-որ փոստային հաղորդագրություն կլինի՝ «սպամ» առաջադրելու մասին:
use_bayes — սա spamassassin-ի մեքենայական ուսուցման կարգավորումները:

Այլ spamassassin կարգավորումները կիրառվել են նախկինում ՝ ըստ հոդվածի:

Ընդհանուր spamassassin կարգավորում:.
Նոր սպամ հաղորդագրությունները IMAP «Spam» թղթապանակ տեղափոխելու մասին:.
Դովեկոտ + SpamAssassin պարզ ամուսնության մասին:.
Հանրապես խորհուրդ եմ տալիս կարդալ spamassassin-ի ուսման տեսությունը IMAP թղթապանակներում (և չեմ խորհուրդ տալիս կիրառել):.

============= Մասնագիտական համայնքին դիմում =============

Ուզում էի ևս մեկ գաղափար ներկայացնել համայնքին՝ ինչպես բարձրացնել ուղարկված նամակների Պահպանողականությունը: Այդ դեպքում ես բավականին խոր միավոր եմ տվել փոստին:

Որպեսզի օգտվողը կարողանա իր հաճախորդում (Outlook, Thunderbird, բրաուզեր-փլագին և այլն) ստեղծել միավոր էական գրոհներ: Պետական ու անձնական: Պետական — ուղարկել DNS: Անձնական — պահպանել հաճախորդում: Փոստային սերվերները կարող են կիրառել պետական բանալին՝ ուղարկելու կոնկրետ հասցեներ:

Եվ spam-ից պաշտպանվելու համար՝ այդպիսի նամակների վրա (այդպես, փոստային սերվերը չի կարող բովանդակությունը տեսնել)՝ անհրաժեշտ կլինի դրական երեք կանոններ ստանալ:

  1. Պարտադիր իրական DKIM հեղինակավոր ծանոթագրություն, պարտադիր SPF, պարտադիր rDNS:
  2. Նեյրոնային ցանց՝ հակասպամ ուսուցման թեմայով + տվյալների բազա լռացող կողմից:
  3. Նանման բարելավված գաղտնիաուն է պետք լինի, որ ուղարկող կողմը պետք է տանջվի 100 անգամ մեծ CPU ռեսուրսներով, քան ընդունող կողմը:

Բացի պետական նամակներից — մշակել նամակների ստանդարտ «սկսել ապահով հաղորդագրություն»: Առաջին օգտվողը (փոստի հասցեն) ուղարկում է մյուս փոստին հաղորդագրություն՝ թղթապանակով: Նամակում կա հաղորդագրություն՝ սկսել ապահով կապի ուղարկելու առաջարկ և պետական բանալին փչացած հասցեի սեփականատիրոջ (пրտ, անձնական բանալին հաճախորդի կողմից):

Շատ լավ է նույնիսկ ամեն հաղորդակցման համար հատուկ երկու բանալի պատրաստել։ Օգտատերը կարող է ընդունել այս առաջարկը և ուղարկել իր հանրային բանալին (թողարկված հատուկ այս հաղորդակցման համար)։ Ավելի հետո, առաջին օգտատերը ուղարկում է կառավարական վերահսկիչ նամակ (միջազգային բանալու միջոցով երկրորդ օգտատիրոջ) — ինչը ստանալով, երկրորդ օգտատերը կարող է համարվել, որ ստեղծված կապի ալիքը հուսալի է։ Եվ հետո երկրորդ օգտատերը ուղարկում է վերահսկիչ նամակ — և այդ դեպքում, առաջին օգտատերը նույնպես կարող է համարվել, որ ստեղծված ալիքը պաշտպանված է։

Բանն այն է, որ բանալիների փոխանցման ընթացքում միջամտություններն ապացուցելու համար — պետք է ապահովել խնդրի լուծում, որը ենթադրում է, որ գոնե մեկ հանրային բանալի փոխանցվի USB ֆլեշով։

Եվ ամենակարևորը` որ այս ամենը գործի (հարցը «իսկ ով դա կվճարի?»):
Ներմուծել փոստային վկայականներ 10 $ -ից 3 տարում: Որոնք թույլ կտան ուղարկողին նշել DNS-ում, որ «իմ հանրային բանալիներն այնտեղ են»։ Եվ կպատրաստեն հնարավորությունը պաշտպանված միացումներ սկսել։ Այս ընթացքում — նման միացումները ընդունվում են անվճար։
Gmail-ը վերջապես կհաստատի իր օգտատերերի մոնետիզացումը։ 10 $ -ով 3 տարում — իրավունք ունենալ պաշտպանված ալիքներ ստեղծելու համար։

============= Վերջաբանում =============

Այս հոդվածի ամբողջականությունը ստուգելու համար ես մտադրվել էի մեկ ամիս ժամանակով մասնավոր սերվեր վարձել և SSL վկայագրով դոմեն գնել։

Բայց կյանքային հանգամանքները այս հարցը երկարեց 2 ամիս։
Հայք եղավ, երբ ազատ ժամանակը պակասեց և որոշեցի գրել հոդվածը այնպես, ինչպես կա,՝ չ riesgo կատարել, որ հրապարակումը ևս մեկ տարի ձգվի։

Եթե տասնյակ հարցեր կբռնվեն, օրինակ «անգամ այս տեղում մանրամասն չէ նկարագրված» — այն ժամանակ հավանաբար ուժերը կգտնվեն դեռ մասնավոր սերվեր վերցնելու, նոր դոմենով և նոր SSL վկայությամբ ու լրացուցիչ մանրամասն նկարագրելու և ի վերջո՝ բացահայտելու բոլոր կարևոր մանրամասները։

Ինձ հետաքրքրում է նաև ասելիքը փոստային վկայության գաղափարի մասին։ Եթե գաղափարը դուր է գալիս — կփորձեմ գտնել ուժեր-ն գրել նախագծի համար RFC։

Մեծ կտորներ հոդվածից պատճենելիս — նշեք այս հոդվածի հղումը։
Այլ լեզվով թարգմանելով — նշեք այս հոդվածի հղումը։
Ես ինձնից չգիտեմ, թե ինչպես անեմ անգլերեն թարգմանությունը, և կ залишংশեմ հակակապեր։


Ընտանիք: habr.com

Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով 🔥 Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster