Connection settings
- Host
- your-kumo-hostname.example.com
- Port
- 587
- Security
- STARTTLS
KumoMTA is a high-performance, Lua-configured mail transfer agent designed for large-scale sending. Unlike hosted providers (Gmail, SendGrid), there is no fixed SMTP hostname — you define your own ESMTP listeners in the KumoMTA init handler using kumo.start_esmtp_listener. This means the host and port you test against depend entirely on your deployment.
Recommended settings
- Host: your server's public hostname or IP (must match the TLS certificate subject/SAN)
- Port: 587 (STARTTLS) for authenticated submission, or 25 for trusted-network relay
- Security: STARTTLS (KumoMTA requires encryption before AUTH)
- Auth method: PLAIN (KumoMTA does not support AUTH LOGIN)
- Username/password: whatever your
smtp_server_auth_plainhandler validates
Configuring a submission listener
In your KumoMTA init handler (typically init.lua), add a listener on port 587:
kumo.start_esmtp_listener {
listen = '0.0.0.0:587',
hostname = 'mail.example.com',
tls_certificate = '/etc/kumomta/certs/mail.example.com.pem',
tls_private_key = '/etc/kumomta/certs/mail.example.com.key',
}
The hostname value is used in the EHLO greeting and should match your DNS and certificate. The TLS certificate and key files enable STARTTLS — clients can then upgrade the connection after the EHLO handshake.
Implementing AUTH PLAIN
KumoMTA authenticates clients through the smtp_server_auth_plain event. This is a Lua function that receives the username and password from the AUTH PLAIN exchange and returns true or false:
kumo.on('smtp_server_auth_plain', function(authz, authc, password)
-- authz is usually empty; authc is the username
if authc == '[email protected]' and password == 'correct-secret' then
return true
end
return false
end)
For production, validate against a secrets store (HashiCorp Vault, environment variables, or a local password file) rather than hardcoding credentials. KumoMTA's documentation covers Vault-backed authentication patterns.
Key points:
- AUTH is only accepted after STARTTLS succeeds. Clients that try AUTH on an unencrypted session get a
530 Must issue a STARTTLS command firstresponse. - Only AUTH PLAIN is supported — AUTH LOGIN will fail. Set your SMTP client (or SMTP Tester) to use PLAIN explicitly if Auto-detect does not work.
Testing with SMTP Tester
- Set host to your KumoMTA server's public hostname or IP.
- Port 587, security STARTTLS.
- Auth method: set to PLAIN (Auto may also work if the server advertises only PLAIN).
- Enter the username and password your
smtp_server_auth_plainhandler expects. - From address: whatever your server allows (check relay policy).
- Click Run. The live transcript shows EHLO → STARTTLS → AUTH PLAIN → 235.
A 235 AUTH OK confirms authentication. If you send a message, a 250 response with a queue ID means KumoMTA accepted the message for delivery.
Common errors
535 "Authentication failed"
- Credentials do not match what your Lua handler expects. Check case sensitivity, trailing whitespace, and that the correct listener is being reached.
- If you have multiple listeners (e.g., port 25 for relay, port 587 for submission), each can have its own auth logic. Confirm you are connecting to the listener that runs
smtp_server_auth_plain.
530 "Must issue a STARTTLS command first"
KumoMTA rejects AUTH on an unencrypted session. Your client tried to authenticate before upgrading to TLS. In SMTP Tester, ensure security is set to STARTTLS (not "none"). If using a custom client, call STARTTLS after EHLO and before AUTH.
550 "Relaying denied" / no relay permission
After authentication, the server still checks relay policy. If you get a relay error despite 235 AUTH OK, your KumoMTA configuration may not be granting relay rights to authenticated sessions. Ensure your source or listener config includes logic like:
-- In a relay_message_generated or similar hook:
-- Grant relay to authenticated sessions
if msg:get_meta('authc') then
-- allow
end
Or use relay_hosts to whitelist the IP if auth is not required (port 25 trusted injection).
Connection timeout
- Verify the listener is bound to an externally reachable address (not
127.0.0.1). - Check firewall rules: ports 587 and 25 must be open inbound.
- Confirm KumoMTA is running (
systemctl status kumomtaor check logs).
Port 25 relay without auth
Many KumoMTA deployments accept unauthenticated injection from trusted application servers on port 25 using relay_hosts:
kumo.start_esmtp_listener {
listen = '0.0.0.0:25',
hostname = 'mail.example.com',
relay_hosts = { '10.0.0.0/8', '192.168.1.0/24' },
}
In this mode, connections from listed CIDRs can relay without AUTH. Test from the allowed network by setting security to "none" (or STARTTLS if TLS certs are configured) and leaving credentials empty. The transcript should show a 250 response without any AUTH exchange.
TLS certificate setup
KumoMTA STARTTLS requires a valid certificate. For Let's Encrypt:
- Obtain a cert with certbot or acme.sh for your mail hostname.
- Point
tls_certificateandtls_private_keyat the fullchain and privkey files. - Restart KumoMTA after renewal.
SMTP Tester's TLS diagnostics panel shows the negotiated protocol, cipher, certificate subject, issuer, and expiry — useful for confirming your cert is correctly installed without needing openssl s_client.
Security notes
- Do not expose port 587 to the internet without implementing
smtp_server_auth_plain. Without it, any client can inject mail. - Use strong, unique passwords for SMTP injection credentials. Rotate them if compromised.
- SMTP Tester redacts all credentials from the live transcript, making it safe to share the output in a support ticket or team chat.
- Consider rate-limiting authenticated injection using KumoMTA's traffic shaping to protect against credential compromise.