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 walks you through installing it on cPanel and using every feature.
Overview
The SMTP Wizard has two parts:
- The deployment wizard (PHP) — 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 access layer (Node.js) — the public landing page, the Cryptomus crypto-payment checkout, the gated builder dashboard, and the admin panel for approving free IPs.
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)
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)
For the access layer (Node app)
- Node.js 18+ on whatever host serves your landing page/checkout
- A Cryptomus merchant account for crypto payments
Install on cPanel
Upload the files
In cPanel → File Manager, go to public_html and upload the installer folder (or a ZIP of it). If you upload a ZIP, right-click → Extract.
Check the folder layout
You should end up with public_html/installer/ containing index.html, the api/ folder, and this documentation/ folder.
Set permissions
Folders 755, files 644. cPanel's default upload permissions are usually fine.
Open the wizard
Visit https://yourdomain.com/installer/. You'll see the deployment UI. This documentation lives at https://yourdomain.com/installer/documentation/.
/installer/api/info.php from the server itself (it's locked to localhost for security). It reports your PHP version and whether an SSH backend is available.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 access layer is a small Node.js app that serves the landing page, the checkout, and the builder dashboard.
1. Configure
cp .env.example .env
# then edit .env:
CRYPTOMUS_MERCHANT_ID=your-merchant-uuid
CRYPTOMUS_PAYMENT_API_KEY=your-payment-api-key
APP_BASE_URL=https://yourdomain.com # must be reachable by Cryptomus
UNLOCK_PRICE_USD=100
ADMIN_TOKEN=a-long-random-secret
2. Run
npm install
npm start # serves on PORT (default 3000)
3. How a purchase flows
- A visitor clicks Unlock, 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.
APP_BASE_URL/api/cryptomus/webhook over HTTPS. In local testing, expose it with a tunnel (e.g. ngrok) and set APP_BASE_URL to the tunnel URL.Admin IP allowlist (free forever)
You can grant specific IPs free, unlimited SMTP builds — no payment, ever. Set ADMIN_TOKEN in .env, then open the admin panel:
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 Node access layer exposes /api/health returning JSON status for uptime checks.