Nodemailer use specific outboung port - node.js

I'm having issues sending email from nodemailer due to the company firewall.
I'm using the default configuration of nodemailer but I get a timeout error, and seems that the problem is due to the server/firewall is configured only allow outbound traffic to go through port 587.
Is there any way to configure nodemailer to use this specific outgoing port and not a random one?

The destination port defaults to 587. If secure: true is set, 465.
nodemailer.createTransport({ host: 'mx', port: 465, secure: true })
TCP source ports are chosen randomly by the host, but that's nothing to do with nodemailer.

Related

Nodemailer: My frontend website can't send emails through node mailer from a different IP address

My frontend portfolio has an emailing option which sends a post req to nodemailer in the backend.
My portfolio is already deployed in firebase and I'm currently running the backend on the localhost server.
I face no issues when I send emails on my laptop, same IP address, while I receive an error whenever I try sending emails on a different device.
I have searched around for a day now and I can't find an available solution. Any idea on how I can solve this issue?
My nodemailer configuration:
const transporter = nodemailer.createTransport(smtpTransport({
name: 'domainname',
host: 'domainname.com',
port: 443,
secure: true,
service: 'gmail',
auth: {
user: '*****#gmail.com',
pass: '******' //Google's less secure apps option enabled.
},
tls: {
// do not fail on invalid certs
rejectUnauthorized: false,
}
}))
The following error is logged into the console when sending email fails:
POST http://localhost:4000/api/email/ net::ERR_CONNECTION_REFUSED
TypeError: Failed to fetch
at main.1ec56b92.js:2:347746
at c (main.1ec56b92.js:2:168378)
at Generator._invoke (main.1ec56b92.js:2:168166)
at Generator.next (main.1ec56b92.js:2:168807)
at Ft (main.1ec56b92.js:2:332714)
at i (main.1ec56b92.js:2:347506)
at main.1ec56b92.js:2:347567
at new Promise (<anonymous>)
at main.1ec56b92.js:2:347446
at main.1ec56b92.js:2:348157
Thank you
As Derpirscher pointed out, the host of the backend was hardcoded as localhost:4000 hence why it worked on my laptop and failed on my phone.
The solution for me was to deploy the code to a server -like Heroku- and use its address to connect to the nodemailer API, eg: https://project.herokuapp.com/api/email instead of https://localhost:4000/api/email

error 550 Domain not allowed in header from

I am trying to get namecheap c-panel email hooked up with my nodemailer server instance but I am unable to find how to do that.
here is my nodemailer code
let transporter = nodemailer.createTransport({
host: "premium174.web-hosting.com",
port: 465,
secure: true,
auth: {
user: username,
pass: password
},
connectionTimeout: 30000
});
from part in the sendMail method contains the email I am logging in to
I am able to establish a connection the server using these details but I can't send any email, AT ALL. anytime I try to send it the error I get is
code: 'EENVELOPE',
response: '550-"Your IP: my-ip-here : Your domain domain-here is not allowed in header\n' +
'550 From"',
responseCode: 550,
command: 'RCPT TO'
the send mail part is all correct and it works with the other emails I have but this one just would not work
You can visit Email Routing from cPanel and choose "Local Mail Exchanger" under Configure Email Routing.
Ok so what I had to do was to change namecheap email routing to local and it worked :D

Using Redbird to reverse proxy for HTTPS site and its sub-domains on node.js server

I'm trying to understand how to use redbird as a reverse proxy (seems less work than nginx for a legacy node server but maybe I'm wrong) and I'm failing to understand their example in the readme file, can't find the answer elsewhere: https://github.com/OptimalBits/redbird
My setup: I have a node server running under "example.com" and I need to create a sub-domain (api.example.com). Right now the legacy app installed on the server redirects all trafic from port 80 to 443 and has a SSL cert installed (not LetsEncrypt as I said this is legacy and probably before getting a cert was free). This certificate only covers "example.com" and "www.example.com".
After a few hours (ok, days) of trying to find the best way of adding a sub-domain (to be served through HTTPS too), this is how I thought it would work:
Add the A-record for my sub-domain (api.example.com);
Get a certificate for api.example.com from Let's Encrypt;
Change the legacy app so it doesn't listen to port 80 (for the
redirect)
Change the legacy app so it listens to 7000 instead of 443
Put my new app online and make it listen to 7001
Setup Redbird to listen to 80 and redirect to 443
Setup Redbird to register "example.com" and redirect requests to
7000 (with the existing cert)
Setup Redbird to register "api.example.com" and redirect requests to
7001 (with my new cert)
Am I on the right path?
Note: I know redbird has a feature for getting ssl certificates automatically but since I have to use the legacy certificate for the main domain (example.com) I figured I couldn't use the automagical way.
I'm able to go through the list down to #6 but then the redbird documentation for HTTPS is confusing to me. Here's their example:
var redbird = new require('redbird')({
port: 8080, //??? => so this is the entry point? Why not 443 since we want only HTTPS?
// Specify filenames to default SSL certificates (in case SNI is not supported by the
// user's browser)
ssl: {
port: 8443, //??? => what is this port for? Is it our default HTTPS port (in my case 443?)
key: "certs/dev-key.pem",
cert: "certs/dev-cert.pem",
}
});
// Since we will only have one https host, we dont need to specify additional certificates.
redbird.register('localhost', 'http://localhost:8082', {ssl: true}); //??? => this is the port my request will be forwarded too... right?
What I think I gather from this is : traffic coming to localhost through port 8080 is redirected to port 8082. Right? But then what is 8443 for?
Barely understanding what's going on I tried the below:
var redbird = new require('redbird')({
port: 80,
secure: false,
// Specify filenames to default SSL certificates (in case SNI is not supported by the
// user's browser)
ssl: {
port: 443,
key: "/etc/cert/example.key",
cert: "/etc/cert/example.crt",
}
});
// Since we will only have one https host, we dont need to specify additional certificates.
redbird.register('example.com', 'http://localhost:7000', {ssl: true});
redbird.register('api.example.com', 'http://localhost:7001', {
ssl: {
key: "/etc/letsencrypt/api.example.key",
cert: "/etc/letsencrypt/api.example.crt"
}
});
Why don't we have HTTPS instead of HTTP in the second argument of redbird.register() ?
Needless to say the above does not work and when I open example.com from my browser or api.example.com, it responds : "ECONNRESET".
UPDATE: I was serving both node apps with HTTPS (on 7000 and 7001), and tried serving them to the proxy as HTTP. I got the proxy correctly forwarding the requests to the corresponding ports, BUT only the main (legacy) app (at "example.com") has the right SSL certificate. When I open "api.example.com" I get the warning saying the site is not secure...
Makes me wonder: is it ok to have a main domain with a certificate from say GoDaddy and a subdomain from LetsEncrypt? Is that the reason it's not working?
When I click in chrome at the "not secure" warning (when looking at api.example.com), it says Cetificate (invaild) and it show the certificate information for the main domain (example.com) instead of the certificat I configured for api.example.com...
UPDATE2:
So I tried with getting a new certificate for my domain and all its subdomains (using the wildcard *.example.com and also noteworthy: *.example.com does not include example.com so it needs to be added manually).
With the all-encapsulating certificate, the below code works but it a lot slower than without Redbird as a reverse proxy (I was expecting a difference but not that much, here we're talking about over 3 seconds difference - and the site being legacy and not optimized, those 3 seconds are on top of an excruciating 8 sec+ with cache disabled).
var redbird = new require('redbird')({
port: 80,
secure: true,
ssl: {
port: 443,
key: "/etc/letsencrypt/live/example.com/privkey.pem",
cert: "/etc/letsencrypt/live/example.com/cert.pem",
}
});
redbird.register('example.com', 'http://localhost:7000', {ssl: true});
redbird.register('www.example.com', 'http://localhost:7000', {ssl: true});
redbird.register('api.example.com', 'http://localhost:7001', {ssl: true});
Here are a few things I can deduce from this experience and it might help others:
the port specified where 80 is in the above is the entry port for HTTP. If you specify in the same object the ssl part, redbird will redirect all HTTP traffic to HTTPS (I couldn't find that in the documentation).
the port specified where 443 is in the above is the entry port for HTTPS. You still have done no redirection at this point, just kind of explaining to redbrid what's what. I think.
the cert in the ssl object should be the file cert.pem not fullchain.pem (this isn't necessarily a redbird issue but just one of those things that could trip people up).
the port where 7000 and 7001 are above are the ports where you want to redirect your traffic to (kind of obvious but documentation should have obvious stuff).
Finally, what the object {ssl: true} does is tell redbird to use the default SSL config above, an alternative would be to specify another config per registered domain but I was not able to make that work (might be because I was only dealing with sub-domains and this feature might only be for non-sub-domains... if that's the case it would have been good to have in the docs).
So this is disappointing because (by order of most important to least):
There seems to be a huge hit on perf: am I missing a "prod" parameter that could improve this?
It seems the only way this works is by having all my node apps/servers as http (not https) and pointing to their ports (7000 and 7001) and only have the proxy server be https. It's not too troubling since no one seems to be able to get to the ports 7000 and 7001 directly, but I'm thinking 7000 and 7001 could have been https too. Can they be? Or does it not make sense to have these apps in https if the proxy can handle that?
I was not able to keep the old (and expensive) ssl certificate that is not yet expired. Or is there a way that I didn't find?
I bet this is gotten so long no one will ever read this...
I hope this helps;
use redbirds built in ssl option which delivers certificates automatically
example:
const proxy = require('redbird')({
port: 80,
xfwd: true, // http port is needed for LetsEncrypt challenge during request / renewal. Also enables automatic http->https redirection for registered https routes.
letsencrypt: {
path: __dirname + '/certs',
port: 9999 // redbird gets your certificates throug this port
},
ssl: {
http2: true,
port: 443, // SSL port used to serve registered https routes with LetsEncrypt certificate.
}
});
let connectionInfo = {
ssl: {
letsencrypt: {
email: 'YOUR EMAIL',
production: true,
}
}
};
proxy.register("subdomain.yourdomain.com", "http://your.ip.goes.here:84", connectionInfo);
proxy.register("yourdomain.com", "http://your.ip.goes.here:83", connectionInfo);
run your subdomain server on port 84 and your main server on port 83;

Nodemailer not working on Amazon EC2 instance

I am EC2 instance up and running , I wanted to integrate nodemailer in my application. Following the https://www.npmjs.com/package/nodemailer I was able to send email from my localhost. When the same code I integrated on EC2 instance I am getting Invalid login error . Sometime gmail blocks login from other application and send confirm mail to the inbox. I didnt get any such mail also. Do I need to enable some port on EC2 instance or I can use nodemailer at all on EC2 instance. Please suggest
Gmail is not a production SMTP service. Configure nodemailer to send mail from a production mailer, such as AWS Simple Email Service. Like gmail, SES is a "well-known service" in nodemailer. There's a great example of using SES in the nodemailer README.
No need to enable aws ses service
Open port : 465 on aws(e2c) instance in outbound section.
Test if port really opened : with nmap command nmap 14.247.74.33.
Note : do not proceed until you see open ports like
Starting Nmap 5.21 ( http://nmap.org ) at 2012-08-15 19:01 IST
Nmap scan report for 14.247.74.33
Host is up (0.058s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
23/tcp open telnet
80/tcp open http
465 open
Simple nodemailer configuration works
const transporter = nodemailer.createTransport({
service: 'gmail',
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: EMAIL_ID,
pass: EMAIL_PASSOWRD,
},
});
Full example code

How to configure mqtt.js to connect to iot.eclipse.org over websockets

Edit: My issue is now this. I can connect to iot.eclipse.org using http://www.hivemq.com/demos/websocket-client, using port 80. When I connect via a browsified mqtt.js client I am getting the following error :
WebSocket connection to 'ws://iot.eclipse.org/' failed: Error during
WebSocket handshake: Unexpected response code: 200
I've tried ports 8080, 8000, 1883 and 80, without any luck. Any suggestions?
------------ Original question below -----------
I want to connect with a mqtt broker using mqtt over websockets. My client will need to run in a browser.
TO achieve this I am using mqtt.js library and am following these instructions.
Everything works when running against the public broker at broker.mqttdashboard.com. However when I connect to the public brokers at iot.eclipse.org and test.mosquitto.org I get HTTP errors.
I think the problem is incorrect configuration of the client when running against the second two brokers, but I'm struggling to find any help.
Heres the configuration, is there anyone out there who can help me?
// Works fine
var options = {
host: "broker.mqttdashboard.com",
port: 8000
};
// Doesn't work
/*var options = {
host: "m2m.eclipse.org",
protocolId: 'MQIsdp',
protocolVersion: 3
};*/
// Doesn't work
/*var options = {
host: "test.mosquitto.org",
protocolId: 'mosqOtti',
protocolVersion: 3
};*/
var client = mqtt.connect(options);
Let me know if theres any more information you need!
Mark
Both test.mosquitto.org and iot.eclipse.org are both websockets enabled (for a long time now actually).
You already have got test.mosquitto.org working - the key there is using port 8080.
The current iot.eclipse.org configuration expects the connection url to be ws://iot.eclipse.org/mqtt.
I don't think m2m.eclipse.org / iot.eclipse.org or test.mosquitto.org have websockets enabled.
broker.mqttdashboard.com runs a HiveMQ underneath which has native websockets enabled.
So in short, I don't think this is a configuration problem on your side. To make sure, you can check this web application and see if the other brokers work with that: http://www.hivemq.com/demos/websocket-client/

Resources