Set up Nodemailer to secure email with a STARTLS handshake? - node.js

I need to send e-mail through my remote Postfix/Dovecot SASL service from Node.js on my desktop.
When I send email using Thunderbird, it works and the Postfix server logs show
Anonymous TLS connection established from unknown[dh.cp.ip.ip]: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)
But not through nodemailer, where the Postfix server logs:
Nov 26 22:02:31 servicelabel postfix/submission/smtpd[27019]: connect from unknown[dh.cp.ip.ip]
Nov 26 22:02:31 servicelabel postfix/submission/smtpd[27019]: lost connection after CONNECT from unknown[dh.cp.ip.ip]
Nov 26 22:02:31 servicelabel postfix/submission/smtpd[27019]: disconnect from unknown[dh.cp.ip.ip] commands=0/0
These same settings are used for Nodemailer transport and Thunderbird
let transporter = nodemailer.createTransport(
{
host: "mx.example.com",
port: 587,
secure: false, // use TLS
// requireTLS:true,
auth: {
user: "emailuser",
pass: "password"
},
tls: { rejectUnauthorized: false },
// logger: true,
debug: true
},
{
from: 'myuser#example.com',
}
);
But Nodemailer won't connect to Dovecot with TLS the same way Thunderbird does ??
when I change secure to true to force TLS a SSL routines:ssl3_get_record:wrong version number error (below); it appears when verifying the transport.
transporter.verify(function(error, success) {
if (error) {
console.log(error);
} else {
console.log("Server is ready to take our messages");
return false;
}
});
Error: 140185182082944:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:
code:"ECONNECTION"
command:"CONN"
function:"ssl3_get_record"
library:"SSL routines"
message:"140185182082944:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:\n"
reason:"wrong version number"
stack:"Error: 140185182082944:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:\n"
When I test with this command:
openssl s_client -starttls smtp -connect mx.example.com:587
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = mx.example.com
verify return:1
---
Certificate chain
0 s:CN = mx. ...
...
...
... the SSL/STARTTLS handshake succeeds and certificates
But if I use this command:
openssl s_client -connect mx.example.com:587 -crlf -ign_eof
I get the same error as with Nodemailer
CONNECTED(00000005)
140508975112640:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:332:
I've tried a number of option configurations and am at a loss...
How do I send secure email through my Dovecot/Postfix server via Nodemailer? Do I need to configure some certs in Nodemailer? Should I use something different to send secure email from node.js? Any help appreciated.

My unit testing context in Mocha does not have the ciphersuites of Node.js available.
The Nodemailer has no problem initiating TLS handshake from STARTLS when running in a Node.js context.

can't add a comment to #Kickaha's response to confirm his observation.
FYI: Some of the node mailer error messages are misleading. When I fat fingered the port number, I got a wrong version error, but now it runs fine from a firebase node.js function:
try {
const mailFrom = functions.config().mail.from;
const mailPwd = functions.config().mail.pwd;
const mailHost = functions.config().mail.host;
// some code to generate the message
const mailOptions = {
from: mailFrom,
to: creatorEmail,
subject: subject,
html: message
};
const transporter = nodemailer.createTransport({
host: mailHost,
port: 465,
secure: true, // STARTTLS
auth: {
type: 'LOGIN',
user: mailFrom,
pass: mailPwd
}
});
await transporter.sendMail(mailOptions);
} catch (err) {
console.error(err);
}

Related

Error: Invalid greeting. response=421 Service not available: 421 Service not available

i tried using nodemailer to send emails from my outlook account to other accounts but i keep getting this error.
Error: Invalid greeting. response=421 Service not available: 421 Service not available
code: 'EPROTOCOL',
response: '421 Service not available',
responseCode: 421,
command: 'CONN'
Here is my code
const nodemailer = require("nodemailer");
module.exports = function OTP() {
// Sends otp link to and code to user
return new Promise((resolve, reject) => {
const transporter = nodemailer.createTransport({
service: "hotmail",
port: "25",
secure: true,
auth: {
user: process.env.EMAIL, //Outlook email
pass: process.env.EMAIL_PASSWORD,
},
tls: {
ciphers: "SSLv3",
},
});
transporter.sendMail(
{
from: process.env.EMAIL,
to: email,
subject: "Test",
text: `
`,
},
(err, info) => {
if (err) {
console.log(err);
return reject({ message: "An error has occurred" });
} else return resolve({ message: "Email sent" });
}
);
});
};
i tried changing the port and switching to gmail but i get the same error.
I had this same error but in nestjs and this is my solution that you can try.
First in my configuration I did not define a port and my secure was set to false, so port was default to 587. I was sending mail and everything was fine untill one day I started to get the same error as you are getting now. so here is my fix
I use telnet to test my connection to the mail server:
a. Open terminal and type: telnet your_domain 587. eg
telnet smtp.sendgrid.net 587
I got 421 Service not available
I change secure to true which will now default the port to 465 and I try telnet again, this time
telnet smtp.sendgrid.net 465
I got no error. I test the endpoint again and everything works fine.
I hope this helps
Reference:
stackoverflow
nodemailersmtp

Nodemailer to GMAIL Error: self-signed certificate in certificate chain

It is a GMAIL server my two-step password is correct and my recipient data is correct
"use strict";
const nodemailer = require("nodemailer");
// async..await is not allowed in global scope, must use a wrapper
async function main() {
// Generate test SMTP service account from ethereal.email
// Only needed if you don't have a real mail account for testing
//let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: "smtp.gmail.com", //Servidor de gmail
port: 465, //Puerto de servidor de gmail
secure: true, //Esta activado en true // true for 465, false for other ports
auth: {
user: ' ****#gmail.com',/*testAccount.user,*/ // generated ethereal user
pass: 'qskafnvgyhzyrceb'/*testAccount.pass,*/ // generated ethereal password
},
});
// send mail with defined transport object
let info = await transporter.sendMail({
from: '*****#gmail.com',/*'"Fred Foo 👻" <foo#example.com>',*/ // sender address
to: '*****#gmail.com',/*"bar#example.com, baz#example.com",*/ // list of receivers
subject: "Hello ✔", // Subject line
text: "Hello world?", // plain text body
html: "<h1>Hello World</h1>", // html body
});
}
main().then(() => { console.log('Correo Enviado') }).catch((err)=>{ console.log(err) }/*console.error*/);`
but I have this error
Error: self-signed certificate in certificate chain
at TLSSocket.onConnectSecure (node:_tls_wrap:1538:34)
at TLSSocket.emit (node:events:513:28)
at TLSSocket._finishInit (node:_tls_wrap:952:8)
at ssl.onhandshakedone (node:_tls_wrap:733:12) {
code: 'ESOCKET',
command: 'CONN'
}
I want send any email to gmail acount,
this code worked for me last week

could not setup dkim in nodemailer

I want to setup DKIM in nodemailer. Without DKIM, tls and "secure: true" my code works fine however, when I run code changed for DKIM it shows error:
Code:
var nodemailer = require('nodemailer');
var fs = require("fs");
const pr_key = fs.readFileSync("private.key", {encoding: "utf-8"})
const transporter = nodemailer.createTransport({
port: 465, // Postfix uses port 25
host: 'example.com',
secureConnection: false,
tls: {
ciphers:'SSLv3'
// rejectUnauthorized: false
},
secure: true,
dkim: {
domainName: "mail.example.com",
keySelector: "mail",
privateKey: pr_key
},
auth: {
user: "abc",
pass: "def"
},
});
var message = {
from: 'noreply#example.com',
to: 'pleasereply#example.com',
subject: 'Confirm Email',
text: 'Please confirm your email',
html: '<p>Please confirm your email</p>'
};
transporter.sendMail(message, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
});
Error Message:
[Error: 7336:error:1408F10B:SSL routines:ssl3_get_record:wrong version
number:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:332: ] {
library: 'SSL routines', function: 'ssl3_get_record', reason:
'wrong version number', code: 'ESOCKET', command: 'CONN' }
I have already configured TXT record for DKIM in DNS and SMTP server running on my server side is programed using library "smtp-server" module of nodejs.
What I tried:
I tried changing port to 25, 2525, 465 and 143
Tried every combination of host, domainname for domain "example.com" and tried keySelector "mail" and "#".
I tried commenting "secureConnection" and "tls: {}" and then changing to "secure: false" which results in other error:
Error: self signed certificate
at TLSSocket.onConnectSecure (node:_tls_wrap:1530:34)
at TLSSocket.emit (node:events:526:28)
at TLSSocket._finishInit (node:_tls_wrap:944:8)
at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:725:12) { code: 'ESOCKET', command: 'CONN' }
i tried to change "to:" property of message object to my gmail account just for testing but still got same message saying I got wrong version
Help me resolving this issue.

unable to send mail using nodemailer node.js api?

I have written code to send gmail using nodemailer node.js rest api. this is working fine for my local system server but when the same code i deployed on windows-2000 server, i am unable to send gmail and getting internal server error.
this is the code snippet i am using --
var nodemailer = require('nodemailer');
var stringify = require('json-stringify');
// create reusable transport method (opens pool of SMTP connections)
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
host: 'smtp.gmail.com',
port:587,
secure: false,
auth: {
user: 'user#gmail.com',
pass: 'user#123'
}
});
// setup e-mail data with unicode symbols
module.exports={
create:function(req,res){
var params=req.allParams();
var order_details=JSON.stringify(params);
//console.log("order-->"+order_details);
var mailOptions = {
from: 'user#gmail.com', // sender address
to: 'user1#gmail.com', // list of receivers
subject: "g-mail message ", // Subject line
html: order_details // html body
}
console.log("mailOptions"+JSON.stringify(mailOptions));
smtpTransport.sendMail(mailOptions, function(err, result){
console.log(result);
if(err){
return res.status(500).json("Error");
//return res.json("System Error")
}else{
return res.status(200).json("e-mail sent to customer");
}
smtpTransport.close();
});
}
}
when i am calling the api from local system server this is the response i am getting for conole.log(result)-->
{ accepted: [ 'user1#gmail.com' ],
rejected: [],
envelopeTime: 1094,
messageTime: 1124,
messageSize: 300,
response: '250 2.0.0 OK 1539452574 189-v6sm7035924pfe.121 - gsmtp',
envelope:
{ from: 'user#gmail.com',
to: [ 'user1#gmail.com' ] },
messageId: '<d84e7c1e-7158-5c6a-851d-a783e05be5ce#gmail.com>' }
but when i am trying to call the api from my windows-2000 server, for line console.log(result)--> i am getting "undefined".
So my question is whether i am getting this response from gmail.smtp server or gmail.smtp server is unreachable from the system.
I tried to ping gmail.smtp server from my windws-2000 server and there is 0% packet loss. so gmail.smtp is reachable from my server?
I also tried port 465,587,25 and secure- true, false option.
for Error log i am getting this-
{ Error: self signed certificate in certificate chain at TLSSocket.
<anonymous> (_tls_wrap.js:1105:38) at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7) at TLSSocket._finishInit (_tls_wrap.js:639:8) at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38) code: 'ECONNECTION', command: 'CONN' }}
Thnaks for your's valuable inputs on this issue.
var nodemailer = require('nodemailer');
var stringify = require('json-stringify');
// add this line before nodemailer.createTransport()
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
// create reusable transport method (opens pool of SMTP connections)
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
host: 'smtp.gmail.com',
port:587,
secure: false,
auth: {
user: 'user#gmail.com',
pass: 'user#123'
}
});
now it will work.

NodeJS - nodemailer using nodemailer-smtp-transport

I'm having an issue getting nodemailer to work with AuthSMTP (https://www.authsmtp.com/).
var nodemailer = require('nodemailer');
var transOptions = {
host: 'mail.authsmtp.com',
port: 25,
secure: false,
auth: {
user: '...',
pass: '...'
}
};
var transporter = nodemailer.createTransport(transOptions);
var mainOptions = {
from: 'whatever#domain.com',
to: 'something#domain.com',
subject: 'hello',
text: 'hello world!'
};
var callback = function(err, info){
if (err) { throw err }
console.log('sent');
}
transporter.sendMail(mainOptions, callback);
The error I'm getting back from AuthSMTP is:
"Your program, application or device is trying to use SSL with our
service but SSL is not enabled on your account."
I don't want to enable SSL, and I have the secure property in the transport options object set to false as the docs say: https://github.com/andris9/nodemailer-smtp-transport#usage.
Why would AuthSMTP say I'm using SSL when I'm setting nodemailer not to use SSL...?
you may try this
var transOptions = {
host: 'mail.authsmtp.com',
port: 25,
secure: false,
ignoreTLS: true
auth: {
user: '...',
pass: '...',
}
secure – if true the connection will use TLS when connecting to
server. If false (the default) then TLS is used if server supports the
STARTTLS extension.
In most cases set this value to true if you are connecting to port 465. For port 587 or 25 keep it false.
ignoreTLS – if this is true and secure is false then TLS is not used
even if the server supports STARTTLS extension.
so, params like this:
secure: false, ignoreTLS: true,
If you want to be safe, I think just to set you email, start IMAP/SMTP and POP/SMTP service as below:
and add your pass on your email settings:

Resources