NodeMailServer
Deployment

Security

Keep secrets out of git, lock down the ports and protect your DKIM keys.

Keep secrets out of git

The root .gitignore excludes these files. Commit only the .example versions.

FileContains
server/.envHostnames, TLS paths, DKIM and PGP keys.
outbound/.envKumoMTA settings and keys for the DKIM and webhook services.
outbound/policy/users.luaSMTP usernames and passwords, in plain text.
relay/.envRelay settings and the key for the DKIM service.
relay/policy/users.luaRelay passwords and webhook secrets, in plain text.
server/records.jsonGenerated DNS records and the DKIM private key.
*.key, *.pem, outbound/dkim/, relay/dkim/, relay/tls/Private keys and certificates.
server/spool/Queued mail, bounce tracking records and the suppression list.

If a secret was ever committed, treat it as exposed: rotate it, not just delete the file.

Open only the ports you need

PortOpen to the internet?
25Yes, to receive mail.
587Yes, if clients outside your network send through the server.
2587Yes, if you run the relay. Every message needs a login. Use a real TLS certificate.
2525No, unless a forwarder on another host must reach it. Bounces for BOUNCE_DOMAIN already arrive on port 25. Set BOUNCE_SMTP_PORT=0 to turn it off.
8025No. The bounce HTTP server. It needs BOUNCE_WEBHOOK_TOKEN. Publish it only to the KumoMTA network, and put TLS in front of it if it crosses hosts.
8080No, unless your apps are outside the network. The JSON send API can send mail with any From address, and its token is the only protection. Use a TLS reverse proxy.
2580No. The Go MTA. Only the Node server calls it.
143Only if you run IMAP. Prefer TLS (993).
8000No. KumoMTA's HTTP API can inject mail. It listens on 127.0.0.1 inside the container, and the compose file does not publish it.
8008No. The KumoMTA traffic-shaping daemon, if you run it.
6379No. Redis is not published in the compose file.

Protect your sending reputation

  • Require authentication on every submission port, and use strong passwords.
  • Use long random values for MAIL_API_TOKEN, BOUNCE_WEBHOOK_TOKEN and GO_MTA_TOKEN. The JSON API and the bounce HTTP server do not start without their token. The Go MTA starts without one and only logs a warning, so always set it.
  • Keep OUTBOUND_RELAY_TLS at verify. Use none only on a private network you control.
  • Keep bounces.suppression.enabled on, so the server stops sending to addresses that hard-bounce.
  • Do not run an open relay. Check it with an external open-relay test after any change to relay settings.
  • Keep rate limits on (MAX_EMAILS_PER_MINUTE, and the per-domain rates in KumoMTA).
  • Watch your DMARC reports, and tighten the policy as they come back clean.
  • Check your IP address against blacklists regularly.

DKIM keys

  • Generate one key per domain, and rotate them from time to time by publishing a new selector first.
  • Do not email private keys or paste them into chats.
  • Store the DKIM private key in DKIM_PRIVATE_KEY, a mounted key file, or a secrets service. Never put it in the repository.

On this page