本文介绍如何设置现代邮件服务器。
后缀+鸽舍。 SPF + DKIM + rDNS。 与 IPv6。
采用 TSL 加密。 支持多个域 - 具有真实 SSL 证书的部分。
具有反垃圾邮件保护和来自其他邮件服务器的高反垃圾邮件评级。
支持多个物理接口。
对于 OpenVPN,连接是通过 IPv4 进行的,而连接则提供 IPv6。
如果您不想学习所有这些技术,但想设置这样的服务器,那么本文适合您。
本文并不试图解释每一个细节。 该解释针对哪些内容未按标准设置或从消费者的角度来看很重要。
建立邮件服务器的动机是我的旧梦。 这可能听起来很愚蠢,但恕我直言,这比梦想拥有一辆你最喜欢的品牌的新车要好得多。
配置 IPv6 的动机有两个。 IT专家需要不断学习新技术才能生存。 我愿意为反对审查制度做出自己的微薄贡献。
配置 OpenVPN 的动机只是为了让 IPv6 在本地计算机上工作。
设置多个物理接口的动机是,在我的服务器上,我有一个“慢但无限制”的接口和另一个“快,但有关税”的接口。
设置 Bind 设置的动机是我的 ISP 提供了不稳定的 DNS 服务器,并且 google 有时也会崩溃。 我想要一个稳定的 DNS 服务器供个人使用。
写这篇文章的动机是10个月前写的草稿,我已经看过两遍了。 即使作者经常需要它,那么其他人也很有可能需要它。
邮件服务器没有通用的解决方案。 但我会尝试写一些类似“这样做,然后,当一切都按预期进行时,扔掉多余的东西”。
tech.ru 有一个托管服务器。 可以与OVH、Hetzner、AWS进行比较。 为了解决这个问题,与tech.ru的合作会更有效。
服务器已安装 Debian 9。
服务器有 2 个接口“eno1”和“eno2”。 第一个是无限的,第二个是快速的。
有 3 个静态 IP 地址,“eno0”接口上有 XX.XX.XX.X1 和 XX.XX.XX.X2 和 XX.XX.XX.X1,“eno5”接口上有 XX.XX.XX.X2 。
可用 XXXX:XXXX:XXXX:XXXX::/64 分配给“eno6”接口的 IPv1 地址池,并根据我的要求将 XXXX:XXXX:XXXX:XXXX:1:2::/96 分配给“eno2”。
有 3 个域“domain1.com”、“domain2.com”、“domain3.com”。 `domain1.com` 和 `domain3.com` 有一个 SSL 证书。
我有一个 Google 帐户,我想将其链接到邮箱`[电子邮件保护]`(直接从 gmail 界面接收邮件和发送邮件)。
必须有一个邮箱`[电子邮件保护]`,我想在 Gmail 中查看的邮件副本。 而且能代发东西的也很少见`[电子邮件保护]` 通过网络界面。
必须有一个邮箱`[电子邮件保护]`,伊万诺夫将在他的 iPhone 上使用它。
发送的电子邮件必须符合所有现代反垃圾邮件要求。
应该是公共网络中提供的最高级别的加密。
发送和接收电子邮件都必须支持 IPv6。
应该是SpamAssassin,它永远不会删除电子邮件。 它会退回、跳过或发送到 IMAP 垃圾邮件文件夹。
必须配置 SpamAssassin 自动学习:如果我将信件移至 Spam 文件夹,它就会从中学习; 如果我从垃圾邮件文件夹中移动一封信,它就会从中学习。 SpamAssassin 训练结果 - 应该影响垃圾邮件文件夹中信件的命中率。
PHP 脚本应该能够代表给定服务器上的任何域发送邮件。
必须有一个 openvpn 服务,能够在没有 IPv6 的客户端上使用 IPv6。
首先,您需要配置接口和路由,包括 IPv6。
然后,您需要配置 OpenVPN,它将通过 IPv4 连接并为客户端提供静态真实 IPv6 地址。 该客户端将有权访问服务器上的所有 IPv6 服务以及 Internet 上的任何 IPv6 资源。
然后你需要配置 Postfix 来发送电子邮件 + SPF + DKIM + rDNS 和其他类似的小事情。
然后您需要配置 Dovecot 并配置多域。
然后您需要配置 SpamAssassin 并设置培训。
最后,安装绑定。
============= 多接口============
要配置接口,您需要在“/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 的虚拟 NIC 的名称。
XX.XX.XX.X0 - eno4 上的 IPv1 #1。
XX.XX.XX.X1 - eno4 上的 IPv2 #1。
XX.XX.XX.X2 - eno4 上的 IPv3 #1。
XX.XX.XX.X5 - eno4 上的 IPv1 #2。
XX.XX.XX.1 - IPv4 网关。
XXXX:XXXX:XXXX:XXXX::/64 - 整个服务器的 IPv6。
XXXX:XXXX:XXXX:XXXX:1:2::/96 - eno6 的 IPv2,其他所有内容都从外部转到 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
该块指定 eno4 接口的第二个 IPv1。
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。 否则,您将无法为 OpenVPN 客户端配置 IPv6 网关。
eno2 - 子网必须大于 tun0。 否则,OpenVPN 客户端将无法获取 IPv6 本地地址。
为了清楚起见,我选择了子网步骤 16,但如果您愿意,您甚至可以执行“1”步骤。
因此,64 + 16 = 80,80 + 16 = 96。为了更清楚:
XXXX:XXXX:XXXX:XXXX:1:1:YYYY:YYYY 是应分配给接口 eno1 上的特定站点或服务的地址。
XXXX:XXXX:XXXX:XXXX:1:2:YYYY:YYYY 是应分配给接口 eno2 上的特定站点或服务的地址。
XXXX:XXXX:XXXX:XXXX:1:3:YYYY:YYYY 是分配给 OpenVPN 客户端或用作 OpenVPN 服务地址的地址。
要配置网络,应该可以重新启动服务器。
IPv4 更改在执行过程中被拾取(确保将其包裹在屏幕中 - 否则此命令将简单地删除服务器上的网络):
/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
如果没有这些设置,来自 OpenVPN 客户端的 IPv6 流量将不会传播到世界各地。
其他设置要么不相关,要么我不记得为什么。
但为了以防万一,我将其保留“原样”。
为了在不重新启动服务器的情况下应用对此文件的更改,您必须运行以下命令:
sysctl -p
有关“表”规则的更多详细信息:
============= OpenVPN ==============
如果没有 iptables,OpenVPN IPv4 就无法工作。
我有这样的 VPN iptables:
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 - IPv4 openvpn 网络。 openvpn 客户端的 IPv4 地址。
规则的顺序很重要。
iptables -A INPUT -p udp -s YY.YY.YY.YY --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -o eno1 -j ACCEPT
...
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -j DROP
iptables -A FORWARD -p udp --dport 1194 -j DROP
这是一个限制,只有我可以从我的静态 IP 使用 OpenVPN。
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j SNAT --to-source XX.XX.XX.X0
-- или --
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADE
要在 OpenVPN 客户端和 Internet 之间转发 IPv4 数据包,您需要注册这些命令之一。
对于不同的情况,其中一种选项并不适合。
这两个命令都适合我的情况。
阅读文档后,我选择了第一个选项,因为它占用的 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
这并不适合所有人 - 我选择了这种加密连接的方法。
============ 后缀 ==============
安装主包:
apt-get install postfix
安装时,选择“internet-site”。
我的“/etc/postfix/main.cf”看起来像这样:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
smtpd_use_tls=yes
smtpd_tls_auth_only = yes
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1
smtp_tls_security_level = may
smtp_tls_ciphers = export
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_loglevel = 1
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = domain1.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = domain1.com
mydestination = localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
internal_mail_filter_classes = bounce
# Storage type
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# SMTP-Auth settings
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
#reject_invalid_hostname,
#reject_unknown_recipient_domain,
reject_unauth_destination,
reject_rbl_client sbl.spamhaus.org,
check_policy_service unix:private/policyd-spf
smtpd_helo_restrictions =
#reject_invalid_helo_hostname,
#reject_non_fqdn_helo_hostname,
reject_unknown_helo_hostname
smtpd_client_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_helo_hostname,
permit
# SPF
policyd-spf_time_limit = 3600
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim/opendkim.sock
# IP address per domain
sender_dependent_default_transport_maps = pcre:/etc/postfix/sdd_transport.pcre
让我们看看这个配置的详细信息。
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
根据哈布罗维派的说法,这个区块包含“虚假信息和不正确的论点”。在我开始职业生涯仅 8 年之后,我就开始了解 SSL 的工作原理。
因此,我将冒昧地描述如何使用 SSL(不回答“它是如何工作的?”和“它为什么工作?”的问题)。
现代加密的基础是创建密钥对(两个很长的字符串)。
一个“密钥”是私有的,另一个密钥是“公共”的。 私钥被严格保密。 我们将公钥分发给每个人。
使用公钥,您可以加密一串文本,以便只有私钥的所有者才能解密它。
嗯,这就是技术的全部基础。步骤#1 - https 网站。
浏览器在访问该站点时,从 Web 服务器获知该站点是 https,因此请求公钥。
Web 服务器给出公钥。 浏览器使用公钥对http请求进行加密并发送。
http请求的内容只能由拥有私钥的人(即正在访问的服务器)读取。
Http-request 至少包含一个 URI。 因此,如果一个国家试图限制访问不是整个网站而是特定页面,那么对于 https 网站就无法做到这一点。步骤#2 - 加密响应。
Web 服务器会给出一个可以轻松读取的响应。
解决方案非常简单 - 浏览器在本地为每个 https 站点生成相同的私钥-公钥对。
在请求站点公钥的同时,它还发送其本地公钥。
Web 服务器会记住它,并在发送 http 响应时使用特定客户端的公钥对其进行加密。
现在http-response只能由客户端浏览器私钥的所有者(即客户端本身)解密。步骤 3 - 通过公共通道建立安全连接。
在示例 2 中,存在一个漏洞 - 没有什么可以阻止好心人拦截 http 请求并编辑有关公钥的信息。
因此,中间人将完全能够看到发送和接收的消息的全部内容,直到通信通道发生改变。
处理这个问题非常简单 - 只需将浏览器的公钥作为使用 Web 服务器的公钥加密的消息发送即可。
然后,网络服务器首先发送一个类似“你的公钥是这样的”的响应,并使用相同的公钥加密该消息。
浏览器查看答案 - 如果收到“您的公钥是这样的”消息,则 100% 保证该通信通道是安全的。
安全性如何?
这种安全通信通道的创建速度为 ping * 2。 例如20毫秒。
攻击者必须提前拥有其中一方的私钥。 或者在几毫秒内获取私钥。
在超级计算机上破解一个现代私钥需要数十年的时间。第 4 步 - 公钥的公共数据库。
显然,在整个故事中,攻击者有可能占据客户端和服务器之间的通信通道。
客户端能够显示为服务器,服务器能够显示为客户端。 并在两个方向上模拟一对按键。
然后攻击者将看到所有流量并能够“编辑”流量。
例如,更改汇款地址或从网上银行复制密码或阻止“令人反感”的内容。
为了对抗此类入侵者,他们提出了一个公共数据库,其中包含每个 https 站点的公钥。
每个浏览器都“知道”大约 200 个此类数据库的存在。 每个浏览器都预装了它。
“知识”由每个证书的公钥支持。 也就是说,与各个特定认证机构的连接是无法伪造的。现在已经简单了解了如何使用SSL进行https。
如果你动动脑子,就会清楚特殊服务如何破解这个结构中的某些东西。 但这将花费他们巨大的努力。
而对于比 NSA 或 CIA 更小的组织来说,即使是 VIP 也几乎不可能突破现有的保护级别。我还将添加有关 ssh 连接的内容。 没有公钥,怎么办。 该问题通过两种方式解决。
ssh-by-password 选项:
在第一次连接时,ssh 客户端应该警告我们有来自 ssh 服务器的新公钥。
随着连接的进一步深入,如果出现警告“来自 ssh 服务器的新公钥”,则意味着他们正在尝试听取您的意见。
或者在第一次连接时,您被监听,现在您无需中介即可与服务器进行通信。
实际上,由于窃听的事实很容易、快速且毫不费力地被揭露,这种攻击仅在针对特定客户端的特殊情况下使用。ssh-by-key 选项:
我们拿一个闪存驱动器,为 ssh 服务器写入一个私钥(这有一些术语和许多基本的细微差别,但我正在编写一个教育程序,而不是使用说明)。
我们将公钥留在 ssh 客户端所在的计算机上,并对其保密。
我们把闪存驱动器带到服务器上,粘贴它,复制私钥,然后烧掉闪存驱动器并在风中撒灰(或者至少用零填充格式化它)。
就是这样 - 在这样的操作之后,将不可能破解这样的 ssh 连接。 当然,十年后我们将有可能在超级计算机上看到流量——但那是另一回事了。我为offtopic道歉。
所以,现在这个理论已经众所周知了。 我会告诉你创建ssl证书的流程。
在“openssl genrsa”的帮助下,我们创建一个私钥和公钥的“空白”。
我们将“空白”发送给第三方公司,我们为最简单的证书支付约 9 美元。
几个小时后,我们从这家第三方公司收到了我们的“公钥”和一组多个公钥。
为什么第三方公司要支付我的公钥的注册费用是一个单独的问题,我们在这里不考虑它。
现在大家很清楚铭文的含义了:
smtpd_tls_key_file=/etc/ssl/domain1.com.2018.key
“/etc/ssl”文件夹包含 ssl 问题的所有文件。
domain1.com 是域名。
2018 年是密钥创建的年份。
“key”表示该文件是私钥。
以及这个文件的含义:
smtpd_tls_cert_file=/etc/ssl/domain1.com.2018.chained.crt
domain1.com 是域名。
2018 年是密钥创建的年份。
chained - 表示存在一个公钥链(第一个是我们的公钥,其余的来自发行公钥的公司)。
crt - 表示有一个现成的证书(带有技术解释的公钥)。
smtp_bind_address = XX.XX.XX.X0
smtp_bind_address6 = XXXX:XXXX:XXXX:XXXX:1:1:1:1
本例中不使用此设置,但作为示例编写。
因为此参数错误将导致从您的服务器发送垃圾邮件(未经您的意愿)。
然后向所有人证明你是无罪的。
recipient_delimiter = +
也许很多人不知道,所以这是pasem排名的标准字符,并且大多数现代邮件服务器都支持它。
例如,如果您有一个邮箱“[电子邮件保护]» 尝试发送至 «[电子邮件保护]- 走着瞧吧。
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 授权才可以接受邮件以进一步发送。
我真的不明白为什么这里会重复这个。 我们已经指出了“virtual_transport”中所需的一切。
但 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 脚本并不总是指示“from”字段。 然后用户名就可以派上用场了。这篇文章已经很广泛了 - 我不想因为设置 nginx + fpm 而分心。
简而言之 - 我们为每个站点设置了自己的 linux 用户所有者。 相应地你的 fpm 池。
Fpm-pool 使用任何版本的 php(当您可以在同一服务器上使用不同版本的 php 甚至不同的 php.ini 且相邻站点不会出现问题时,这非常棒)。
因此,特定的 linux 用户“www-domain2”拥有一个站点 domain2.com。 该站点有一个用于发送电子邮件的代码,无需指定发件人字段。
因此,即使在这种情况下,信件也会正确离开,并且永远不会落入垃圾邮件。
我的“/etc/postfix/master.cf”看起来像这样:
...
smtp inet n - y - - smtpd
-o content_filter=spamassassin
...
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
...
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}
...
domain1 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X1
-o smtp_helo_name=domain1.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:1:1
-o syslog_name=postfix-domain1
domain2 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X5
-o smtp_helo_name=domain2.com
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:2:1:1
-o syslog_name=postfix-domain2
domain3 unix - - n - - smtp
-o smtp_bind_address=XX.XX.XX.X2
-o smtp_helo_name=domain3
-o inet_protocols=all
-o smtp_bind_address6=XXXX:XXXX:XXXX:XXXX:1:1:5:1
-o syslog_name=postfix-domain3
该文件未完整显示 - 它已经非常大。
我只标记了更改的内容。
smtp inet n - y - - smtpd
-o content_filter=spamassassin
...
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}
这些是与 spamassasin 相关的设置,稍后会详细介绍。
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
我们允许您通过端口 587 连接到邮件服务器。
为此,您必须登录。
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” - 这是为了方便阅读日志。
购买证书
=============鸽舍==============
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 培训设置在传输到“垃圾邮件”文件夹或从“垃圾邮件”文件夹传输时的设置。
文件“/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
主要配置文件。
重要的是我们在这里指定添加协议。
============= 垃圾杀手 ==============
apt-get install spamassassin spamc
让我们安装这些软件包。
adduser spamd --disabled-login
添加代表其的用户。
systemctl enable spamassassin.service
启用启动时自动加载 spamassassin 服务。
文件“/etc/default/spamassassin”:
CRON=1
默认情况下启用规则自动更新。
文件“/etc/spamassassin/local.cf”:
report_safe 0
use_bayes 1
bayes_auto_learn 1
bayes_auto_expire 1
bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
bayes_sql_dsn DBI:mysql:sa:localhost:3306
bayes_sql_username sa
bayes_sql_password password
有必要在mysql中创建一个数据库“sa”,用户为“sa”,密码为“password”(替换为适当的内容)。
report_safe - 这将发送垃圾邮件报告而不是信件。
use_bayes 是 spamassassin 机器学习设置。
Spamassassin 的其余设置已在本文前面应用。
============= 社区呼吁==============
我还想向社区提出一个关于如何提高转发信件的安全级别的想法。 因为我深深地沉浸在邮件这个话题中。
这样用户就可以在他的客户端(outlook、thunderbird、浏览器插件等)上创建密钥对。 公立和私立。 公共 - 发送到 DNS。 私密 - 为客户节省费用。 邮件服务器将能够使用公钥发送给特定的收件人。
为了防止此类信件的垃圾邮件(是的,邮件服务器将无法查看内容) - 您需要输入 3 条规则:
- 强制真实 DKIM 签名、强制 SPF、强制 rDNS。
- 一个关于学习反垃圾邮件主题的神经网络+客户端的数据库。
- 加密算法必须使得发送方在加密上花费的 CPU 能力必须是接收方的 100 倍。
除了公开信函之外,还应制定“开始安全通信”的要约函标准。 其中一个用户(邮箱)将一封带有附件的信件发送到另一个邮箱。 在信中,有一条文本语句启动了一个用于通信的安全通信通道以及邮箱所有者的公钥(私钥位于客户端)。
您甚至可以为每封信件专门制作几个钥匙。 接收用户可以接受此提议并发送他的公钥(也是专门为此通信而制作的)。 接下来,第一用户发送服务控制信函(用第二用户的公钥加密)——第二用户收到该信函后可以认为所形成的通信信道是可靠的。 然后第二个用户发送控制信——然后第一个用户也可以认为所形成的通道是安全的。
为了防止在路上拦截密钥,有必要在协议中提供使用闪存驱动器传输至少一个公钥的可能性。
最重要的是这一切都有效(问题是“谁来为此买单?”):
推出价值 10 美元起、为期 3 年的邮政凭证。 这将允许发件人在 dns 中指定“我的公钥在那里”。 他们将提供开始安全连接的机会。 同时 - 免费接受此类连接。
gmail 终于通过其用户获利了。 10 年内只需花费 3 美元即可获得创建安全通信渠道的权利。
============= 结论==============
为了测试整篇文章,我打算租用一个月的专用服务器并购买带有 ssl 证书的域名。
但生活环境发生了变化,这个问题拖了两个月。
当空闲时间再次出现时,我决定按原样发表这篇文章,而不是冒着出版又拖一年的风险。
如果有很多诸如“但这里描述得不够详细”之类的问题,那么可能会有实力采用具有新域和新 SSL 证书的专用服务器并更详细地描述它,最重要的是,找出所有遗漏的重要细节。
我还想收到有关邮件证书想法的反馈。 如果你喜欢这个想法,我会努力找到力量为rfc写一份草稿。
复制大篇文章时,请标明指向本文的链接。
翻译成任何其他语言时,请提供本文的链接。
我会尝试自己翻译成英文并留下交叉引用。
来源: habr.com