Nginx Reverse Proxy
Use Nginx in front of KumoMTA when you want TLS termination, bearer-token authentication, request size limits, and a simple deny-by-default public surface.
The recommended shape is:
public HTTPS :443
Nginx validates bearer token
Nginx proxies /api/inject/v1 to 127.0.0.1:8000/api/inject/v1
Nginx proxies /metrics to 127.0.0.1:8000/metrics
Nginx returns 404 for everything elseWhere it lives
Install on the KumoMTA host:
/etc/nginx/conf.d/mta.yourdomain.com.confThe TLS certificate should cover mta.yourdomain.com.
Sanitized server shape
map $http_authorization $auth_ok {
default 0;
"Bearer <PING8_INJECTION_TOKEN>" 1;
}
server {
listen 443 ssl http2;
server_name mta.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/mta.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mta.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
add_header Strict-Transport-Security "max-age=31536000" always;
client_max_body_size 25m;
location = /api/inject/v1 {
if ($auth_ok = 0) {
return 401 '{"error":"unauthorized"}\n';
}
proxy_pass http://127.0.0.1:8000/api/inject/v1;
proxy_set_header Host $host;
proxy_set_header Authorization "";
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
}
location = /metrics {
if ($auth_ok = 0) {
return 401;
}
proxy_pass http://127.0.0.1:8000/metrics;
proxy_set_header Authorization "";
}
location / {
return 404;
}
}
server {
listen 80;
server_name mta.yourdomain.com;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}Why Nginx handles auth
KumoMTA can run an HTTP listener directly, but a reverse proxy gives you a smaller public interface:
- TLS certificates live in one familiar layer.
- Bearer-token comparison happens before KumoMTA sees the request.
- The KumoMTA listener can bind to
127.0.0.1. /metricscan share the same authentication model.- Unknown paths are denied by default.
KumoMTA's official HTTP listener docs explain the listener options and trusted-host behavior: KumoMTA HTTP listeners (opens in a new tab).
PING8 fields
Use these values in the PING8 KumoMTA connection screen:
| PING8 field | Value |
|---|---|
| Base URL | https://mta.yourdomain.com |
| Injection path | /api/inject/v1 |
| Metrics URL | https://mta.yourdomain.com/metrics |
| Auth mode | Bearer token |
| Auth secret | <PING8_INJECTION_TOKEN> |
| TLS verification | Enabled |
Security checks
https://mta.yourdomain.com/api/inject/v1without the bearer token returns401.https://mta.yourdomain.com/metricswithout the bearer token returns401.- Unknown paths return
404. - KumoMTA does not listen publicly on port
8000. - Port
80is used only for ACME and HTTP-to-HTTPS redirect. - The injection token is not present in shell history or source control.
Common mistakes
- Exposing KumoMTA's HTTP listener directly on
0.0.0.0. - Forgetting to clear the upstream
Authorizationheader after Nginx validates it. - Using a TLS certificate for
mail.yourdomain.comwhen the endpoint ismta.yourdomain.com. - Setting
client_max_body_sizetoo low for real messages. - Making
/metricspublic without authentication.