在内网穿透的环境下搭建邮件系统


一、前言

由于云主机上的存储空间少得可怜,我的各种服务都是通过内网穿透来搭建的。

而内网穿透存在一个明显的缺陷,就是本地服务器无法直接获取客户端的真实 IP 地址,这个应该不难理解吧。

而邮件系统如果不能获取客户端的真实 IP 地址,就无法执行伪造邮件检测、反垃圾等操作。

针对这个问题,我们可以使用 PROXY Protocol 来解决。

此外,我们还必须想办法让邮件系统使用云主机的网络与其他 SMTP 服务器建立连接,否则发出去的邮件几乎都会被拒收。

本文将在「→ 在 CentOS 7 上搭建属于自己的 “完美” 邮件系统」的基础上进行进一步配置以让邮件系统能在内网穿透的环境下正常工作。

说明
• 本文仅介绍邮件系统的相关配置。


二、PROXY Protocol 简介

PROXY Protocol 是 HAProxy 作者开发的用于 TCP 连接的一个协议。

协议文档

开启了 PROXY Protocol 的反向代理服务器会在客户端连接的时候记下客户端的源目 IP 地址及端口信息,并在与后端服务器 TCP 连接的载荷头部加上这个信息。这样一来,后端服务器就能通过 TCP 连接的载荷头部来获取客户端的真实 IP 地址。

PROXY Protocol 目前有两个版本。v1 以纯文本格式传递客户端信息;v2 以二进制格式传递客户端信息。

需要注意的是,PROXY Protocol 必须要客户端支持才能使用。并且如果服务的某个端口开启了 PROXY Protocol,那么该端口就只能由使用 PROXY Protocol 的反向代理服务器来连接(即 TCP 载荷头部必须携带客户端信息)。


三、云主机环境

  • 操作系统:CentOS 7.6.1810

四、配置方法

4.1 大体思路

配置后整个邮件系统的架构如上图所示。下面将从邮件发送以及接收的角度进行讲解。

发送

这里我们使用一个最简单的方法——透明代理。在云主机和本地服务器之间建立诸如 Shadowsocks 的加密代理隧道,然后通过 iptables 的 REDIRECT 功能让本地服务器外发目的端口为 TCP 25、465、587 的流量走代理隧道就完事了。

需要注意的是,这种方法暂时无法支持 IPv6 流量的透明代理(主要是加密代理不支持),但我已经在 Postfix 中设置 IPv4 优先(smtp_address_preference = ipv4),所以基本上没什么影响。

接收

Postfix 和 Dovecot 均额外开启支持 PROXY Protocol 的端口,并通过内网穿透映射到云主机上,内网穿透软件无需进行特别的配置。请注意,这些端口无法直接对外提供服务。

在云主机上使用 HAProxy 来接收传入的邮件服务流量,然后通过 PROXY Protocol 为这些流量添加客户端信息并转发给对应的内网穿透端口。内网穿透软件会将这些流量原封不动地发送给本地服务器。

4.2 本地服务器的配置

4.2.1 重定向流量

假设透明代理端口为 22222,则在本地服务器上执行以下命令:

iptables -t nat -I OUTPUT -p tcp -m multiport --dports 25,465,587 -j REDIRECT --to-ports 22222

然后根据需要自行保存防火墙的配置。

4.2.2 配置 Postfix

说明
• Postfix 仅支持 PROXY Protocol v1。

执行以下命令:

cat >> /etc/postfix/master.cf << EOF

以下内容直接粘贴到命令行窗口中按回车即可。

65501      inet  n       -       n       -       -       smtpd
       -o smtpd_upstream_proxy_protocol=haproxy
65502      inet n       -       n       -       -       smtpd
       -o smtpd_tls_wrappermode=yes
       -o smtpd_upstream_proxy_protocol=haproxy
65503     inet  n       -       n       -       -       smtpd
       -o smtpd_tls_security_level=encrypt
       -o smtpd_upstream_proxy_protocol=haproxy
EOF

说明
• 以上配置的端口号与 4.1 图中的端口号相对应,如有需要可进行修改。

然后,执行以下命令来重启 Postfix 服务:

systemctl restart postfix

4.2.3 配置 Dovecot

说明
• Dovecot 仅支持 PROXY Protocol v2。

请使用 vim 之类的文本编辑器打开 /etc/dovecot/conf.d/10-master.conf

找到以下内容:

inet_listener imaps {
    port = 993
    ssl = yes
  }

然后在以上内容的下方新建一个空行,添加以下内容:

inet_listener imaps_haproxy {
    port = 65504
    ssl = yes
    haproxy = yes
  }

说明
• 以上配置的端口号与 4.1 图中的端口号相对应,如有需要可进行修改。

修改完成后记得保存文件。

然后,执行以下命令来重启 Dovecot 服务:

systemctl restart dovecot

4.3 云主机的配置

4.3.1 安装 HAProxy

执行以下命令:

yum -y install haproxy

4.3.2 配置 HAProxy

执行以下命令:

cat >> /etc/haproxy/haproxy.cfg << EOF

以下内容直接粘贴到命令行窗口中按回车即可。

frontend SMTP
    mode tcp
    bind 0.0.0.0:25
    bind :::25
    use_backend BACKEND-SMTP

backend BACKEND-SMTP
    mode tcp
    server BACKEND-SMTP 127.0.0.1:65501 send-proxy

frontend SMTPS
    mode tcp
    bind 0.0.0.0:465
    bind :::465
    use_backend BACKEND-SMTPS

backend BACKEND-SMTPS
    mode tcp
    server BACKEND-SMTPS 127.0.0.1:65502 send-proxy

frontend SUBMISSION
    mode tcp
    bind 0.0.0.0:587
    bind :::587
    use_backend BACKEND-SUBMISSION

backend BACKEND-SUBMISSION
    mode tcp
    server BACKEND-SUBMISSION 127.0.0.1:65503 send-proxy

frontend IMAPS
    mode tcp
    bind 0.0.0.0:993
    bind :::993
    use_backend BACKEND-IMAPS

backend BACKEND-IMAPS
    mode tcp
    server BACKEND-IMAPS 127.0.0.1:65504 send-proxy-v2
EOF

说明
• 以上配置的端口号与 4.1 图中的端口号相对应,如有需要可进行修改。

4.3.3 启动 HAProxy 服务

执行以下命令:

systemctl start haproxy

如需开机自启动,请执行:

systemctl enable haproxy

发表评论

电子邮件地址不会被公开。