快速搭建一个SMTP邮件服务

in #cn-dev2 years ago (edited)

image.png

由于最近一台VPS要到期不打算续费了,上面有一个SMTP发邮件的服务,因此需要转移。

当时配置的时候,是直接在宿主机搞的,转移起来有些麻烦。

为了以后转移方便,这次打算使用 docker 部署。

在网上找了半天,有很多类似的快速搭建的 Docker 镜像。

我找到的是这个 https://github.com/cainwise/docker-postfix

但是这个库里记录的 Docker 镜像已经不存在或者被作者设置为私有了。

而 Dockerfile 编译也因为软件包过时的原因,无法编译了。

于是花了三天三夜的时间重写了 Dockerfile。

新的代码库:https://github.com/ety001/docker-postfix

现在可以基于我新做的 Docker 镜像来快速部署 SMTP 服务了。

假设要为 example.com 域设置一个邮件服务器 mail.example.com(IP 地址为 1.2.3.4),并开启 STARTTLS 的支持。

创建 Postfix 容器

创建目录 /etc/postfix_conf/dkim_keys/etc/postfix_conf/tls

mkdir -p /etc/postfix_conf/dkim_keys
mkdir -p /etc/postfix_conf/tls

运行临时容器,不带 STARTTLS 功能

shell> docker run --name postfix \
          -itd --rm\
          --restart always \
          -p 25:25 \
          -e MTA_DOMAIN=example.com \
          -e MTA_HOST=mail.example.com \
          -e MTA_USERS=user:passwd \
          -v /etc/postfix_conf/dkim_keys:/etc/opendkim/keys \
          ety001/postfix

使用 acme.sh 来申请证书并安装证书

shell> acme.sh --issue -d mail.example.com --dns dns_cf
shell> acme.sh --installcert \
    -d mail.example.com \
    --key-file /etc/postfix_conf/tls/mail.example.com.key \
    --fullchain-file /etc/postfix_conf/tls/mail.example.com.crt \
    --reloadcmd "docker restart postfix"

停止容器,启动正式容器(即多增加一个证书目录的映射)

shell> docker stop postfix
shell> docker run --name postfix \
          -itd --restart always \
          -p 25:25 \
          -e MTA_DOMAIN=example.com \
          -e MTA_HOST=mail.example.com \
          -e MTA_USERS=user:passwd \
          -v /etc/postfix_conf/dkim_keys:/etc/opendkim/keys \
          -v /etc/postfix_conf/tls:/etc/postfix/tls \
          ety001/postfix

配置 MX 记录 和 A 记录

TypeHostAnswer
MXexample.commail.example.com
Amail.example.com1.2.3.4
  • MX 保证向 example.com 域发送的邮件就会被递送到 mail.example.com
  • A 记录保证能解析到 mail.example.com 的 IP 地址。

配置 PTR 记录 (rDNS)

1.2.3.4 配置反向解析,值为 mail.example.com

配置 SPF 记录

TypeHostAnswer
TXTexample.comv=spf1 mx ~all
SPFexample.comv=spf1 mx ~all

配置 DKIM 记录

容器创建后,会在容器日志中显示公钥值,将其中的值按如下方式填写即可:

TypeHostAnswer
TXTmail._domainkey.example.comv=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCi3zFH65YkLK+Edfu3VeZH2ylOpNC3ADfkL2p1PjhWQXrzn65rvrh2YTqEEb8xGunWD9c422SBoxRdpVENhUqnbb1Tk0Xu58gfrN2muTIedFDtWx7irvySNtDgcWWIdXDaPFk/nodeutahtueaszEuLqI/DpKD/9mY9Mm5QIDAQAB

配置 DMARC 记录

TypeHostAnswer
TXT_dmarc.example.comv=DMARC1; p=reject; rua=postmaster@mexample.com

测试

用一个简单 Node 程序来测试邮件服务是否可以正常工作。

'use strict';

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'mail.example.com',
  port: 25,
  secure: false,
  requireTLS: true,
  auth: {
    user: 'user@mail.example.com',
    pass: 'passwd'
  },
});

// setup e-mail data with unicode symbols
var mailOptions = {
  from: '"BOSS" <boss@example.com>', // sender address
  to: '<your mail>', // list of receivers
  subject: '风中的来信', // Subject line
  text: '为了防止垃圾邮件,现在有许多 SMTP 服务器要求客户端的 IP 地址必须要能够查到有效的 PTR 记录。', // plaintext body
  html: '为了防止垃圾邮件,现在有许多 SMTP 服务器要求客户端的 IP 地址必须要能够查到有效的 PTR 记录。' // html body
};

// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
  if(error){
    return console.log(error);
  }
  console.log('Message sent: ' + info.response);
})

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.034
BTC 63815.31
ETH 3124.40
USDT 1.00
SBD 3.99