Debian + Postfix + Dovecot + Multidomain + SSL + IPv6 + OpenVPN + Đa ​​giao diện + SpamAssassin-learn + Bind

Bài viết này nói về cách thiết lập một máy chủ thư hiện đại.
Postfix + Dovecot. SPF + DKIM + rDNS. Với IPv6.
Với mã hóa TSL. Với sự hỗ trợ cho nhiều tên miền - một phần là chứng chỉ SSL thực.
Với tính năng bảo vệ chống thư rác và xếp hạng chống thư rác cao từ các máy chủ thư khác.
Hỗ trợ nhiều giao diện vật lý.
Với OpenVPN, kết nối được thực hiện qua IPv4 và cung cấp IPv6.

Nếu bạn không muốn tìm hiểu tất cả những công nghệ này nhưng muốn thiết lập một máy chủ như vậy thì bài viết này là dành cho bạn.

Bài viết không cố gắng giải thích từng chi tiết. Lời giải thích liên quan đến những gì không được cấu hình theo tiêu chuẩn hoặc quan trọng theo quan điểm của người tiêu dùng.

Động lực thiết lập một mail server là ước mơ từ lâu của tôi. Điều này nghe có vẻ ngu ngốc, nhưng IMHO, điều đó tốt hơn nhiều so với việc mơ về một chiếc ô tô mới của thương hiệu yêu thích của bạn.

Có hai động lực để thiết lập IPv6. Một chuyên gia CNTT cần liên tục học hỏi các công nghệ mới để tồn tại. Tôi muốn đóng góp khiêm tốn của mình vào cuộc chiến chống kiểm duyệt.

Động lực thiết lập OpenVPN chỉ là để IPv6 hoạt động trên máy cục bộ.
Động lực để thiết lập một số giao diện vật lý là trên máy chủ của tôi, tôi có một giao diện “chậm nhưng không giới hạn” và một giao diện khác “nhanh nhưng có tính phí”.

Động lực thiết lập cài đặt Bind là do ISP của tôi cung cấp máy chủ DNS không ổn định và google đôi khi cũng bị lỗi. Tôi muốn có một máy chủ DNS ổn định để sử dụng cá nhân.

Động lực viết bài - Tôi viết bản nháp cách đây 10 tháng và đã xem nó hai lần. Ngay cả khi tác giả thường xuyên cần nó thì khả năng cao là những người khác cũng sẽ cần nó.

Không có giải pháp chung cho máy chủ thư. Nhưng tôi sẽ cố gắng viết những điều như “hãy làm điều này và sau đó, khi mọi thứ hoạt động bình thường, hãy loại bỏ những thứ thừa”.

Công ty tech.ru có một máy chủ Colocation. Có thể so sánh với OVH, Hetzner, AWS. Để giải quyết vấn đề này, việc hợp tác với tech.ru sẽ hiệu quả hơn rất nhiều.

Debian 9 được cài đặt trên máy chủ.

Máy chủ có 2 giao diện `eno1` và `eno2`. Cái đầu tiên là không giới hạn và cái thứ hai tương ứng là nhanh.

Có 3 địa chỉ IP tĩnh là XX.XX.XX.X0 và ​​XX.XX.XX.X1 và XX.XX.XX.X2 trên giao diện `eno1` và XX.XX.XX.X5 trên giao diện `eno2` .

Có sẵn XXXX:XXXX:XXXX:XXXX::/64 một nhóm địa chỉ IPv6 được gán cho giao diện `eno1` và từ đó XXXX:XXXX:XXXX:XXXX:1:2::/96 được gán cho `eno2` theo yêu cầu của tôi.

Có 3 tên miền `domain1.com`, `domain2.com`, `domain3.com`. Có chứng chỉ SSL cho `domain1.com` và `domain3.com`.

Tôi có một tài khoản Google mà tôi muốn liên kết hộp thư của mình với[email được bảo vệ]` (nhận thư và gửi thư trực tiếp từ giao diện gmail).
Phải có hộp thư`[email được bảo vệ]`, bản sao của email mà tôi muốn xem trong gmail của mình. Và thật hiếm khi có thể gửi thứ gì đó thay mặt cho `[email được bảo vệ]`thông qua giao diện web.

Phải có hộp thư`[email được bảo vệ]`, mà Ivanov sẽ sử dụng từ iPhone của mình.

Email đã gửi phải tuân thủ tất cả các yêu cầu chống thư rác hiện đại.
Phải có mức mã hóa cao nhất được cung cấp trong các mạng công cộng.
Cần có hỗ trợ IPv6 cho cả việc gửi và nhận thư.
Cần có một SpamAssassin sẽ không bao giờ xóa email. Và nó sẽ bị trả lại hoặc bỏ qua hoặc gửi đến thư mục “Thư rác” IMAP.
Tính năng tự động học của SpamAssassin phải được định cấu hình: nếu tôi di chuyển một lá thư vào thư mục Thư rác, nó sẽ học từ điều này; nếu tôi di chuyển một lá thư từ thư mục Thư rác, nó sẽ học được điều này. Kết quả đào tạo SpamAssassin sẽ ảnh hưởng đến việc lá thư có nằm trong thư mục Thư rác hay không.
Các tập lệnh PHP phải có khả năng gửi thư thay mặt cho bất kỳ tên miền nào trên một máy chủ nhất định.
Cần có dịch vụ openvpn, với khả năng sử dụng IPv6 trên máy khách không có IPv6.

Trước tiên, bạn cần cấu hình các giao diện và định tuyến, bao gồm cả IPv6.
Sau đó, bạn sẽ cần định cấu hình OpenVPN, dịch vụ này sẽ kết nối qua IPv4 và cung cấp cho khách hàng địa chỉ IPv6 thực tĩnh. Máy khách này sẽ có quyền truy cập vào tất cả các dịch vụ IPv6 trên máy chủ và truy cập vào mọi tài nguyên IPv6 trên Internet.
Sau đó, bạn sẽ cần định cấu hình Postfix để gửi thư + SPF + DKIM + rDNS và những việc nhỏ tương tự khác.
Sau đó, bạn sẽ cần định cấu hình Dovecot và định cấu hình Multidomain.
Sau đó, bạn sẽ cần định cấu hình SpamAssassin và định cấu hình đào tạo.
Cuối cùng, cài đặt Bind.

============== Đa giao diện ==============

Để định cấu hình giao diện, bạn cần viết phần này vào “/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

Các cài đặt này có thể được áp dụng trên bất kỳ máy chủ nào trong tech.ru (với một chút phối hợp với bộ phận hỗ trợ) và nó sẽ ngay lập tức hoạt động như bình thường.

Nếu bạn có kinh nghiệm thiết lập những thứ tương tự cho Hetzner, OVH, thì ở đó sẽ khác. Khó hơn.

eno1 là tên card mạng số 1 (chậm nhưng không giới hạn).
eno2 là tên của card mạng số 2 (nhanh nhưng có tính phí).
tun0 là tên của card mạng ảo từ OpenVPN.
XX.XX.XX.X0 - IPv4 #1 trên eno1.
XX.XX.XX.X1 - IPv4 #2 trên eno1.
XX.XX.XX.X2 - IPv4 #3 trên eno1.
XX.XX.XX.X5 - IPv4 #1 trên eno2.
XX.XX.XX.1 - Cổng IPv4.
XXXX:XXXX:XXXX:XXXX::/64 - IPv6 cho toàn bộ máy chủ.
XXXX:XXXX:XXXX:XXXX:1:2::/96 - IPv6 cho eno2, mọi thứ khác từ bên ngoài sẽ chuyển vào eno1.
XXXX:XXXX:XXXX:XXXX::1 — Cổng IPv6 (cần lưu ý rằng việc này có thể/nên được thực hiện khác đi. Chỉ định bộ chuyển đổi IPv6).
dns-nameservers - 127.0.0.1 được chỉ định (vì liên kết được cài đặt cục bộ) và 213.248.1.6 (đây là từ tech.ru).

“table eno1t” và “table eno2t” - ý nghĩa của các quy tắc định tuyến này là lưu lượng đi vào qua eno1 -> sẽ đi qua đó và lưu lượng đi vào qua eno2 -> sẽ đi qua đó. Và các kết nối do máy chủ khởi tạo cũng sẽ đi qua eno1.

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

Với lệnh này, chúng tôi chỉ định rằng mọi lưu lượng truy cập khó hiểu thuộc bất kỳ quy tắc nào được đánh dấu “bảng eno1t” -> sẽ được gửi đến giao diện eno1.

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

Với lệnh này, chúng tôi chỉ định rằng mọi lưu lượng truy cập do máy chủ khởi tạo phải được chuyển hướng đến giao diện eno1.

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

Với lệnh này, chúng tôi đặt ra các quy tắc để đánh dấu giao thông.

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

Khối này chỉ định IPv4 thứ hai cho giao diện eno1.

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

Với lệnh này, chúng tôi đặt tuyến từ máy khách OpenVPN sang IPv4 cục bộ ngoại trừ XX.XX.XX.X0.
Tôi vẫn không hiểu tại sao lệnh này lại đủ cho tất cả IPv4.

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

Đây là nơi chúng tôi đặt địa chỉ cho chính giao diện. Máy chủ sẽ sử dụng nó làm địa chỉ “gửi đi”. Sẽ không được sử dụng dưới bất kỳ hình thức nào nữa.

Tại sao ":1:1::" lại phức tạp như vậy? Để OpenVPN hoạt động chính xác và chỉ dành cho việc này. Thêm về điều này sau.

Về chủ đề cổng - đó là cách nó hoạt động và điều đó ổn. Nhưng cách chính xác là chỉ ra ở đây IPv6 của bộ chuyển mạch mà máy chủ được kết nối.

Tuy nhiên, vì lý do nào đó mà IPv6 ngừng hoạt động nếu tôi thực hiện việc này. Đây có lẽ là một loại vấn đề nào đó của tech.ru.

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

Đây là việc thêm địa chỉ IPv6 vào giao diện. Nếu bạn cần một trăm địa chỉ, điều đó có nghĩa là có một trăm dòng trong tệp này.

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

Tôi đã ghi lại địa chỉ và mạng con của tất cả các giao diện để làm rõ.
eno1 - phải là "/64" - bởi vì đây là toàn bộ nhóm địa chỉ của chúng tôi.
tun0 - mạng con phải lớn hơn eno1. Nếu không, sẽ không thể định cấu hình cổng IPv6 cho máy khách OpenVPN.
eno2 - mạng con phải lớn hơn tun0. Nếu không, máy khách OpenVPN sẽ không thể truy cập địa chỉ IPv6 cục bộ.
Để rõ ràng, tôi đã chọn bước mạng con là 16, nhưng nếu muốn, bạn thậm chí có thể thực hiện bước “1”.
Theo đó, 64+16 = 80 và 80+16 = 96.

Để rõ ràng hơn nữa:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY là các địa chỉ được chỉ định cho các trang web hoặc dịch vụ cụ thể trên giao diện eno1.
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY là các địa chỉ được chỉ định cho các trang web hoặc dịch vụ cụ thể trên giao diện eno2.
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY là những địa chỉ nên được chỉ định cho máy khách OpenVPN hoặc được sử dụng làm địa chỉ dịch vụ OpenVPN.

Để định cấu hình mạng, có thể khởi động lại máy chủ.
Các thay đổi của IPv4 được chọn khi được thực thi (hãy chắc chắn bọc nó trong màn hình - nếu không lệnh này sẽ làm sập mạng trên máy chủ):

/etc/init.d/networking restart

Thêm vào cuối file “/etc/iproute2/rt_tables”:

100 eno1t
101 eno2t

Nếu không có điều này, bạn không thể sử dụng các bảng tùy chỉnh trong tệp “/etc/network/interfaces”.
Các số phải là duy nhất và nhỏ hơn 65535.

Các thay đổi của IPv6 có thể được thay đổi dễ dàng mà không cần khởi động lại, nhưng để làm được điều này, bạn cần học ít nhất ba lệnh:

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

Cài đặt "/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

Đây là cài đặt "sysctl" của máy chủ của tôi. Hãy để tôi chỉ ra một điều quan trọng.

net.ipv4.ip_forward = 1

Không có điều này, OpenVPN sẽ không hoạt động.

net.ipv6.ip_nonlocal_bind = 1

Bất cứ ai cố gắng liên kết IPv6 (ví dụ nginx) ngay sau khi giao diện hoạt động sẽ gặp lỗi. Rằng địa chỉ này không có sẵn.

Để tránh tình huống như vậy, một cài đặt như vậy được thực hiện.

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

Nếu không có các cài đặt IPv6 này, lưu lượng truy cập từ máy khách OpenVPN sẽ không đi ra ngoài.

Các cài đặt khác không liên quan hoặc tôi không nhớ chúng dùng để làm gì.
Nhưng để đề phòng, tôi để nó “nguyên trạng”.

Để nhận các thay đổi đối với tệp này mà không cần khởi động lại máy chủ, bạn cần chạy lệnh:

sysctl -p

Thông tin chi tiết hơn về quy tắc “bảng”: habr.com/post/108690

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

OpenVPN IPv4 không hoạt động nếu không có iptables.

IPtables của tôi giống như thế này đối với 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 là địa chỉ IPv4 tĩnh của máy cục bộ.
10.8.0.0/24 - Mạng openvpn IPv4. Địa chỉ IPv4 cho máy khách openvpn.
Tính nhất quán của các quy tắc là quan trọng.

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

Đây là một hạn chế để chỉ tôi mới có thể sử dụng OpenVPN từ IP tĩnh của mình.

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

Để chuyển tiếp các gói IPv4 giữa các máy khách OpenVPN và Internet, bạn cần đăng ký một trong các lệnh này.

Đối với các trường hợp khác nhau, một trong các tùy chọn không phù hợp.
Cả hai lệnh đều phù hợp với trường hợp của tôi.
Sau khi đọc tài liệu, tôi chọn tùy chọn đầu tiên vì nó sử dụng ít CPU hơn.

Để tất cả các cài đặt iptables được chọn sau khi khởi động lại, bạn cần lưu chúng ở đâu đó.

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

Những cái tên như vậy không được chọn một cách tình cờ. Chúng được sử dụng bởi gói "iptables-persistent".

apt-get install iptables-persistent

Cài đặt gói OpenVPN chính:

apt-get install openvpn easy-rsa

Hãy thiết lập mẫu cho chứng chỉ (thay thế các giá trị của bạn):

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

Hãy chỉnh sửa cài đặt mẫu chứng chỉ:

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

Tạo chứng chỉ máy chủ:

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

Hãy chuẩn bị khả năng tạo file “client-name.opvn” cuối cùng:

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

Hãy chuẩn bị một tập lệnh sẽ hợp nhất tất cả các tệp thành một tệp opvn duy nhất.

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

Tạo ứng dụng khách OpenVPN đầu tiên:

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

Tệp “~/client-configs/files/client-name.ovpn” được gửi đến thiết bị của khách hàng.

Đối với máy khách iOS, bạn sẽ cần thực hiện thủ thuật sau:
Nội dung của thẻ "tls-auth" phải không có bình luận.
Và cũng đặt “key-direction 1” ngay trước thẻ “tls-auth”.

Hãy định cấu hình cấu hình máy chủ 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

Điều này là cần thiết để đặt địa chỉ tĩnh cho từng khách hàng (không cần thiết, nhưng tôi sử dụng nó):

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

Chi tiết khó và quan trọng nhất.

Thật không may, OpenVPN vẫn chưa biết cách định cấu hình độc lập cổng IPv6 cho máy khách.
Bạn phải “chuyển tiếp” thủ công thông tin này cho từng khách hàng.

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

Tập tin “/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

Tệp “/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

Cả hai tập lệnh đều sử dụng tệp “/etc/openvpn/variables”:

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

Tôi thấy khó nhớ tại sao nó lại được viết như thế này.

Bây giờ netmask = 112 trông có vẻ lạ (phải là 96 ngay tại đó).
Và tiền tố lạ quá, nó không khớp với mạng tun0.
Nhưng không sao, tôi sẽ để nguyên như vậy.

cipher DES-EDE3-CBC

Điều này không dành cho tất cả mọi người - tôi đã chọn phương pháp mã hóa kết nối này.

Tìm hiểu thêm về cách thiết lập OpenVPN IPv4.

Tìm hiểu thêm về cách thiết lập OpenVPN IPv6.

============== Hậu tố ==============

Cài đặt gói chính:

apt-get install postfix

Khi cài đặt, chọn “trang web internet”.

"/etc/postfix/main.cf" của tôi trông như thế này:

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

Hãy cùng xem chi tiết cấu hình này nhé.

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

Theo cư dân Khabrovsk, khối này chứa “thông tin sai lệch và luận điểm không chính xác”.Chỉ 8 năm sau khi bắt đầu sự nghiệp, tôi mới bắt đầu hiểu SSL hoạt động như thế nào.

Do đó, tôi sẽ thoải mái mô tả cách sử dụng SSL (không trả lời các câu hỏi “Nó hoạt động như thế nào?” và “Tại sao nó hoạt động?”).

Cơ sở của mã hóa hiện đại là tạo ra một cặp khóa (hai chuỗi ký tự rất dài).

Một “khóa” là riêng tư, khóa còn lại là “công khai”. Chúng tôi giữ bí mật khóa riêng rất cẩn thận. Chúng tôi phân phối khóa công khai cho mọi người.

Sử dụng khóa chung, bạn có thể mã hóa một chuỗi văn bản để chỉ chủ sở hữu khóa riêng mới có thể giải mã được.
Vâng, đó là toàn bộ nền tảng của công nghệ.

Bước #1 - Trang web https.
Khi truy cập một trang web, trình duyệt sẽ biết từ máy chủ web rằng trang web đó là https và do đó yêu cầu khóa chung.
Máy chủ web cung cấp khóa chung. Trình duyệt sử dụng khóa chung để mã hóa yêu cầu http và gửi nó.
Nội dung của yêu cầu http chỉ có thể được đọc bởi những người có khóa riêng, nghĩa là chỉ máy chủ mà yêu cầu được thực hiện.
Yêu cầu http chứa ít nhất một URI. Do đó, nếu một quốc gia đang cố gắng hạn chế quyền truy cập không phải vào toàn bộ trang web mà vào một trang cụ thể, thì điều này là không thể thực hiện được đối với các trang https.

Bước # 2 - phản hồi được mã hóa.
Máy chủ web cung cấp câu trả lời có thể dễ dàng đọc được trên đường.
Giải pháp cực kỳ đơn giản - trình duyệt tạo cục bộ cùng một cặp khóa riêng tư-công khai cho mỗi trang https.
Và cùng với yêu cầu về khóa công khai của trang web, nó sẽ gửi khóa công khai cục bộ của nó.
Máy chủ web ghi nhớ nó và khi gửi phản hồi http, sẽ mã hóa nó bằng khóa chung của một máy khách cụ thể.
Bây giờ, phản hồi http chỉ có thể được giải mã bởi chủ sở hữu khóa riêng của trình duyệt của khách hàng (nghĩa là chính khách hàng đó).

Bước số 3 - thiết lập kết nối an toàn qua kênh công cộng.
Có một lỗ hổng trong ví dụ số 2 - không có gì ngăn cản những người có thiện chí chặn yêu cầu http và chỉnh sửa thông tin về khóa chung.
Như vậy, người trung gian sẽ thấy rõ toàn bộ nội dung tin nhắn đã gửi và nhận cho đến khi kênh liên lạc thay đổi.
Xử lý vấn đề này cực kỳ đơn giản - chỉ cần gửi khóa chung của trình duyệt dưới dạng tin nhắn được mã hóa bằng khóa chung của máy chủ web.
Sau đó, máy chủ web trước tiên sẽ gửi phản hồi như “khóa chung của bạn giống như thế này” và mã hóa thông báo này bằng cùng một khóa chung.
Trình duyệt xem phản hồi - nếu nhận được thông báo "khóa công khai của bạn giống như thế này" - thì đây là sự đảm bảo 100% rằng kênh liên lạc này được an toàn.
Nó an toàn đến mức nào?
Việc tạo ra một kênh liên lạc an toàn như vậy diễn ra ở tốc độ ping*2. Ví dụ 20ms.
Kẻ tấn công phải có trước khóa riêng của một trong các bên. Hoặc tìm khóa riêng trong vài mili giây.
Việc hack một khóa riêng hiện đại sẽ mất hàng thập kỷ trên siêu máy tính.

Bước #4 - cơ sở dữ liệu công khai về khóa công khai.
Rõ ràng, trong toàn bộ câu chuyện này, kẻ tấn công có cơ hội chiếm được kênh liên lạc giữa máy khách và máy chủ.
Máy khách có thể giả vờ là máy chủ và máy chủ có thể giả vờ là máy khách. Và mô phỏng một cặp chìa khóa theo cả hai hướng.
Sau đó, kẻ tấn công sẽ nhìn thấy tất cả lưu lượng truy cập và có thể “chỉnh sửa” lưu lượng truy cập.
Ví dụ: thay đổi địa chỉ gửi tiền hoặc sao chép mật khẩu từ ngân hàng trực tuyến hoặc chặn nội dung “phản cảm”.
Để chống lại những kẻ tấn công như vậy, họ đã nghĩ ra một cơ sở dữ liệu công khai có khóa chung cho mỗi trang https.
Mỗi trình duyệt “biết” về sự tồn tại của khoảng 200 cơ sở dữ liệu như vậy. Điều này được cài đặt sẵn trong mọi trình duyệt.
“Kiến thức” được hỗ trợ bởi khóa công khai từ mỗi chứng chỉ. Nghĩa là, kết nối với từng cơ quan chứng nhận cụ thể không thể bị làm giả.

Bây giờ chúng ta đã hiểu đơn giản về cách sử dụng SSL cho https.
Nếu bạn sử dụng bộ não của mình, bạn sẽ thấy rõ làm thế nào các dịch vụ đặc biệt có thể hack thứ gì đó trong cấu trúc này. Nhưng nó sẽ khiến họ phải trả giá bằng những nỗ lực to lớn.
Và các tổ chức nhỏ hơn NSA hay CIA - gần như không thể hack được mức độ bảo vệ hiện có, ngay cả đối với VIP.

Tôi cũng sẽ bổ sung thêm về kết nối ssh. Không có khóa công khai ở đó, vậy bạn có thể làm gì? Vấn đề được giải quyết theo hai cách.
Tùy chọn ssh-by-password:
Trong lần kết nối đầu tiên, máy khách ssh sẽ cảnh báo rằng chúng tôi có khóa chung mới từ máy chủ ssh.
Và trong các kết nối tiếp theo, nếu cảnh báo “khóa công khai mới từ máy chủ ssh” xuất hiện, điều đó có nghĩa là họ đang cố nghe lén bạn.
Hoặc bạn đã bị nghe lén trong lần kết nối đầu tiên nhưng bây giờ bạn liên lạc với máy chủ mà không qua trung gian.
Trên thực tế, do việc nghe lén có thể bị phát hiện một cách dễ dàng, nhanh chóng và dễ dàng nên cuộc tấn công này chỉ được sử dụng trong những trường hợp đặc biệt đối với một khách hàng cụ thể.

Tùy chọn ssh-by-key:
Chúng tôi lấy một ổ đĩa flash, viết khóa riêng cho máy chủ ssh trên đó (có các thuật ngữ và nhiều sắc thái quan trọng cho việc này, nhưng tôi đang viết một chương trình giáo dục chứ không phải hướng dẫn sử dụng).
Chúng tôi để lại khóa chung trên máy nơi chứa ứng dụng khách ssh và chúng tôi cũng giữ bí mật nó.
Chúng tôi mang ổ đĩa flash đến máy chủ, lắp nó vào, sao chép khóa riêng và ghi ổ đĩa flash và rải tro theo gió (hoặc ít nhất là định dạng nó bằng số không).
Chỉ vậy thôi - sau một thao tác như vậy, sẽ không thể hack được kết nối ssh như vậy. Tất nhiên, trong 10 năm nữa, người ta sẽ có thể xem lưu lượng truy cập trên siêu máy tính - nhưng đó lại là một câu chuyện khác.

Tôi xin lỗi vì sự bất thường.

Vì vậy, bây giờ lý thuyết đã được biết đến. Tôi sẽ cho bạn biết về quy trình tạo chứng chỉ SSL.

Sử dụng “openssl genrsa”, chúng tôi tạo khóa riêng và “khoảng trống” cho khóa chung.
Chúng tôi gửi “khoảng trống” cho một công ty bên thứ ba và chúng tôi phải trả khoảng 9 USD cho chứng chỉ đơn giản nhất.

Sau vài giờ, chúng tôi nhận được khóa “công khai” và một bộ khóa công khai từ công ty bên thứ ba này.

Tại sao một công ty bên thứ ba phải trả tiền cho việc đăng ký khóa công khai của tôi là một câu hỏi riêng, chúng tôi sẽ không xem xét vấn đề này ở đây.

Bây giờ đã rõ ý nghĩa của dòng chữ là gì:

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

Thư mục “/etc/ssl” chứa tất cả các tệp liên quan đến vấn đề ssl.
domain1.com — tên miền.
Năm 2018 là năm của sự sáng tạo chìa khóa.
“khóa” - chỉ định rằng tệp là khóa riêng.

Và ý nghĩa của tập tin này:

smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com — tên miền.
Năm 2018 là năm của sự sáng tạo chìa khóa.
bị xâu chuỗi - chỉ định rằng có một chuỗi khóa chung (đầu tiên là khóa chung của chúng tôi và phần còn lại là khóa đến từ công ty phát hành khóa chung).
crt - chỉ định rằng có chứng chỉ được tạo sẵn (khóa chung có giải thích kỹ thuật).

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

Cài đặt này không được sử dụng trong trường hợp này nhưng được viết dưới dạng ví dụ.

Bởi nếu sai sót ở thông số này sẽ dẫn tới việc spam được gửi từ máy chủ của bạn (không theo ý muốn của bạn).

Sau đó hãy chứng minh cho mọi người thấy bạn không có tội.

recipient_delimiter = +

Có thể nhiều người không biết nhưng đây là ký tự tiêu chuẩn để xếp hạng email và được hầu hết các máy chủ thư hiện đại hỗ trợ.

Ví dụ: nếu bạn có hộp thư "[email được bảo vệ]"thử gửi tới"[email được bảo vệ]"- hãy nhìn xem chuyện gì xảy ra.

inet_protocols = ipv4

Điều này có thể gây nhầm lẫn.

Nhưng nó không chỉ như vậy. Mỗi miền mới theo mặc định chỉ có IPv4, sau đó tôi bật IPv6 riêng cho từng miền.

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

Ở đây chúng tôi chỉ định rằng tất cả thư đến sẽ được chuyển đến dovecot.
Và các quy tắc về tên miền, hộp thư, bí danh - hãy tìm trong cơ sở dữ liệu.

/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

Bây giờ postfix biết rằng thư chỉ có thể được chấp nhận để gửi tiếp sau khi được ủy quyền với dovecot.

Tôi thực sự không hiểu tại sao điều này lại được sao chép ở đây. Chúng tôi đã chỉ định mọi thứ cần thiết trong “virtual_transport”.

Nhưng hệ thống postfix đã rất cũ - có lẽ đó là sự trở lại của thời xa xưa.

smtpd_recipient_restrictions =
        ...

smtpd_helo_restrictions =
        ...

smtpd_client_restrictions =
        ...

Điều này có thể được cấu hình khác nhau cho mỗi máy chủ thư.

Tôi có 3 máy chủ thư tùy ý sử dụng và các cài đặt này rất khác nhau do các yêu cầu sử dụng khác nhau.

Bạn cần phải định cấu hình nó một cách cẩn thận - nếu không thư rác sẽ tràn vào bạn, hoặc thậm chí tệ hơn - thư rác sẽ tràn ra từ bạn.

# SPF
policyd-spf_time_limit = 3600

Thiết lập một số plugin liên quan đến kiểm tra SPF của thư gửi đến.

# 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

Cài đặt là chúng tôi phải cung cấp chữ ký DKIM cho tất cả các email gửi đi.

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

Đây là chi tiết quan trọng trong việc định tuyến thư khi gửi thư từ các tập lệnh PHP.

Tập tin “/etc/postfix/sdd_transport.pcre”:

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

Bên trái là các biểu thức chính quy. Bên phải là nhãn đánh dấu chữ cái.
Postfix theo nhãn - sẽ tính đến một số dòng cấu hình nữa cho một chữ cái cụ thể.

Cách cấu hình lại chính xác hậu tố cho một chữ cái cụ thể sẽ được chỉ ra trong “master.cf”.

Các dòng 4, 5, 6 là những dòng chính. Chúng tôi đặt nhãn này thay mặt cho miền mà chúng tôi đang gửi thư.
Nhưng trường “từ” không phải lúc nào cũng được chỉ định trong các tập lệnh PHP ở mã cũ. Sau đó, tên người dùng sẽ được giải cứu.

Bài viết đã mở rộng - Tôi không muốn bị phân tâm khi thiết lập nginx+fpm.

Tóm lại, đối với mỗi trang web, chúng tôi đặt chủ sở hữu người dùng linux của riêng nó. Và theo đó, fpm-pool của bạn.

Fpm-pool sử dụng bất kỳ phiên bản php nào (thật tuyệt vời khi trên cùng một máy chủ, bạn có thể sử dụng các phiên bản php khác nhau và thậm chí cả php.ini khác nhau cho các trang web lân cận mà không gặp vấn đề gì).

Vì vậy, một người dùng linux cụ thể “www-domain2” có trang web domain2.com. Trang web này có mã để gửi email mà không chỉ định trường từ.

Vì vậy, ngay cả trong trường hợp này, các bức thư sẽ được gửi chính xác và sẽ không bao giờ bị gửi vào thư rác.

"/etc/postfix/master.cf" của tôi trông như thế này:

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

Tệp không được cung cấp đầy đủ - nó đã rất lớn.
Tôi chỉ lưu ý những gì đã được thay đổi.

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}

Đây là những cài đặt liên quan đến spamassasin, chúng ta sẽ nói thêm về điều đó sau.

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

Chúng tôi cho phép bạn kết nối với máy chủ thư qua cổng 587.
Để làm điều này, bạn phải đăng nhập.

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

Bật kiểm tra SPF.

apt-get install postfix-policyd-spf-python

Hãy cài đặt gói kiểm tra SPF ở trên.

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

Và đây là điều thú vị nhất. Đây là khả năng gửi thư cho một miền cụ thể từ một địa chỉ IPv4/IPv6 cụ thể.

Điều này được thực hiện vì lợi ích của rDNS. rDNS là quá trình nhận chuỗi theo địa chỉ IP.
Và đối với thư, tính năng này được sử dụng để xác nhận rằng helo khớp chính xác với rDNS của địa chỉ mà email được gửi.

Nếu helo không khớp với miền email thay mặt cho người gửi thư, điểm thư rác sẽ được thưởng.

Helo không khớp với rDNS - rất nhiều điểm spam được thưởng.
Theo đó, mỗi tên miền phải có địa chỉ IP riêng.
Đối với OVH - trong bảng điều khiển có thể chỉ định rDNS.
Đối với tech.ru - vấn đề được giải quyết thông qua hỗ trợ.
Đối với AWS, vấn đề được giải quyết thông qua hỗ trợ.
“inet_protocols” và “smtp_bind_address6” - chúng tôi kích hoạt hỗ trợ IPv6.
Đối với IPv6 bạn cũng cần phải đăng ký rDNS.
“syslog_name” - và điều này là để dễ đọc nhật ký.

Mua chứng chỉ Tôi khuyên bạn nên ở đây.

Đang thiết lập liên kết postfix+dovecot tại đây.

Cài đặt SPF.

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

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

Thiết lập mysql, tự cài đặt các gói.

Tệp "/etc/dovecot/conf.d/10-auth.conf"

disable_plaintext_auth = yes
auth_mechanisms = plain login

Ủy quyền chỉ được mã hóa.

Tập tin “/etc/dovecot/conf.d/10-mail.conf”

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

Ở đây chúng tôi chỉ ra vị trí lưu trữ cho các chữ cái.

Tôi muốn chúng được lưu trữ trong các tập tin và được nhóm theo tên miền.

Tệp "/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 {
  }
}

Đây là tập tin cấu hình dovecot chính.
Ở đây chúng tôi vô hiệu hóa các kết nối không an toàn.
Và kích hoạt kết nối an toàn.

Tệp "/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
}

Đang thiết lập ssl. Chúng tôi chỉ ra rằng ssl là bắt buộc.
Và chính giấy chứng nhận. Và một chi tiết quan trọng là chỉ thị “địa phương”. Cho biết chứng chỉ SSL nào sẽ được sử dụng khi kết nối với IPv4 cục bộ nào.

Nhân tiện, IPv6 chưa được định cấu hình ở đây, tôi sẽ sửa thiếu sót này sau.
XX.XX.XX.X5 (domain2) - không có chứng chỉ. Để kết nối khách hàng, bạn cần chỉ định domain1.com.
XX.XX.XX.X2 (domain3) - có chứng chỉ, bạn có thể chỉ định domain1.com hoặc domain3.com để kết nối máy khách.

Tệp "/etc/dovecot/conf.d/15-lda.conf"

protocol lda {
  mail_plugins = $mail_plugins sieve
}

Điều này sẽ cần thiết cho spamassassin trong tương lai.

Tệp "/etc/dovecot/conf.d/20-imap.conf"

protocol imap {
  mail_plugins = $mail_plugins antispam
}

Đây là một plugin chống thư rác. Cần thiết cho việc đào tạo spamassasin tại thời điểm chuyển đến/từ thư mục “Thư rác”.

Tệp "/etc/dovecot/conf.d/20-pop3.conf"

protocol pop3 {
}

Chỉ có một tập tin như vậy.

Tập tin “/etc/dovecot/conf.d/20-lmtp.conf”

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

Đang thiết lập lmtp.

Tệp "/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
}

Cài đặt đào tạo Spamassasin tại thời điểm chuyển đến/từ thư mục Thư rác.

Tệp "/etc/dovecot/conf.d/90-sieve.conf"

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

Một tập tin chỉ định những việc cần làm với các bức thư đến.

Tệp "/var/lib/dovecot/sieve/default.sieve"

require ["fileinto", "mailbox"];

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

Bạn cần biên dịch file: “sievec default.sieve”.

Tệp "/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
}

Chỉ định tệp sql để ủy quyền.
Và bản thân tập tin được sử dụng như một phương thức ủy quyền.

Tệp "/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';

Điều này tương ứng với các cài đặt tương tự cho postfix.

Tệp "/etc/dovecot/dovecot.conf"

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

Tập tin cấu hình chính.
Điều quan trọng là chúng tôi chỉ ra ở đây - thêm các giao thức.

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

apt-get install spamassassin spamc

Hãy cài đặt các gói.

adduser spamd --disabled-login

Hãy thêm người dùng thay mặt họ.

systemctl enable spamassassin.service

Chúng tôi kích hoạt dịch vụ spamassassin tự động tải khi tải.

Tệp "/etc/default/spamassassin":

CRON=1

Bằng cách cho phép cập nhật tự động các quy tắc “theo mặc định”.

Tập tin “/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

Bạn cần tạo cơ sở dữ liệu “sa” trong mysql với người dùng “sa” bằng mật khẩu “password” (thay bằng gì đó phù hợp).

report_safe - thao tác này sẽ gửi báo cáo về email spam thay vì một lá thư.
use_bayes là các cài đặt máy học gửi thư rác.

Các cài đặt spamassassin còn lại đã được sử dụng trước đó trong bài viết.

Cài đặt chung "spamassassin".
Giới thiệu về việc di chuyển các email Thư rác mới vào thư mục “Thư rác” IMAP.
Về sự kết hợp đơn giản giữa Dovecot + SpamAssassin.
Tôi khuyên bạn nên đọc lý thuyết học spamassasin khi di chuyển các chữ cái trong thư mục imap (và tôi không khuyên bạn nên sử dụng nó).

============== Kêu gọi cộng đồng ==============

Tôi cũng muốn đưa ra ý tưởng cho cộng đồng về cách tăng mức độ bảo mật của các bức thư được chuyển tiếp. Vì tôi quá đắm chìm vào chủ đề thư.

Để người dùng có thể tạo một cặp khóa trên máy khách của mình (outlook, Thunderbird, plugin trình duyệt, ...). Công cộng và tư nhân. Công khai - gửi tới DNS. Riêng tư - lưu vào máy khách. Máy chủ thư sẽ có thể sử dụng khóa chung để gửi đến một người nhận cụ thể.

Và để bảo vệ khỏi thư rác với những bức thư như vậy (vâng, máy chủ thư sẽ không thể xem nội dung) - bạn sẽ cần đưa ra 3 quy tắc:

  1. Chữ ký DKIM thực bắt buộc, SPF bắt buộc, rDNS bắt buộc.
  2. Mạng lưới thần kinh về chủ đề đào tạo chống thư rác + cơ sở dữ liệu về nó ở phía khách hàng.
  3. Thuật toán mã hóa phải sao cho bên gửi phải tiêu tốn sức mạnh CPU gấp 100 lần cho việc mã hóa so với bên nhận.

Ngoài các thư công khai, hãy phát triển một thư đề xuất tiêu chuẩn “để bắt đầu trao đổi thư từ một cách an toàn”. Một trong những người dùng (hộp thư) gửi thư có tệp đính kèm đến hộp thư khác. Bức thư chứa một văn bản đề xuất để bắt đầu một kênh liên lạc an toàn cho thư từ và khóa chung của chủ sở hữu hộp thư (với khóa riêng ở phía máy khách).

Bạn thậm chí có thể tạo một vài khóa cụ thể cho từng thư từ. Người dùng người nhận có thể chấp nhận lời đề nghị này và gửi khóa công khai của mình (cũng được tạo riêng cho thư từ này). Tiếp theo, người dùng đầu tiên gửi thư kiểm soát dịch vụ (được mã hóa bằng khóa chung của người dùng thứ hai) - khi nhận được thư này, người dùng thứ hai có thể coi kênh liên lạc đã hình thành là đáng tin cậy. Tiếp theo, người dùng thứ hai gửi thư kiểm soát - và sau đó người dùng đầu tiên cũng có thể coi kênh đã hình thành là an toàn.

Để chống lại việc chặn các khóa trên đường, giao thức phải cung cấp khả năng truyền ít nhất một khóa chung bằng ổ đĩa flash.

Và điều quan trọng nhất là tất cả đều hoạt động (câu hỏi là “ai sẽ trả tiền cho việc đó?”):
Nhập chứng chỉ bưu điện bắt đầu từ $10 trong 3 năm. Điều này sẽ cho phép người gửi chỉ ra trong dns rằng “khóa công khai của tôi ở đằng kia”. Và họ sẽ cho bạn cơ hội để bắt đầu kết nối an toàn. Đồng thời, việc chấp nhận các kết nối như vậy là miễn phí.
gmail cuối cùng cũng kiếm tiền từ người dùng của mình. Với $10 mỗi 3 năm - quyền tạo các kênh thư tín an toàn.

============== Kết luận ==============

Để kiểm tra toàn bộ bài viết, tôi định thuê một máy chủ chuyên dụng trong một tháng và mua một miền có chứng chỉ SSL.

Nhưng hoàn cảnh cuộc sống phát triển nên vấn đề này kéo dài suốt 2 tháng.
Và vì vậy, khi có thời gian rảnh trở lại, tôi quyết định xuất bản bài báo như cũ, thay vì mạo hiểm việc xuất bản sẽ kéo dài thêm một năm nữa.

Nếu có khá nhiều câu hỏi như “nhưng điều này không được mô tả đầy đủ chi tiết”, thì có lẽ sẽ có đủ sức mạnh để lấy một máy chủ chuyên dụng có tên miền mới và chứng chỉ SSL mới và mô tả nó chi tiết hơn nữa và, hầu hết quan trọng là xác định tất cả các chi tiết quan trọng còn thiếu.

Tôi cũng muốn nhận được phản hồi về ý kiến ​​​​về chứng chỉ bưu chính. Nếu bạn thích ý tưởng này, tôi sẽ cố gắng tìm sức để viết bản nháp cho rfc.

Khi sao chép phần lớn của một bài viết, hãy cung cấp liên kết tới bài viết này.
Khi dịch sang bất kỳ ngôn ngữ nào khác, hãy cung cấp liên kết tới bài viết này.
Tôi sẽ cố gắng tự dịch sang tiếng Anh và để lại phần tham khảo chéo.


Nguồn: www.habr.com

Thêm một lời nhận xét