Debian + Postfix + Dovecot + Multidomain + SSL + IPv6 + OpenVPN + چند رابط + SpamAssassin-learn + Bind

این مقاله در مورد نحوه راه اندازی یک میل سرور مدرن است.
پست فیکس + کبوتر. SPF + DKIM + rDNS. با IPv6.
با رمزگذاری TSL. با پشتیبانی از چندین دامنه - بخشی با گواهی SSL واقعی.
با محافظت در برابر هرزنامه و رتبه آنتی اسپم بالا از سایر سرورهای ایمیل.
پشتیبانی از چندین رابط فیزیکی
با OpenVPN که اتصال به آن از طریق IPv4 است و IPv6 را ارائه می دهد.

اگر نمی خواهید همه این فناوری ها را یاد بگیرید، اما می خواهید چنین سروری را راه اندازی کنید، این مقاله برای شما مناسب است.

مقاله هیچ تلاشی برای توضیح همه جزئیات نمی کند. توضیح به مواردی است که به عنوان استاندارد پیکربندی نشده یا از دیدگاه مصرف کننده مهم است.

انگیزه راه اندازی یک سرور پست الکترونیکی رویای دیرینه من بوده است. این ممکن است احمقانه به نظر برسد، اما IMHO، بسیار بهتر از رویای یک ماشین جدید از برند مورد علاقه شما است.

دو انگیزه برای راه اندازی IPv6 وجود دارد. یک متخصص فناوری اطلاعات برای بقای خود نیاز به یادگیری مداوم فناوری های جدید دارد. من می خواهم سهم کوچک خود را در مبارزه با سانسور داشته باشم.

انگیزه راه اندازی OpenVPN فقط این است که IPv6 روی ماشین محلی کار کند.
انگیزه راه اندازی چندین رابط فیزیکی این است که در سرورم یک رابط "آهسته اما نامحدود" و دیگری "سریع اما با تعرفه" دارم.

انگیزه تنظیم تنظیمات Bind این است که ISP من یک سرور DNS ناپایدار ارائه می دهد و گوگل نیز گاهی اوقات از کار می افتد. من یک سرور DNS پایدار برای استفاده شخصی می خواهم.

انگیزه نوشتن مقاله - من 10 ماه پیش یک پیش نویس نوشتم و قبلاً دو بار به آن نگاه کرده ام. حتی اگر نویسنده به طور مرتب به آن نیاز داشته باشد، احتمال زیادی وجود دارد که دیگران نیز به آن نیاز داشته باشند.

هیچ راه حل جهانی برای سرور پست الکترونیکی وجود ندارد. اما من سعی خواهم کرد چیزی مانند "این کار را انجام دهید و سپس، وقتی همه چیز همانطور که باید کار کرد، چیزهای اضافی را دور بریزید" بنویسم.

شرکت tech.ru یک سرور Colocation دارد. امکان مقایسه با OVH، Hetzner، AWS وجود دارد. برای حل این مشکل، همکاری با tech.ru بسیار موثرتر خواهد بود.

دبیان 9 روی سرور نصب شده است.

سرور دارای 2 رابط «eno1» و «eno2» است. اولی نامحدود است و دومی به ترتیب سریع است.

3 آدرس IP ثابت XX.XX.XX.X0 و XX.XX.XX.X1 و XX.XX.XX.X2 در رابط «eno1» و XX.XX.XX.X5 در رابط «eno2» وجود دارد. .

موجود XXXX:XXXX:XXXX:XXXX::/64 مجموعه‌ای از آدرس‌های IPv6 که به رابط «eno1» اختصاص داده شده‌اند و از آن به درخواست من XXXX:XXXX:XXXX:XXXX:1:2::/96 به «eno2» اختصاص داده شده است.

3 دامنه «domain1.com»، «domain2.com»، «domain3.com» وجود دارد. یک گواهی SSL برای «domain1.com» و «domain3.com» وجود دارد.

من یک حساب Google دارم که می خواهم صندوق پستی خود را به آن پیوند دهم[ایمیل محافظت شده]` (دریافت نامه و ارسال نامه به طور مستقیم از رابط gmail).
باید یک صندوق پستی وجود داشته باشد[ایمیل محافظت شده]`، یک کپی از ایمیلی که می خواهم از آن در جیمیل خود ببینم. و نادر است که بتوان چیزی از طرف ` ارسال کرد[ایمیل محافظت شده]از طریق رابط وب.

باید یک صندوق پستی وجود داشته باشد[ایمیل محافظت شده]`، که ایوانف از آیفون خود استفاده خواهد کرد.

ایمیل های ارسالی باید با تمام الزامات ضد اسپم مدرن مطابقت داشته باشند.
باید بالاترین سطح رمزگذاری در شبکه های عمومی ارائه شود.
باید پشتیبانی IPv6 برای ارسال و دریافت نامه وجود داشته باشد.
باید SpamAssassin وجود داشته باشد که هرگز ایمیل ها را حذف نکند. و یا پرش می شود یا رد می شود یا به پوشه "هرزنامه" IMAP ارسال می شود.
یادگیری خودکار SpamAssassin باید پیکربندی شود: اگر نامه‌ای را به پوشه Spam منتقل کنم، از این موضوع یاد می‌گیرد. اگر نامه ای را از پوشه Spam منتقل کنم، از این موضوع یاد می گیرد. نتایج آموزش SpamAssassin باید بر روی پایان نامه در پوشه Spam تأثیر بگذارد.
اسکریپت های PHP باید بتوانند از طرف هر دامنه ای در یک سرور معین نامه ارسال کنند.
باید یک سرویس openvpn وجود داشته باشد، با قابلیت استفاده از IPv6 در کلاینت هایی که IPv6 ندارد.

ابتدا باید رابط ها و مسیریابی، از جمله IPv6 را پیکربندی کنید.
سپس باید OpenVPN را پیکربندی کنید، که از طریق IPv4 متصل می شود و یک آدرس 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 را مشخص کنید).
dns-nameservers - 127.0.0.1 نشان داده شده است (زیرا bind به صورت محلی نصب شده است) و 213.248.1.6 (این از tech.ru است).

"table eno1t" و "table eno2t" - معنای این قوانین مسیر این است که ترافیکی که از طریق 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

با این دستور مسیر را از کلاینت های 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 به درستی و فقط برای این کار کند. بیشتر در این مورد بعدا.

در مورد دروازه - این روش کار می کند و خوب است. اما راه صحیح این است که در اینجا 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 برای مشتریان 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:XXX:XXXX:XXXX:1:3:YYYY:YYYY آدرس هایی هستند که باید به مشتریان OpenVPN اختصاص داده شوند یا به عنوان آدرس های سرویس OpenVPN استفاده شوند.

برای پیکربندی شبکه، باید امکان راه اندازی مجدد سرور وجود داشته باشد.
تغییرات IPv4 هنگام اجرا دریافت می شوند (حتما آن را در صفحه قرار دهید - در غیر این صورت این دستور به سادگی شبکه را در سرور خراب می کند):

/etc/init.d/networking restart

به انتهای فایل “/etc/iproute2/rt_tables” اضافه کنید:

100 eno1t
101 eno2t

بدون این، نمی توانید از جداول سفارشی در فایل "/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

هر کسی که سعی کند IPv6 (به عنوان مثال nginx) را بلافاصله پس از بالا آمدن رابط متصل کند، یک خطا دریافت خواهد کرد. که این آدرس در دسترس نیست.

برای جلوگیری از چنین وضعیتی، چنین تنظیمی ایجاد می شود.

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

بدون این تنظیمات IPv6، ترافیک از کلاینت OpenVPN به دنیا نمی رود.

تنظیمات دیگر یا مرتبط نیستند یا یادم نیست برای چه هستند.
اما در هر صورت، آن را "همانطور که هست" می گذارم.

برای اینکه تغییرات این فایل بدون راه اندازی مجدد سرور دریافت شود، باید دستور زیر را اجرا کنید:

sysctl -p

جزئیات بیشتر در مورد قوانین "جدول": habr.com/post/108690

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

OpenVPN IPv4 بدون iptables کار نمی کند.

iptable های من برای 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

این یک محدودیت است به طوری که فقط من می توانم از OpenVPN از IP استاتیک خود استفاده کنم.

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

برای ارسال بسته های 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

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

یک گواهی سرور ایجاد کنید:

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

ایجاد اولین مشتری 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 بیشتر بیاموزید.

============= پسوند ==============

نصب پکیج اصلی:

apt-get install postfix

هنگام نصب، "سایت اینترنتی" را انتخاب کنید.

"/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 را توضیح دهم (بدون پاسخ به سؤالات "چگونه کار می کند؟" و "چرا کار می کند؟").

اساس رمزگذاری مدرن ایجاد یک جفت کلید (دو رشته بسیار طولانی از کاراکترها) است.

یک کلید خصوصی است و کلید دیگر عمومی است. ما کلید خصوصی را با دقت بسیار مخفی نگه می داریم. ما کلید عمومی را بین همه توزیع می کنیم.

با استفاده از کلید عمومی، می توانید رشته ای از متن را رمزگذاری کنید تا فقط صاحب کلید خصوصی بتواند آن را رمزگشایی کند.
خوب، این اساس کل فناوری است.

مرحله شماره 1 - سایت های https.
هنگام دسترسی به یک سایت، مرورگر از وب سرور متوجه می شود که سایت https است و بنابراین یک کلید عمومی را درخواست می کند.
وب سرور کلید عمومی را می دهد. مرورگر از کلید عمومی برای رمزگذاری درخواست http و ارسال آن استفاده می کند.
محتوای درخواست http را فقط کسانی می توانند بخوانند که کلید خصوصی را دارند، یعنی فقط سروری که درخواست برای آن ارسال شده است.
درخواست Http حداقل حاوی یک URI است. بنابراین، اگر کشوری سعی می کند دسترسی را نه به کل سایت، بلکه به یک صفحه خاص محدود کند، انجام این کار برای سایت های https غیرممکن است.

مرحله شماره 2 - پاسخ رمزگذاری شده
وب سرور پاسخی را ارائه می دهد که به راحتی در جاده قابل خواندن است.
راه حل بسیار ساده است - مرورگر به صورت محلی همان جفت کلید خصوصی و عمومی را برای هر سایت https ایجاد می کند.
و همراه با درخواست کلید عمومی سایت، کلید عمومی محلی خود را ارسال می کند.
وب سرور آن را به خاطر می آورد و هنگام ارسال http-response، آن را با کلید عمومی یک کلاینت خاص رمزگذاری می کند.
اکنون http-response فقط توسط مالک کلید خصوصی مرورگر مشتری (یعنی خود مشتری) قابل رمزگشایی است.

مرحله شماره 3 - ایجاد یک اتصال امن از طریق یک کانال عمومی.
یک آسیب‌پذیری در مثال شماره 2 وجود دارد - هیچ چیز خیرخواهان را از رهگیری یک درخواست http و ویرایش اطلاعات مربوط به کلید عمومی باز نمی‌دارد.
بنابراین، تا زمانی که کانال ارتباطی تغییر نکند، واسطه تمام محتوای پیام های ارسالی و دریافتی را به وضوح مشاهده می کند.
مقابله با این بسیار ساده است - فقط کلید عمومی مرورگر را به عنوان یک پیام رمزگذاری شده با کلید عمومی وب سرور ارسال کنید.
سپس وب سرور ابتدا پاسخی مانند "کلید عمومی شما اینگونه است" ارسال می کند و این پیام را با همان کلید عمومی رمزگذاری می کند.
مرورگر به پاسخ نگاه می کند - اگر پیام "کلید عمومی شما اینگونه است" دریافت شد - این یک تضمین 100٪ برای ایمن بودن این کانال ارتباطی است.
چقدر امن است؟
ایجاد چنین کانال ارتباطی امنی با سرعت پینگ*2 اتفاق می افتد. به عنوان مثال 20 میلی ثانیه.
مهاجم باید کلید خصوصی یکی از طرفین را از قبل داشته باشد. یا یک کلید خصوصی را در چند میلی ثانیه پیدا کنید.
هک کردن یک کلید خصوصی مدرن چندین دهه در یک ابر رایانه به طول خواهد انجامید.

مرحله 4 - پایگاه داده عمومی کلیدهای عمومی.
بدیهی است که در کل این داستان فرصتی وجود دارد که یک مهاجم در کانال ارتباطی بین مشتری و سرور بنشیند.
مشتری می تواند وانمود کند که سرور است و سرور می تواند وانمود کند که مشتری است. و یک جفت کلید را در هر دو جهت شبیه سازی کنید.
سپس مهاجم تمام ترافیک را می بیند و می تواند ترافیک را "ویرایش" کند.
به عنوان مثال، آدرس محل ارسال پول را تغییر دهید یا رمز عبور را از بانکداری آنلاین کپی کنید یا محتوای «مشکله» را مسدود کنید.
برای مبارزه با چنین مهاجمانی، آنها یک پایگاه داده عمومی با کلیدهای عمومی برای هر سایت https ارائه کردند.
هر مرورگر از وجود حدود 200 پایگاه داده "می داند". این از قبل در هر مرورگر نصب شده است.
"دانش" توسط یک کلید عمومی از هر گواهی پشتیبانی می شود. یعنی اتصال به هر مرجع صدور گواهینامه خاص قابل جعل نیست.

اکنون درک ساده ای از نحوه استفاده از SSL برای https وجود دارد.
اگر از مغز خود استفاده کنید، مشخص می شود که چگونه سرویس های ویژه می توانند چیزی را در این ساختار هک کنند. اما این به قیمت تلاش های هیولایی برای آنها تمام خواهد شد.
و سازمان‌های کوچک‌تر از NSA یا CIA - هک کردن سطح حفاظت موجود، حتی برای افراد VIP تقریباً غیرممکن است.

من همچنین در مورد اتصالات ssh اضافه خواهم کرد. هیچ کلید عمومی در آنجا وجود ندارد، پس چه کاری می توانید انجام دهید؟ مسئله از دو طریق حل می شود.
گزینه ssh-by-password:
در طول اولین اتصال، مشتری ssh باید هشدار دهد که ما یک کلید عمومی جدید از سرور ssh داریم.
و در حین اتصالات بعدی، اگر اخطار "کلید عمومی جدید از سرور ssh" ظاهر شود، به این معنی است که آنها سعی دارند شما را استراق سمع کنند.
یا از اولین اتصال خود شنود شده اید، اما اکنون بدون واسطه با سرور ارتباط برقرار می کنید.
در واقع، با توجه به اینکه واقعیت شنود به راحتی، سریع و بدون زحمت آشکار می شود، این حمله فقط در موارد خاص برای یک مشتری خاص استفاده می شود.

گزینه ssh-by-key:
ما یک درایو فلش می گیریم، کلید خصوصی سرور ssh را روی آن می نویسیم (اصطلاحات و تفاوت های ظریف زیادی برای این وجود دارد، اما من یک برنامه آموزشی می نویسم، نه دستورالعمل استفاده).
ما کلید عمومی را روی دستگاهی که کلاینت ssh در آن قرار خواهد گرفت، می گذاریم و همچنین آن را مخفی نگه می داریم.
درایو فلش را به سرور می آوریم، آن را وارد می کنیم، کلید خصوصی را کپی می کنیم و درایو فلش را می سوزانیم و خاکستر را به باد پراکنده می کنیم (یا حداقل آن را با صفر فرمت می کنیم).
این همه است - پس از چنین عملیاتی، هک چنین اتصال ssh غیرممکن خواهد بود. البته، در 10 سال آینده امکان مشاهده ترافیک در یک ابر رایانه وجود خواهد داشت - اما این یک داستان متفاوت است.

بابت آف تاپیک عذرخواهی میکنم

بنابراین اکنون که نظریه شناخته شده است. من در مورد جریان ایجاد یک گواهی SSL به شما خواهم گفت.

با استفاده از "openssl genrsa" یک کلید خصوصی و "blank" برای کلید عمومی ایجاد می کنیم.
ما "خالی ها" را به یک شرکت شخص ثالث می فرستیم، که تقریباً 9 دلار برای ساده ترین گواهی به آن می پردازیم.

پس از چند ساعت، ما کلید عمومی و مجموعه ای از چندین کلید عمومی را از این شرکت شخص ثالث دریافت می کنیم.

اینکه چرا یک شرکت شخص ثالث باید برای ثبت کلید عمومی من هزینه کند، یک سوال جداگانه است، ما در اینجا آن را بررسی نمی کنیم.

اکنون مشخص می شود که معنای کتیبه چیست:

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

پوشه "/etc/ssl" حاوی تمام فایل های مربوط به مسائل ssl است.
domain1.com - نام دامنه.
2018 سال خلق کلید است.
"کلید" - تعیین اینکه فایل یک کلید خصوصی است.

و معنی این فایل:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com - نام دامنه.
2018 سال خلق کلید است.
زنجیره ای - تعیین زنجیره ای از کلیدهای عمومی (اولین کلید عمومی ما و بقیه مواردی هستند که از شرکت صادر کننده کلید عمومی آمده است).
crt - تعیین اینکه گواهی آماده (کلید عمومی با توضیحات فنی) وجود دارد.

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

این تنظیمات در این مورد استفاده نمی شود، اما به عنوان نمونه نوشته شده است.

زیرا خطا در این پارامتر منجر به ارسال اسپم از سرور شما (بدون اراده شما) می شود.

سپس به همه ثابت کنید که گناهی ندارید.

recipient_delimiter = +

ممکن است بسیاری از مردم ندانند، اما این یک کاراکتر استاندارد برای رتبه بندی ایمیل ها است و توسط اکثر سرورهای ایمیل مدرن پشتیبانی می شود.

به عنوان مثال، اگر یک صندوق پستی دارید "[ایمیل محافظت شده]"سعی کنید ارسال کنید به"[ایمیل محافظت شده]"- نگاه کن از آن چه می آید.

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

در اینجا مشخص می کنیم که تمام نامه های دریافتی به dovecot می رود.
و قوانین دامنه، صندوق پستی، نام مستعار - در پایگاه داده نگاه کنید.

/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 پذیرفت.

من واقعاً درک نمی کنم که چرا اینجا تکرار شده است. ما قبلاً همه چیزهایی را که در "transport_virtual" مورد نیاز است مشخص کرده ایم.

اما سیستم postfix بسیار قدیمی است - احتمالاً این یک بازگشت از روزهای گذشته است.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

این می تواند برای هر سرور ایمیل به طور متفاوتی پیکربندی شود.

من 3 سرور ایمیل در اختیار دارم و این تنظیمات به دلیل نیازهای استفاده متفاوت بسیار متفاوت است.

شما باید آن را با دقت پیکربندی کنید - در غیر این صورت هرزنامه به شما سرازیر می شود، یا حتی بدتر از آن - هرزنامه از شما خارج می شود.

# SPF
policyd-spf_time_limit = 3600

راه اندازی برخی از افزونه های مربوط به بررسی 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

تنظیم این است که ما باید یک امضای DKIM با تمام ایمیل‌های ارسالی ارائه کنیم.

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

این یک جزئیات کلیدی در مسیریابی نامه هنگام ارسال نامه از اسکریپت های PHP است.

فایل “/etc/postfix/sdd_transport.pcre”:

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

در سمت چپ عبارات منظم وجود دارد. در سمت راست برچسبی وجود دارد که حرف را مشخص می کند.
Postfix مطابق با برچسب - چند خط پیکربندی دیگر را برای یک حرف خاص در نظر می گیرد.

نحوه دقیق پیکربندی مجدد postfix برای یک حرف خاص در "master.cf" نشان داده خواهد شد.

خطوط 4، 5، 6 خطوط اصلی هستند. از طرف کدام دامنه نامه را ارسال می کنیم، این برچسب را قرار می دهیم.
اما فیلد «از» همیشه در اسکریپت‌های PHP در کدهای قدیمی نشان داده نمی‌شود. سپس نام کاربری به کمک می آید.

مقاله در حال حاضر گسترده است - من نمی خواهم با تنظیم nginx+fpm حواس من پرت شود.

به طور خلاصه، برای هر سایت صاحب کاربر لینوکس خود را تعیین می کنیم. و بر این اساس fpm-pool شما.

Fpm-pool از هر نسخه‌ای از php استفاده می‌کند (وقتی در همان سرور می‌توانید از نسخه‌های مختلف php و حتی php.ini مختلف برای سایت‌های همسایه بدون مشکل استفاده کنید، عالی است).

بنابراین، یک کاربر خاص لینوکس "www-domain2" یک وب سایت domain2.com دارد. این سایت دارای کدی برای ارسال ایمیل بدون تعیین فیلد from است.

بنابراین، حتی در این صورت، نامه ها به درستی ارسال می شوند و هرگز به اسپم نمی رسند.

"/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 به سرور پست الکترونیکی متصل شوید.
برای این کار باید وارد شوید.

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" - و این برای سهولت خواندن گزارش‌ها است.

خرید گواهینامه من اینجا را توصیه می کنم.

راه اندازی پیوند postfix+dovecot در اینجا.

تنظیم SPF

============= كبوترخانه ==============

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

مجوز فقط رمزگذاری شده است.

فایل “/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 {
  }
}

این فایل پیکربندی اصلی Dovecot است.
در اینجا ما اتصالات ناامن را غیرفعال می کنیم.
و اتصالات امن را فعال کنید.

فایل "/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 مورد نیاز است.
و خود گواهی. و یک جزئیات مهم دستورالعمل "محلی" است. نشان می دهد که هنگام اتصال به کدام IPv4 محلی از کدام گواهی SSL استفاده شود.

به هر حال، IPv6 در اینجا پیکربندی نشده است، من بعداً این حذف را اصلاح خواهم کرد.
XX.XX.XX.X5 (دامنه2) - بدون گواهی. برای اتصال کلاینت ها باید 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
}

این یک افزونه آنتی اسپم است. برای آموزش spamassasin در زمان انتقال به/از پوشه "هرزنامه" مورد نیاز است.

فایل "/etc/dovecot/conf.d/20-pop3.conf"

protocol pop3 {
}

فقط چنین فایلی وجود دارد.

فایل “/etc/dovecot/conf.d/20-lmtp.conf”

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

راه اندازی 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
}

تنظیمات آموزش Spamassasin در زمان انتقال به/از پوشه 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

شما باید یک پایگاه داده "sa" در mysql با کاربر "sa" با رمز عبور "password" ایجاد کنید (با چیزی مناسب جایگزین کنید).

report_safe - به جای نامه، گزارشی از ایمیل هرزنامه ارسال می شود.
use_bayes تنظیمات یادگیری ماشینی spamassassin هستند.

تنظیمات باقیمانده spamassassin قبلاً در مقاله استفاده شد.

تنظیمات عمومی "Spamassassin".
درباره انتقال ایمیل‌های هرزنامه جدید به پوشه «هرزنامه» IMAP.
درباره ترکیب ساده Dovecot + SpamAssassin.
توصیه می کنم هنگام جابجایی حروف در پوشه های imap، تئوری یادگیری spamassasin را بخوانید (و استفاده از آن را توصیه نمی کنم).

============= توسل به جامعه ==============

من همچنین می خواهم ایده ای را در مورد چگونگی افزایش سطح امنیت نامه های ارسال شده در جامعه مطرح کنم. از آنجایی که من عمیقاً در موضوع پست الکترونیکی غوطه ور هستم.

به طوری که کاربر می تواند یک جفت کلید روی کلاینت خود ایجاد کند (چشم انداز، تاندربرد، مرورگر-پلاگین، ...). عمومی و خصوصی. عمومی - ارسال به DNS. خصوصی - صرفه جویی در مشتری. سرورهای ایمیل می توانند از یک کلید عمومی برای ارسال به یک گیرنده خاص استفاده کنند.

و برای محافظت در برابر هرزنامه با چنین حروفی (بله، سرور ایمیل قادر به مشاهده محتوا نخواهد بود) - باید 3 قانون را معرفی کنید:

  1. امضای واقعی DKIM اجباری، SPF اجباری، rDNS اجباری.
  2. یک شبکه عصبی با موضوع آموزش آنتی اسپم + پایگاه داده برای آن در سمت مشتری.
  3. الگوریتم رمزگذاری باید به گونه ای باشد که طرف فرستنده باید 100 برابر بیشتر از طرف گیرنده قدرت CPU را صرف رمزگذاری کند.

علاوه بر نامه های عمومی، یک پیشنهاد نامه استاندارد "برای شروع مکاتبات ایمن" ایجاد کنید. یکی از کاربران (صندوق پستی) نامه ای را با پیوست به صندوق پست دیگری ارسال می کند. نامه حاوی یک پیشنهاد متنی برای شروع یک کانال ارتباطی امن برای مکاتبات و کلید عمومی صاحب صندوق پستی (با یک کلید خصوصی در سمت مشتری) است.

حتی می توانید برای هر مکاتبات چند کلید بسازید. کاربر گیرنده می تواند این پیشنهاد را بپذیرد و کلید عمومی خود را ارسال کند (که به طور خاص برای این مکاتبات نیز ساخته شده است). در مرحله بعد، کاربر اول یک نامه کنترل سرویس (که با کلید عمومی کاربر دوم رمزگذاری شده است) ارسال می کند - پس از دریافت آن، کاربر دوم می تواند کانال ارتباطی تشکیل شده را قابل اعتماد در نظر بگیرد. در مرحله بعد، کاربر دوم یک نامه کنترل ارسال می کند - و سپس کاربر اول می تواند کانال تشکیل شده را امن در نظر بگیرد.

برای مبارزه با رهگیری کلیدها در جاده، پروتکل باید امکان انتقال حداقل یک کلید عمومی با استفاده از درایو فلش را فراهم کند.

و مهمترین چیز این است که همه چیز کار می کند (سوال این است که "چه کسی هزینه آن را پرداخت می کند؟"):
گواهی نامه های پستی را با قیمت 10 دلار به مدت 3 سال وارد کنید. که به فرستنده اجازه می دهد در dns نشان دهد که "کلیدهای عمومی من آنجا هستند." و به شما این فرصت را می دهند که یک اتصال امن را شروع کنید. در عین حال، پذیرش چنین ارتباطاتی رایگان است.
جیمیل بالاخره از کاربرانش درآمدزایی می کند. برای 10 دلار در هر 3 سال - حق ایجاد کانال های مکاتبات ایمن.

============= نتیجه گیری ==============

برای تست کل مقاله قرار بود یک سرور اختصاصی برای یک ماه اجاره کنم و یک دامنه با گواهی SSL بخرم.

اما شرایط زندگی ایجاد شد به طوری که این موضوع 2 ماه به طول انجامید.
و به این ترتیب، وقتی دوباره وقت آزاد داشتم، تصمیم گرفتم مقاله را همانطور که هست منتشر کنم، به جای اینکه ریسک کنم که انتشار یک سال دیگر به طول بینجامد.

اگر سؤالات زیادی مانند "اما این با جزئیات کافی توضیح داده نشده است" وجود دارد، احتمالاً می توان یک سرور اختصاصی با یک دامنه جدید و یک گواهی SSL جدید انتخاب کرد و آن را با جزئیات بیشتر و بیشتر توصیف کرد. مهمتر از همه، همه جزئیات مهم گم شده را شناسایی کنید.

همچنین می‌خواهم درباره ایده‌هایی درباره گواهی‌های پستی بازخورد دریافت کنم. اگر این ایده را دوست دارید، سعی می کنم قدرتی برای نوشتن پیش نویس برای rfc پیدا کنم.

هنگام کپی کردن قسمت های بزرگ یک مقاله، پیوندی به این مقاله ارائه دهید.
هنگام ترجمه به هر زبان دیگری، پیوندی به این مقاله ارائه دهید.
سعی می کنم خودم آن را به انگلیسی ترجمه کنم و ارجاعات متقابل را بگذارم.


منبع: www.habr.com

اضافه کردن نظر