Node.js: smtp-server и nodemailer не отправляют сообщения на удалённые хосты, а сохраняют на localhost

Есть сервер на smtp-server, есть отправщик на nodemailer. Письма с удалённых адресов принимаются, но когда я пытаюсь отправить со своего сервера письмо на удалённый адрес, оно не доходит, а принимается как будто извне. В чём причина?

Вот код сервера и отправителя (некоторые адреса и пароли заменены):

server.js

"use strict";

const DOMAIN = "sode.su";

const fs         = require("fs");
const SMTPServer = require("smtp-server").SMTPServer;
const parser     = require("mailparser").simpleParser;
const sqlite3    = require("sqlite3").verbose();

const server = new SMTPServer({
    secure: false,
    key:    fs.readFileSync("/etc/letsencrypt/live/sode.su/privkey.pem"),
    cert:   fs.readFileSync("/etc/letsencrypt/live/sode.su/cert.pem"),

    onRcptTo({address}, session, callback)
    {
        if (address.startsWith("noreply@"))
            return callback(new Error(`Address ${address} is not allowed receiver`));
        callback();
    },

    onAuth(auth, session, callback)
    {
        if (auth.username !== "!SECRET!" || auth.password !== "!SECRET!")
            return callback(new Error("Invalid username or password!"));
        callback(null, { user: 1 });
    },

    onConnect(session, callback) {
        return callback();
    },

    onClose(session) {},

    onMailFrom(address, session, callback) {
        return callback();
    },

    authOptional: true,

    onData(stream, session, callback)
    {
        // Stream – Поток с данными письма. Callback вызывается по окончанию парсинга.
        // в этом обработчике мы будем парсить письмо.

        var parts = [];
        var buffer;
    
        stream.on("data", data => {
            parts.push(data);
        });

        stream.on("end", () => {
            buffer = Buffer.concat(parts);
    
            parser(buffer, {}, (err, mail) => {
                try {
                    if (err)
                        return console.error(err);

                    if (!mail.to) {
                        mail.to = "[email protected]";
                    }

                    mail.headers     = undefined;
                    mail.headerLines = undefined;
                    mail.textAsHtml  = undefined;
                    mail.from        = mail.from.text;
    
                    for (let to_val of (mail.to.value ? mail.to.value : mail.to[0].value)) {
                        if (to_val.address.endsWith("@" + DOMAIN)) {
                            mail.to = to_val.address.split("@")[0];
                            break;
                        }
                    }

                    for (let att in mail.attachments) {
                        mail.attachments[att].content = mail.attachments[att].content.toString("base64");
                    }
    
                    const json = JSON.stringify(mail);
                    const path = "/home/mail/" + DOMAIN + "/" + mail.to + "/" + mail.messageId;
    
                    // если письмо переадресовано, а адресовалось не на sode.su, положить в admin.
                    if (mail.to.value) {
                        mail.to = "admin";
                    }
                    mail.to = mail.to.toLowerCase();
    
                    console.log(mail.to + " :: " + mail.messageId);
    
                    // если у сообщения нет id, дописать его в конец общего списка в .wo_id/
                    if (!mail.messageId) {
                        fs.appendFileSync("/home/mail/" + DOMAIN + "/.wo_id/" + mail.to, buffer + "\n\n\n");
                        return callback();
    
                    } else {
                        // проверяем файл на существование
                        fs.access(path, err => {
                            try {
                                if (err) {
                                    // проверяем каталог адресата на существование
                                    fs.access("/home/mail/" + DOMAIN + "/" + mail.to, err => {
                                        // если каталога нет, создаём его
                                        if (err) {
                                            fs.mkdirSync("/home/mail/" + DOMAIN + "/" + mail.to);
                                        }
    
                                        // записываем разобранное письмо в файл
                                        fs.writeFileSync("/home/mail/" + DOMAIN + "/" + mail.to + "/" + mail.messageId, json);

                                        try {
                                            // надо записать письмо и в бд
                                            var db   = new sqlite3.Database("/home/mail/sode.su/mail.db");

                                            db.get("select id from addresses where name = ?", [ mail.to ], (err, row) => {
                                                if (err)
                                                    return console.error(err);

                                                // если такого адресата в бд ещё нет, создаём
                                                if (!row) {
                                                    db.run("insert into addresses (name) values (?)", [ mail.to ], err => {
                                                        if (err)
                                                            return console.error(err);

                                                        // и получаем его id
                                                        db.get("select id from addresses where name = ?", [ mail.to ], (err, row) => {
                                                            if (err)
                                                                return console.error(err);

                                                            var id = row["id"];

                                                            // вставляем инфу о письме
                                                            db.run("insert into messages (message_id, addressee_id) values (?, ?)", [ mail.messageId, id ], err => {
                                                                if (err)
                                                                    return console.error(err);
                                                            }); 
                                                        });
                                                    });

                                                } else {
                                                    var id = row["id"];
    
                                                    // вставляем инфу о письме  
                                                    db.run("insert into messages (message_id, addressee_id) values (?, ?)", [ mail.messageId, id ], err => {
                                                        if (err)
                                                            return console.error(err);
                                                    });
                                                }
                                            });

                                        } catch (err) {
                                            console.error(err);
                                        } finally {
                                            db.close();
                                        }
                                    });
    
                                // если файл с таким id сообщения уже есть, дописать его в конец общего списка в .err/
                                } else {
                                    fs.appendFileSync("/home/mail/" + DOMAIN + "/.err/" + mail.to, json + "\n\n\n");
                                }
    
                            } catch(err) {
                                console.error(err);
                            }

                            return callback();
                        });
                    }
    
                } catch(err) {
                    console.error(err);
                }
            });
        });
    }
});




process.on('uncaughtException', err => {
    console.error("Caught exception: " + err);
});

server.listen(25);

sender.js

const nodemailer = require("nodemailer");

(async () => {
    try {
        var transporter = nodemailer.createTransport({
            host: "localhost",
            port: 25,
            secure: false,
            auth: {
                user: "!SECRET!",
                pass: "!SECRET!"
            },
            tls: {
                rejectUnauthorized: false
            },
        });

        var mail_options = {
            from:    "!SECRET!",
            to:      "!SECRET!",
            subject: "Hello",
            text:    "Hello!"
        };

        var info = await transporter.sendMail(mail_options);
        console.log("Message sent:\n", info);

    } catch (err) {
        console.error(err);
    }
}) ();

Кода много, но я не знаю, где именно может быть проблема.


Ответы (0 шт):