Set up your SMTP Wizard
A one-click deployment tool that turns any fresh VPS into a high-deliverability outbound SMTP server — with DKIM/SPF/DMARC, a dashboard, and automated crypto payments for access. This guide covers every SMTP installation and configuration step.
Overview
The SMTP Wizard is a PHP-based deployment tool that runs on your cPanel hosting. You enter a target server's IP and root password, pick a domain, and it remotely installs and configures a complete SMTP engine over SSH — then hands you the exact DNS records to publish.
The wizard also includes a built-in payment system (crypto via Cryptomus), an admin panel, and a support chat — all managed from your cPanel admin area without any separate server or process to run.
Requirements
For the cPanel wizard (PHP)
- cPanel/PHP hosting running PHP 8.1+
- The
ssh2PHP extension or the bundledphpseclibfallback (already included inapi/vendor/— no action needed if ssh2 is missing) curlenabled (for the Cloudflare DNS auto-setup feature)- A Cryptomus merchant account for crypto payments (configured once in the admin panel)
For the target mail server
- A fresh VPS with a public IPv4 address and root SSH access
- Supported OS: AlmaLinux, Rocky, CentOS, RHEL, Fedora, Ubuntu, or Debian
- Ports
25,587,8000, and80open (the wizard configures the firewall for you) - Port 25 not blocked by your provider (many block it by default — request unblocking)
Configure the wizard
On the wizard's Mail Identity Configuration screen, fill in:
| Field | What to enter |
|---|---|
| Server IP | The public IPv4 of the VPS you're deploying to. |
| SSH port / password | Root SSH port (usually 22) and the root password. |
| Domain | Your sending domain, e.g. example.com. |
| Hostname (FQDN) | The mail hostname, e.g. mail.example.com. Should match the PTR/rDNS. |
| Public IP (SPF/PTR) | The IP that appears in SPF and reverse DNS — normally the same as the server IP. |
| DMARC report email | Optional. Where aggregate DMARC reports are sent. |
| DKIM selector | mail, dkim, or any valid selector label. |
| Stack components | Toggle the core engine, the Admin UI dashboard, and optional Prometheus/Grafana monitoring. |
Run deployment
Click Start Deployment. The wizard streams a live log as it works through these stages on your VPS:
- TCP + SSH pre-flight checks and OS detection
- Fixes server DNS resolution if broken, sets the hostname and
/etc/hosts - Configures the firewall and removes any competing MTAs (Postfix/Sendmail/Exim) holding ports 25/587
- Installs the SMTP engine, generates a 2048-bit DKIM key, and writes the policy config
- Optionally installs Prometheus, Grafana, and the Admin UI dashboard
- Runs a final health check and verifies the SMTP banner
When it finishes, the wizard shows your DNS records and access URLs. Deployment typically takes 3–8 minutes depending on the server.
DNS records
After deployment, publish these records at your DNS provider. The wizard generates them with your real values — the table below shows what each one is for.
| Type | Host | Purpose |
|---|---|---|
A | @ and mail | Point your domain and mail host at the server's IPv4. |
AAAA if IPv6 | @ and mail | Only added when the server has a global IPv6 address. |
MX | @ | Routes mail for the domain to mail.example.com (priority 10). |
TXT (SPF) | @ | Authorizes your server's IP(s) to send for the domain. |
TXT (DKIM) | selector._domainkey | Publishes the DKIM public key so receivers can verify signatures. |
TXT (DMARC) | _dmarc | Policy + reporting address. Starts at p=none. |
PTR (rDNS) | your IP | Set this in your VPS/hosting panel, not your DNS registrar. Must match the hostname. |
Cloudflare auto-setup
If your domain is on Cloudflare, the wizard can publish every record (except PTR) for you. There are two ways:
- 1-click Connect (recommended) — click Connect Cloudflare. If you're signed into Cloudflare in your browser, you'll see a consent screen asking to allow DNS changes. Click Allow and the wizard locates your zone and fixes the DNS automatically — no token copying.
- API token — paste a scoped token (Zone → DNS → Edit). Always available as a fallback.
Enabling 1-click Connect (one-time setup)
The 1-click flow uses Cloudflare OAuth, so you register an OAuth client once:
- Go to Cloudflare dashboard → Manage Account → OAuth clients → Create client.
- Set Grant type = Authorization Code, Token auth = Client Secret, and Redirect URL =
https://YOUR_DOMAIN/installer/api/cf_oauth_callback.php. - Select the DNS edit and Zone read scopes, then create the client and copy the Client ID + Client Secret.
- Edit
installer/api/cf_config.phpand fill inclient_id,client_secret, andredirect_uri.
cf_config.php is left blank, the button hides and the API-token method is used instead.https://api.cloudflare.com/client/v4/oauth/scopes and update scopes in cf_config.php.mail.example.com.IPv4 & IPv6 servers
The wizard supports both IPv4-only and dual-stack (IPv4 + IPv6) servers automatically:
- IPv4-only servers — you get A, MX, SPF (
ip4:only), DKIM, DMARC, and an IPv4 PTR. No AAAA or IPv6 entries are generated, so there's nothing extra to clean up. - Dual-stack servers — if a globally routable IPv6 address is detected, the wizard additionally publishes AAAA records and adds an
ip6:term to SPF, plus an IPv6 PTR reminder. The engine prefers IPv6 for outbound with automatic IPv4 fallback.
fe80::…) are never placed in DNS or SPF — putting them there would break delivery, so the wizard filters them out.Send a test email
Use the wizard's built-in test, or send manually. Authenticated submission uses port 587 with your master password (default Lurstan — change it). Any username works; the password is what authorizes relay.
swaks --server mail.example.com --port 587 \
--auth LOGIN --auth-user you@example.com \
--auth-password 'YOUR_MASTER_PASSWORD' \
--from you@example.com --to test@gmail.com \
--header "Subject: Hello from SMTP Wizard" \
--body "It works!" --tls
Unauthenticated connections are rejected with 550 5.7.1 relaying not permitted, so your server can't be used as an open relay.
Change domain
To repoint an existing server at a new sending domain, use the wizard's Change Domain action. It backs up the current config, generates a fresh DKIM key for the new domain, rewrites the policy atomically, updates the hostname, and restarts the engine — then gives you the new DNS records. Previous configs are saved under /opt/<engine>/etc/backups/ on the server.
Payment gateway (Cryptomus)
The payment system is built into the PHP backend — no separate process needed. Configure it once from the admin panel.
1. Get your Cryptomus credentials
Sign up at cryptomus.com, create a merchant, and copy your Merchant UUID and Payment API key.
2. Configure in the admin panel
Open https://yourdomain.com/admin.html, sign in with your admin token, and go to the Settings tab. Enter your Cryptomus credentials, your site URL, and the unlock price. Save — changes take effect immediately.
| Setting | Value |
|---|---|
| Cryptomus Merchant ID | Your merchant UUID from Cryptomus |
| Cryptomus Payment API Key | Your payment API key from Cryptomus |
| App Base URL | https://yourdomain.com — must be reachable by Cryptomus for webhooks |
| Unlock Price (USD) | Default 110 — the price per SMTP build in USD |
| Admin Token | A long random secret for admin panel access |
3. How a purchase flows
- A visitor clicks Build SMTP, enters their email, and is sent to the Cryptomus crypto checkout.
- Cryptomus calls your
/api/cryptomus/webhook(signature-verified) when payment confirms. - The server issues a license key and unlocks the dashboard, where the buyer enters their server IP + SMTP details to build once.
- The build consumes the payment. Rebuilding on that IP requires paying again.
yourdomain.com/api/cryptomus/webhook over HTTPS. Make sure your domain has a valid SSL certificate (cPanel AutoSSL handles this automatically).Admin IP allowlist (free forever)
You can grant specific IPs free, unlimited SMTP builds — no payment, ever. Open the admin panel at:
https://yourdomain.com/admin.html
Sign in with your admin token and add an IP with an optional note. From then on, building SMTP on that IP is free and never consumes a payment. Remove the IP to require payment again.
API (if you prefer scripting)
# Add an IP to the free allowlist
curl -X POST https://yourdomain.com/api/admin/allowlist \
-H "x-admin-token: YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"ip":"203.0.113.42","note":"in-house server"}'
# List approved IPs
curl https://yourdomain.com/api/admin/allowlist -H "x-admin-token: YOUR_ADMIN_TOKEN"
# Remove one
curl -X DELETE https://yourdomain.com/api/admin/allowlist/203.0.113.42 \
-H "x-admin-token: YOUR_ADMIN_TOKEN"
Build log & abuse control
The admin panel's Build log tab records every SMTP build for full accountability. Each entry captures:
- The builder's IP and geolocation (country, city, and flag) plus their browser user-agent
- The target/sending server IP and its geolocation
- The full SMTP credentials (host, port, username, password) and the dashboard UI + metrics URLs
- Whether it was a paid or free (allowlisted) build, and the buyer's email/license
If a server starts abusing the service for spam, click Block next to its entry (or add it under the Blocked IPs tab). Blocked server IPs are immediately refused at /api/smtp/build and cannot build again until you unblock them.
# Block a server IP for abuse
curl -X POST https://yourdomain.com/api/admin/block \
-H "x-admin-token: YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"ip":"203.0.113.42","reason":"spam complaints"}'
# Review the full build log
curl https://yourdomain.com/api/admin/builds -H "x-admin-token: YOUR_ADMIN_TOKEN"
Health & monitoring
The wizard includes a health check that reports engine status, port 25/587 listening state, queue depth, DKIM key presence, PTR, disk/RAM/load, and recent logs. If you enabled them:
- Prometheus scrapes engine metrics at
http://server:8000/metrics(UI on port9090). - Grafana dashboards on port
3000. - Admin UI dashboard at
http://mail.example.com/ui/.
The PHP backend also exposes /api/health returning JSON status for uptime checks.
Support & live chat
A built-in support system lets clients report issues without any third-party service — the data stays in your app.
- Clients see a floating chat button (bottom-right) on the landing page and dashboard. They open a ticket with their email, subject, and message, then chat in a thread that updates live (polled every few seconds). Their ticket is remembered in the browser so they can return to it.
- You answer from the Support tab in the admin panel (
admin.html): pick a ticket, read the conversation, reply, and close or reopen it. The tab shows a badge with the number of open tickets.
It's wired automatically — the widget script (support-widget.js) is already included on the landing page and dashboard, and it talks to same-origin /api/support/* endpoints.
Security checklist
- Gate the installer. The
/installer/wizard drives root SSH on target servers, so lock it down: rename the bundledhtaccessto.htaccessand either enable cPanel ▸ Directory Privacy on the folder, or uncomment the HTTP Basic Auth block inside it (after creating an.htpasswdoutsidepublic_html). - Set a strong Admin Token (and optionally an Admin Password login). The admin API also locks out an IP after repeated failed logins.
- Set SECRET_KEY in the admin panel Settings so stored SMTP passwords are encrypted at rest (AES-256-GCM). Without it they're stored as plain text. Don't change it later — that makes existing stored passwords unreadable.
- Sensitive files are protected. The
.htaccessblocks direct HTTP access to.env,db.sqlite, dotfiles, and thebackups/directory — so config and data can't be fetched over HTTP. - Change the default master mail password before sending real mail.
- Serve everything over HTTPS (cPanel AutoSSL / Let's Encrypt).
api/info.phpis locked to localhost — delete it once you're done testing.
Email notifications (optional)
Set SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, MAIL_FROM, and ADMIN_EMAIL in the admin panel Settings to email license keys/receipts to buyers, alert you on new support tickets, and notify clients when you reply. Leave them blank to disable email — the app logs [mail skipped] and keeps working. Buyers who lose their key can use POST /api/resend-license.
Reliability
- The database is backed up daily to
/backupson your cPanel server (last 14 kept). - Unpaid pending orders are auto-purged after
ORDER_TTL_MINminutes (configurable in admin Settings). - cPanel keeps the PHP backend running via Apache — no separate process manager needed.
Troubleshooting
"No SSH backend available"
Install the PHP ssh2 extension, or ensure the bundled api/vendor/ (phpseclib) uploaded correctly.
Engine won't start on port 25
A competing MTA (Postfix/Sendmail/Exim) may hold the port. The wizard tries to remove them; if it persists, on the server run:
ss -tlnp | grep :25 # find what holds the port
fuser -k 25/tcp # free it
systemctl restart kumomta
Emails land in spam
Almost always DNS. Confirm SPF, DKIM, DMARC are published and propagated, and that PTR/rDNS matches your hostname (set in the VPS provider panel). Warm up new IPs gradually.
Payment didn't unlock the dashboard
Check that Cryptomus can reach your webhook URL over HTTPS and that the App Base URL in admin Settings is correct. The dashboard also actively re-checks payment status as a fallback.
Downloads fail during install
Usually broken server DNS. On the target server: echo "nameserver 8.8.8.8" > /etc/resolv.conf and retry.