Azure Function app cannot connect to on-premise SMTP server - azure

I'm using Azure Functions to email an Excel file. I use the npm package NodeMailer to send the email. When I try to send the email I get this error in the Function app logs:
Result: Failure Exception: connect ETIMEDOUT [SMTP server IP address]:50025 Stack: Error: connect ETIMEDOUT [SMTP server IP address]:50025 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)
Here is part of the app code that sends the email:
// Send the email
const transporter = nodemailer.createTransport({
host: "[SMTP server IP address]",
port: 50025,
secure: false,
ignoreTLS: true,
connectionTimeout: 180000,
debug: true
});
let mailOptions = { .... }
context.log('Sending email');
let info = await transporter.sendMail({mailOptions, function(error, info) {
if (error) {
context.log("sent mail error: " +error.message);
}
context.log(info.response);
}
});
The 'Sending email' line prints out in the logs so I know the code gets that far. However, the code doesn't print out 'sent email error ...'.
I'm using an on-premises SMTP server that is hosted on a private network. I whitelisted the Azure Function app's outbound IP addresses so the app can access the SMTP server. The request from the Function app is not hitting the firewall on the private network(ie none of the outbound IPs are hitting the firewall).
I've tried tweaking the nodemailer configuration, like increasing the connection timeout time and enabling TLS with no difference.
I don't know what else to try. Is there any way to solve this?

Related

Nodemailer with gmail get ETIMEDOUT error

I just deploy my nodejs api on Scaleway and when I try to send a mail from it, i get the following error, while it works like a charm locally :
command: 'CONN'
code: 'ETIMEDOUT',
at processTimers (internal/timers.js:500:7) {
at listOnTimeout (internal/timers.js:557:17)
at Timeout.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:229:22)
at SMTPConnection._onError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:760:20)
at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:19)
Error: Connection timeout
I'm using the following nodemailer transporter configuration :
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.MAIL_ADRESS,
pass: process.env.MAIL_PASSWORD
}
});
So I try to use the debug option from nodemailer transporter and I figure out that the resolved IP addresses are different.
Locally, the resolved IP address is the following :
DEBUG [pfKLJKySPY] Resolved smtp.gmail.com as 142.251.5.108 [cache miss]
While in production, the resolved IP is the following :
DEBUG [vgPMKJtFZT] Resolved smtp.gmail.com as 74.125.140.108 [cache miss]
Also, I checked that the container my docker image is running on is not blocking port 456 used by SMTP and no firewall is enabled.
Do you have any idea ?
I figured out that for the service to work in production, from my server, I had to configure the transport as follows:
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 587,
secure: false,
requireTLS: true,
logger: true,
debug: true,
auth: {
user: process.env.MAIL_ADRESS,
pass: process.env.MAIL_PASSWORD
},
});
Now i'm able to send mail from gmail through nodemailer from my server !
The port has to be configured on 587 and requireTLS has to be true. Now, the resolved IP address is the following :
DEBUG [PHpdgG5NDWI] Resolved smtp.gmail.com as 66.102.1.109 [cache miss]
And with this address I have no more timeout errors !!!

Nodemailer queryA EREFUSED localhost when using Firebase Cloud Functions

I'm trying to send email to admin account whenever there's a new Order created in Firebase Database. I'm using Cloud Functions and Nodemailer for this, but I got below error:
Error: queryA EREFUSED localhost
at QueryReqWrap.onresolve [as oncomplete] (dns.js:213:19)
And this is the code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const nodemailer = require('nodemailer');
admin.initializeApp();
/**
* Here we're using Gmail to send
*/
let transporter = nodemailer.createTransport({
service: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'myemail#gmail.com',
pass: 'mypass'
}
});
exports.sendMail = functions.database.ref('/Order/{orderId}').onCreate((snapshot, context) =>{
const dest = 'destination#gmail.com';
const mailOptions = {
from: 'Risal Fajar <noreply#bukakata.com>',
to: dest,
subject: 'I\'M A PICKLE!!!',
html: `<p style="font-size: 16px;">Pickle Riiiiiiiiiiiiiiiick!!</p>
<br />
<img src="https://images.prod.meredith.com/product/fc8754735c8a9b4aebb786278e7265a5/1538025388228/l/rick-and-morty-pickle-rick-sticker" />
`
};
// returning result
return transporter.sendMail(mailOptions).then(() => {
console.log('Mail sent to ', dest);
});
});
I don't know why the error showed localhost even though I've entered smtp.gmail.com
EDIT: I've added transport.verify() and this is the result
{ Error: queryA EREFUSED localhost
at QueryReqWrap.onresolve [as oncomplete] (dns.js:213:19)
errno: 'EREFUSED',
code: 'EDNS',
syscall: 'queryA',
hostname: 'localhost',
command: 'CONN' }
FIXED IT
I fixed it by changing the transporter configuration (change service name) to:
let transporter = nodemailer.createTransport({
service: 'gmail',
port: 465,
secure: true,
auth: {
user: 'myemail#gmail.com',
pass: 'mypass'
}
});
You can see the document: https://nodemailer.com/usage/using-gmail/
The gmail has another problem, but about this problem, same as I,
I got this Error:
Error: { Error: queryA EREFUSED smtp.163.com
at QueryReqWrap.onresolve [as oncomplete] (dns.js:199:19)
But when I try to run the same code at my mobile using termux, it works, maybe the free smtp services was so bad.
If the accepted answer doesn't work for you, you can also try to check your DNS configuration and ensure a nslookup on the hostname works well.
Run:
nslookup 'hostname'
If this results in error go to your network parameters and change your current DNS to 8.8.8.8 and try again to if the error persists.
.Or run directly:
nslookup 'hostname' 8.8.8.8
Additionally if the error happens only in your Cloud/ Docker container or VM ensure the nameserver configuration is correct.
Note: I had this error because work wifi's primary DNS wasn't resolving 'smtp.office3.com' but the secondary did and it seems nodemailer has no process in place to resolve the hostname using secondary DNS or entry in the OS host. You can read more about how to fix is error in the Nodemailer faq here.

I'm using Nodemailer (Node js) to send Email via Gmail but i'm getting error

I want to send email via Gmail or other email provider like office 365 using Nodemailer as my module Node.js.
I wanna ask also if there's a proxy or firewall setting to disable so that I can send email using gmail or office 365.
Or maybe there is something wrong with my code ?
const nodemailer = require("nodemailer");
const smtpTransport = require('nodemailer-smtp-transport');
function sendEmail(to, subject, html){
nodemailer.createTestAccount((err, account) => {
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'philip#gmail.com',
pass: 'sercretpass'
}
});
let mailOptions = {
from: '"Admin" ',
to: to,
subject: subject,
html: html
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log('Error', error);
}
else{
console.log('Success', info);
}
});
});
}
module.exports.sendEmail = sendEmail;
MY ERROR :
Error { Error: connect ETIMEDOUT 74.125.203.108:465
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1121:14)
errno: 'ETIMEDOUT',
code: 'ECONNECTION',
syscall: 'connect',
address: '74.125.203.108',
port: 465,
command: 'CONN' }
Are you able to telnet to smtp.gmail.com from the machine on port 465 ?
Also try with Port 587, with 587, you should see some other error as it works on STARTTLS.
TESTED WORKING ON GMAIL 2022 March
STEP 1- Enable the "Less Secure App Access" from Security Page of the Google Account
. Google says It's no longer supported but turn On
the feature anyway.
STEP 2-Turn Off the google CAPTCHA.
STTEP 3- Configuring Port And HOST
**Do not use google as the host.Refer the following.
host: "smtp.gmail.com"
if port 587 is not working, try port 465. Make sure to make secure:true for port 465
let transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 465,
secure: true,
auth: {
user: 'youremail#gmail.com',
pass: 'password',
},
// enable below only if u are running on local host
tls: { rejectUnauthorized: true }
});
I always used nodemailer for sending emails, suddenly I started having the above error. So I thought what was new on the computer and found that the antivirus was causing the problem. So disabling the antivirus and windows firewall is a good start to solve the problem.

nodemailer got EACCES while using SMTP

I'm trying to use nodemailer send the email. Below is the sample code.
const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
host: '10.88.88.88',
port: 25,
secureConnection: false,
auth: {
user: 'user',
pass: 'pwd',
}
});
let mailOptions = {
from: 'sender#test.com', // sender address
to: 'receiver#test.com', // list of receivers
subject: 'Hello', // Subject line
html: '<b>Hello world?</b>' // html body
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
});
However I got the error below. It seems I could not access the server. The server is using smtp relay of IIS. What is the exact user/pass in auth here? The server window user account who has the right to access the smtp service? If I change user/pass to mailaddress/password, I got the same error info. If I remove auth, I still got the same error info. Or it is proxy issue?
{ Error: connect EACCES 10.88.88.88:25
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1113:14)
errno: 'EACCES',
code: 'ECONNECTION',
syscall: 'connect',
address: '10.88.88.88,
port: 25,
command: 'CONN' }
The servers infra is like below:
node server <--> SMTP Relay IIS (10.88.88.88) <--> Mailserver
Please check using port 587 instead of 25.

How to send mail using nodemailer in aws server

I am using nodemailer in node.js express app. I am sending email perfectly using nodemailer from my gmail. But the problem is I don't want to mention my gmail and smtp it throws smtp error when tried to send from aws server. so now I want make default like (ex: noreply#mail.com) so it should send from my localhost andfrom aws server also f I host in aws server.
can you please tell me how can I do it.
I tried this way
aws.config.loadFromPath('aws-config.json');
const transporter = nodemailer.createTransport({
SES: new aws.SES({
apiVersion: '2017-12-01'
})
});
// setup email data with unicode symbols
const mailOptions = {
from: 'noreply#abc.com',
to: req.body.email,
subject: 'Message',
text: 'I hope this message gets sent!',
};
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log('Error: ', err);
}
console.log('info: ', info);
// console.log(info.messageId);
});
I get this error:
Error: { Error: connect ECONNREFUSED 127.0.0.1:25
at Object.exports._errnoException (util.js:1020:11)
at exports._exceptionWithHostPort (util.js:1043:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 25 }
info: undefined
You can use the Mailgun mail server to send your emails they have a free plan. This how you can send a email with nodemail and mailgun.

Resources