Proxy support
Nodemailer can connect to an SMTP server through an outbound proxy. Out of the box it understands HTTP CONNECT proxies. For SOCKS4/4a/5 and any other schemes you can either:
- Install the community‑maintained
socks
package and let Nodemailer do the rest. - Provide your own proxy handler function.
Quick start
const nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
proxy: "http://proxy.example.test:3128", // ← HTTP proxy URL
});
Set the proxy
option to a valid URL string. Nodemailer parses the URL and decides how to tunnel the connection.
HTTP CONNECT proxies
HTTP proxies are fully supported without additional dependencies. Just pass their URL in the proxy
option:
const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
proxy: process.env.HTTP_PROXY, // or HTTPS_PROXY
});
SOCKS proxies
Support for SOCKS4, SOCKS4a and SOCKS5 is not bundled to keep Nodemailer lean. Install the socks
package in your project and register it with the transporter:
npm install socks --save
const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
proxy: "socks5://127.0.0.1:1080",
});
transporter.set("proxy_socks_module", require("socks"));
Supported URL protocols
Protocol | Proxy type |
---|---|
socks4: | SOCKS4 |
socks4a: | SOCKS4a |
socks5: | SOCKS5 |
socks: | SOCKS5 |
Local testing with SSH
Create an ad‑hoc SOCKS5 proxy that forwards all traffic through an SSH server:
ssh -N -D 0.0.0.0:1080 user@remote.host
Then set proxy: "socks5://localhost:1080"
.
Custom proxy handlers
Need a special authentication flow or a corporate proxy that speaks a proprietary protocol? Provide your own socket‑creation logic:
const transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
proxy: "myproxy://127.0.0.1:9999",
});
// Register a handler for the "myproxy:" URL scheme
transporter.set("proxy_handler_myproxy", (proxy, options, done) => {
const net = require("net");
console.log(`Proxy host=%s port=%s`, proxy.hostname, proxy.port);
const socket = net.connect(proxy.port, proxy.hostname, () => {
// ...hand‑shake with your proxy here...
// Return the socket to Nodemailer
done(null, { connection: socket });
});
});
If the proxy socket is already encrypted (e.g. you connected with tls.connect()
), set secured: true
so Nodemailer skips its own STARTTLS upgrade:
const tls = require("tls");
transporter.set("proxy_handler_myproxys", (proxy, options, done) => {
const socket = tls.connect(proxy.port, proxy.hostname, () => {
done(null, { connection: socket, secured: true });
});
});