Recently I had to hide my IP address using CloudFlare, but with my MX record pointed to my own domain, I can't.
I know that Mailgun can forward all the emails to user@example.com to Gmail, but I don't want that. I hope the email can be forwarded example.com's own SMTP server.
I decided to use Mailgun catch_all()
and forward("https://exmaple.com/incoming-email?key=SECRET_KEY")
, and wrote some node.js code for that.
var nodemailer = require('nodemailer');
var express = require('express');
var multer = require('multer');
var router = express.Router();
var KEY = 'SECRET_KEY';
var ADDITIONAL_HEADERS = ['timestamp', 'token', 'signature', 'mime-version'];
var transporter = nodemailer.createTransport('smtp://127.0.0.1');
var storage = multer.memoryStorage();
var upload = multer({
storage: storage
});
router.post('/', upload.any(), function (req, res, next) {
if (!req.query.key || req.query.key !== KEY) {
res.sendStatus(403);
return;
}
console.log('Incoming mail: ', req.body.From);
req.body.to = req.body.To;
req.body.cc = req.body.Cc;
req.body.from = req.body.From;
req.body.date = req.body.Date;
req.body.references = req.body.References;
req.body.replyTo = req.body['Reply-To'];
req.body.inReplyTo = req.body['In-Reply-To'];
req.body.messageId = req.body['Message-Id'];
req.body.html = req.body['body-html'];
req.body.text = req.body['body-plain'];
req.body.headers = {};
for (var key in req.body) {
if (key.toLowerCase().indexOf('X-') !== -1 ||
ADDITIONAL_HEADERS.indexOf(key.toLowerCase()) !== -1) {
req.body.headers[key] = req.body[key];
}
}
if (req.files) {
req.body.attachments = req.files;
req.body.attachments.forEach(function (attachment) {
attachment.filename = attachment.originalname;
attachment.contentType = attachment.mimetype;
attachment.content = attachment.buffer;
});
}
transporter.sendMail(req.body, function (err, info) {
if (err) {
console.log(err);
res.status(400).send(err);
return;
}
console.log(info);
res.send(info);
});
});
module.exports = router;
As you can see, the code is able to forward any incoming emails to localhost SMTP server. Using the code about, I can receive emails using user@example.com. The email received will have correct from, to, cc, subject and body and even attachments.
However, a day later I am forced to be unsubscribed from Arch Linux mailing lists, and a person emailed to me that:
It appears that your mail server is misconfigured and sends at least some mails it receives from our mailing lists back to the list. It also removes some headers in the process which help mailman to detect such behaviour. Since those headers are missing, mailman will send the mail out once again to everyone, leading to a never ending loop.
After I called out for help, I have also received some emails indicate that I was unable to receive any emails from mailing lists in the period.
Why could it go wrong? What are the "some headers" in the email removed in the forwarding / wrapping process? Is it Mailgun's problem or my own problem? If it's my problem, what could be added to the code above? Thanks.