SMTP Wizard Docs
Documentation · v1.0

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.

💡 How access works: a customer pays once (default $110 in crypto) to unlock a single SMTP build on one IP. Once built, that payment is spent — rebuilding on the same IP needs a fresh payment. You (the admin) can add specific IPs to a free-forever allowlist so they never require payment.

Requirements

For the cPanel wizard (PHP)

  • cPanel/PHP hosting running PHP 8.1+
  • The ssh2 PHP extension or the bundled phpseclib fallback (already included in api/vendor/ — no action needed if ssh2 is missing)
  • curl enabled (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, and 80 open (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:

FieldWhat to enter
Server IPThe public IPv4 of the VPS you're deploying to.
SSH port / passwordRoot SSH port (usually 22) and the root password.
DomainYour 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 emailOptional. Where aggregate DMARC reports are sent.
DKIM selectormail, dkim, or any valid selector label.
Stack componentsToggle 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:

  1. TCP + SSH pre-flight checks and OS detection
  2. Fixes server DNS resolution if broken, sets the hostname and /etc/hosts
  3. Configures the firewall and removes any competing MTAs (Postfix/Sendmail/Exim) holding ports 25/587
  4. Installs the SMTP engine, generates a 2048-bit DKIM key, and writes the policy config
  5. Optionally installs Prometheus, Grafana, and the Admin UI dashboard
  6. 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.

⚠ The deployment installs and removes packages as root on the target server. Only run it against a fresh server you intend to dedicate to sending mail.

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.

TypeHostPurpose
A@ and mailPoint your domain and mail host at the server's IPv4.
AAAA if IPv6@ and mailOnly 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._domainkeyPublishes the DKIM public key so receivers can verify signatures.
TXT (DMARC)_dmarcPolicy + reporting address. Starts at p=none.
PTR (rDNS)your IPSet 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:

  1. Go to Cloudflare dashboard → Manage Account → OAuth clients → Create client.
  2. Set Grant type = Authorization Code, Token auth = Client Secret, and Redirect URL = https://YOUR_DOMAIN/installer/api/cf_oauth_callback.php.
  3. Select the DNS edit and Zone read scopes, then create the client and copy the Client ID + Client Secret.
  4. Edit installer/api/cf_config.php and fill in client_id, client_secret, and redirect_uri.
📌 The OAuth client can stay private (no domain verification needed) as long as you authorize with the same Cloudflare account that created it. The access token is exchanged and stored server-side in PHP — it's never exposed to the browser. If cf_config.php is left blank, the button hides and the API-token method is used instead.
⚠ If the consent screen reports an unknown scope, your account may use different scope keys. List them at https://api.cloudflare.com/client/v4/oauth/scopes and update scopes in cf_config.php.
📌 PTR is critical for deliverability. It can only be set by whoever controls the IP — your VPS provider. Set reverse DNS for your IP to 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.
✅ Only globally routable IPv6 is ever published. Non-routable link-local addresses (fe80::…) are never placed in DNS or SPF — putting them there would break delivery, so the wizard filters them out.
If the engine fails to start with IPv6 egress on a misconfigured network, the wizard automatically redeploys an IPv4-only configuration so your server still comes up.

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 the master password from the default before going live. Treat it like a root credential — anyone with it can send through your server.

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.

SettingValue
Cryptomus Merchant IDYour merchant UUID from Cryptomus
Cryptomus Payment API KeyYour payment API key from Cryptomus
App Base URLhttps://yourdomain.com — must be reachable by Cryptomus for webhooks
Unlock Price (USD)Default 110 — the price per SMTP build in USD
Admin TokenA long random secret for admin panel access

3. How a purchase flows

  1. A visitor clicks Build SMTP, enters their email, and is sent to the Cryptomus crypto checkout.
  2. Cryptomus calls your /api/cryptomus/webhook (signature-verified) when payment confirms.
  3. The server issues a license key and unlocks the dashboard, where the buyer enters their server IP + SMTP details to build once.
  4. The build consumes the payment. Rebuilding on that IP requires paying again.
⚠ Cryptomus must be able to reach 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"
✅ Anyone building on an allowlisted IP skips payment entirely — useful for your own servers or trusted clients.

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 port 9090).
  • 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.

✅ Want a human live-chat agent instead? You can drop a third-party widget (e.g. Tawk.to or Crisp) snippet into the pages — but the built-in tickets work out of the box and keep all conversations on your own server.

Security checklist

  • Gate the installer. The /installer/ wizard drives root SSH on target servers, so lock it down: rename the bundled htaccess to .htaccess and either enable cPanel ▸ Directory Privacy on the folder, or uncomment the HTTP Basic Auth block inside it (after creating an .htpasswd outside public_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 .htaccess blocks direct HTTP access to .env, db.sqlite, dotfiles, and the backups/ 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.php is 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 /backups on your cPanel server (last 14 kept).
  • Unpaid pending orders are auto-purged after ORDER_TTL_MIN minutes (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.