最近需要在 vultr 云服务器上搭一个邮件服务器,参考 How To Install and Configure Postfix on Ubuntu 16.04 很快就完成了,本地收发测试正常。

但当向外网如 QQ 邮箱 发邮件时:

echo "test" | mail -s "test" -r xiaoxiang@xiaoxiang.io shdxiang@qq.com

却发现连接不上对方服务器,日志如下:

tail /var/log/mail.log
...
Jan  6 04:24:25 vultr-singapore-1 postfix/smtp[18497]: connect to mx3.qq.com[184.105.206.86]:25: Connection timed out
Jan  6 04:24:55 vultr-singapore-1 postfix/smtp[18497]: connect to mx3.qq.com[184.105.206.31]:25: Connection timed out
...

手动测试发现确实是连接不上:

nc -vw 2 mx3.qq.com 25
nc: connect to mx3.qq.com port 25 (tcp) failed: Connection refused
nc: connect to mx3.qq.com port 25 (tcp) failed: Connection refused
...

在我个人电脑上测试是完全可以连接 mx3.qq.com:25 的。

网上搜索后才明白,原因是为了阻止发送垃圾邮件 vultr 禁用了端口 25 的出口流量,其它云服务器提供商也有类似的规则,虽然可以通过工单来申请打开,但是个比较繁琐的过程,因为本来只是搭建一个测试服务器嘛。

那怎么办呢?理论其实很简单,把云服务器发到 mx3.qq.com:25 的流量转发到个人电脑,再由个人电脑转发给真正的 mx3.qq.com 25,我们通过 iptablesssh 来实现。

首先在个人电脑上运行:

ssh -nNT -R 250:mx3.qq.com:25 root@xiaoxiang.io

此命令的作用是建立一条 ssh 隧道,此隧道可以将云服务器(即 xiaoxiang.io)250 端口收到的数据转发给 mx3.qq.com:25

在云服务器上可以看到 sshd 在监听端口 250 了:

sudo netstat -lntp | grep 250
tcp        0      0 127.0.0.1:250           0.0.0.0:*               LISTEN      23113/sshd: root
tcp6       0      0 ::1:250                 :::*                    LISTEN      23113/sshd: root

然后在云服务器上运行:

sudo iptables -t nat -A OUTPUT -p tcp -d mx3.qq.com --dport 25 -j DNAT --to-destination 127.0.0.1:250

这条 iptables 规则的作用是将发送到 mx3.qq.com:25 的数据转发到 127.0.0.1:250 也就是云服务器本身的 250 端口,而这个端口正是 sshd 监听的端口,即隧道的一端。

云服务器上的邮件服务器发给 mx3.qq.com:25 的数据首先被 iptables 的规则转发到它本身的 250 端口,即转发给 sshdsshd 再将数据传给个人电脑上的 ssh 客户端,客户端最终将数据发给 mx3.qq.com:25

至此,就可以正常发送邮件了,可以看到日志:

...
Jan  6 08:16:20 vultr-singapore-1 postfix/cleanup[23272]: 7A4C26113D: message-id=<20180106081620.r63Q01S_1%xiaoxiang@xiaoxiang.io>
Jan  6 08:16:20 vultr-singapore-1 postfix/qmgr[22506]: 7A4C26113D: from=<xiaoxiang@xiaoxiang.io>, size=316, nrcpt=1 (queue active)
Jan  6 08:16:22 vultr-singapore-1 postfix/smtp[23274]: 7A4C26113D: to=<shdxiang@qq.com>, relay=mx3.qq.com[184.105.206.82]:25, delay=2.2, delays=0.04/0.02/0.71/1.4, dsn=2.0.0, status=sent (250 Ok: queued as )
Jan  6 08:16:22 vultr-singapore-1 postfix/qmgr[22506]: 7A4C26113D: removed