如何通过端口分流实现多邮箱域名及子域名的服务转发(类似Nginx代理)?
兄弟,我懂你这种全栈转邮件服务一脸懵的感觉!你要的其实是基于域名/子域名的SMTP流量分流,之前Nginx Stream没搞定大概率是配置没做对域名匹配的关键步骤,Postfix没成可能是没摸对虚拟转发的路子,给你捋几个靠谱的落地方向:
一、修正Nginx Stream配置(支持域名匹配)
你说Nginx 1.25.5的server_name不生效?不对哦,Nginx从1.15.9开始就支持Stream模块里的server_name匹配了,大概率是你漏开了SSL预读模块的配置!给你个能直接用的示例:
首先确保你的Nginx编译了--with-stream和--with-stream_ssl_preread_module模块(大部分发行版的官方包都自带这俩),然后在nginx.conf里加这样的Stream配置:
stream { # 必须开启这个,才能解析SMTP请求里的EHLO/HELO域名 ssl_preread on; # 定义上游服务器:把A.com及子域名的流量导到Postal upstream postal_backend { server 127.0.0.1:2525; # 改成你Postal实际监听的端口(别用25,留着给Nginx) } # Modoboa对应的上游,同理改端口 upstream modoboa_backend { server 127.0.0.1:2526; } # 处理SMTP默认端口25 server { listen 25; # 正则匹配A.com和所有子域名,比如mail.a.com、sub.a.com server_name ~^(.+\.)?a\.com$; proxy_pass postal_backend; } server { listen 25; server_name ~^(.+\.)?b\.com$; proxy_pass modoboa_backend; } # 同样处理提交端口587(用户发邮件常用这个) server { listen 587; server_name ~^(.+\.)?a\.com$; proxy_pass postal_backend:587; # 对应Postal的587端口 } server { listen 587; server_name ~^(.+\.)?b\.com$; proxy_pass modoboa_backend:587; } }
配置完重启Nginx,测试下用A.com的邮箱发信,流量应该就自动导到Postal了,B.com的则去Modoboa。
二、用Postfix做虚拟转发(纯邮件场景更轻量)
如果你不想用Nginx这种反向代理,Postfix本身就能搞定域名分流,核心是用transport_maps做域名路由,步骤很简单:
- 打开
/etc/postfix/main.cf,添加这几行配置:
# 开启域名到后端的映射表 transport_maps = hash:/etc/postfix/transport # 让Postfix根据收件人域名判断转发方向 smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_recipient_access hash:/etc/postfix/transport, reject_unauth_destination
- 新建
/etc/postfix/transport文件,写清楚域名和后端的对应关系:
# A.com及所有子域名转发到Postal的端口 a.com smtp:[127.0.0.1]:2525 *.a.com smtp:[127.0.0.1]:2525 # B.com及子域名转发到Modoboa b.com smtp:[127.0.0.1]:2526 *.b.com smtp:[127.0.0.1]:2526
- 最后生成Postfix需要的哈希表,重启服务:
postmap /etc/postfix/transport systemctl restart postfix
这个方案的好处是不用额外装软件,纯邮件原生支持,缺点是只能处理SMTP流量,如果你还要分流IMAP/POP3的话,还是得用Nginx或者HAProxy。
三、HAProxy方案(复杂场景更靠谱)
要是上面俩都没搞定,试试HAProxy——这货是专业的流量分流工具,对邮件协议的支持比Nginx更细腻,还能同时处理SMTP、IMAP、POP3所有邮件端口:
给你个核心配置示例,你可以根据自己的实际情况补全:
frontend mail_frontend mode tcp bind *:25 bind *:587 bind *:143 # IMAP端口 bind *:993 # IMAPS端口 # 预读SSL信息,抓取请求里的域名 tcp-request inspect-delay 5s tcp-request content capture req.ssl_sni len 256 # 根据域名路由:A.com去Postal,B.com去Modoboa use_backend postal_backend if { req.ssl_sni -m end .a.com } use_backend postal_backend if { req.ssl_sni -m end a.com } use_backend modoboa_backend if { req.ssl_sni -m end .b.com } use_backend modoboa_backend if { req.ssl_sni -m end b.com } backend postal_backend mode tcp server postal_smtp 127.0.0.1:2525 check server postal_submit 127.0.0.1:587 check server postal_imap 127.0.0.1:143 check backend modoboa_backend mode tcp server modoboa_smtp 127.0.0.1:2526 check server modoboa_submit 127.0.0.1:587 check server modoboa_imap 127.0.0.1:143 check
HAProxy的优势是能自动识别不同邮件协议的流量,不用给每个端口单独写配置,适合子域名多、协议全的复杂场景。
最后提个小提醒:不管用哪个方案,一定要确保后端的Postal和Modoboa配置里,允许接收对应域名的邮件(比如Postal要把A.com加到允许的域名列表里),不然流量转过去也会被拒收哦!
备注:内容来源于stack exchange,提问作者user655355

