Nodemailer is able to use proxies for connecting to SMTP servers. HTTP proxy support is built in, Socks proxy support can be enabled by providing socks module to Nodemailer, other proxies need custom handling.
To enable proxying, define a proxy option for the transporter.
Set HTTP proxy url for the proxy option. That’s it, everything required to handle it is built into Nodemailer.
let transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 465,
secure: true,
proxy: 'http://proxy-host:1234'
});
Or if you want to use some environment defined variable like http_proxy:
let transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 465,
secure: true,
proxy: process.env.http_proxy
});
Set Socks proxy url for the proxy option. Additionally you need to provide the socks module for the transporter as it is not bundled with Nodemailer. Both versions 1.x.x and 2.x.x of the socks module are supported
Possible protocol values for the SOCKS proxy:
let transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 465,
secure: true,
proxy: 'socks5://socks-host:1234'
});
// enable support for socks URLs
transporter.set('proxy_socks_module', require('socks'));
For testing you can use ssh to create a SOCKS5 proxy. The following command connects to your remote server and sets up a proxy on port 1080 that routes connections through that server.
ssh -N -D 0.0.0.0:1080 username@remote.host`
proxy url for that server would be socks5://localhost:1080
Additionally you can create your own proxy handler. To do this you would need to register a protocol handler callback with the name proxy_handler_{protocol} where {protocol} would be the protocol from proxy URL. If the URL looks like ‘yyy://localhost’ then you would need to set callback for proxy_handler_yyy.
transporter.set('proxy_handler_myproxy', handler);
Where
let transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 465,
secure: true,
proxy: 'myproxy://localhost:1234'
});
// enable support for socks URLs
transporter.set('proxy_handler_myproxy', (proxy, options, callback) => {
console.log('Proxy host=% port=%', proxy.hostname, proxy.port);
let socket = require('net').connect(options.port, options.host, () => {
callback(null, {
connection: socket
});
});
});
If your proxy uses an encrypted connection then you can mark the proxied socket to be already secure. This prevents Nodemailer from upgrading the provided connection using TLS.
let transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 465,
secure: true,
proxy: 'myproxys://localhost:1234'
});
// enable support for socks URLs
transporter.set('proxy_handler_myproxys', (proxy, options, callback) => {
console.log('Proxy host=% port=%', proxy.hostname, proxy.port);
let socket = require('tls').connect(options.port, options.host, () => {
callback(null, {
connection: socket,
secured: true
});
});
});