What You Are Building
A phishing simulation platform for authorised security awareness training. The stack is GoPhish for campaign management, Postfix for mail delivery, Apache for landing pages, and Let's Encrypt for TLS — all on a single Ubuntu 24.04 LTS host. You will configure every DNS record a sending domain needs to deliver reliably and look legitimate to mail filters: SPF, DKIM, DMARC, CAA and the service-discovery SRV records that modern mail infrastructure expects.
This is an offensive-security tool. Use it only for authorised testing within your own organisation or under a signed engagement letter.
Prerequisites
- A fresh Ubuntu 24.04 LTS server with root or sudo access
- One or more domains dedicated to phishing simulation (never your corporate domain)
- DNS control over those domains
- Ports 25, 80, 443 and 3333 open in your firewall
- A static public IP with a clean reputation (check against Spamhaus, SpamCop and Barracuda before you start)
Step 1: System Preparation
sudo apt update && sudo apt upgrade -y
sudo apt install -y unzip curl wget certbot ufw
sudo timedatectl set-timezone UTC
Set the hostname to your primary sending domain:
sudo hostnamectl set-hostname mail.phishdomain.com
Edit /etc/hosts:
127.0.0.1 localhost
203.0.113.10 mail.phishdomain.com mail
Firewall
sudo ufw allow 22/tcp
sudo ufw allow 25/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3333/tcp
sudo ufw enable
Port 3333 is the GoPhish admin panel. In production, restrict it to your management IP:
sudo ufw delete allow 3333/tcp
sudo ufw allow from 198.51.100.0/24 to any port 3333
Step 2: Install Postfix
sudo apt install -y postfix
Select Internet Site when prompted. Set the system mail name to your primary sending domain (e.g. phishdomain.com).
Configure Postfix
Edit /etc/postfix/main.cf:
# ─── identity ─────────────────────────────────────────────
myhostname = mail.phishdomain.com
mydomain = phishdomain.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost
# ─── network ──────────────────────────────────────────────
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 127.0.0.0/8 [::1]/128
# ─── TLS ──────────────────────────────────────────────────
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.phishdomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.phishdomain.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = >=TLSv1.2
smtp_tls_security_level = may
smtp_tls_protocols = >=TLSv1.2
smtp_tls_loglevel = 1
# ─── delivery ─────────────────────────────────────────────
virtual_alias_maps = hash:/etc/postfix/virtual
transport_maps = hash:/etc/postfix/transport
# ─── hardening ────────────────────────────────────────────
smtpd_banner = $myhostname ESMTP
disable_vrfy_command = yes
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
message_size_limit = 10240000
# ─── rate limiting ────────────────────────────────────────
smtp_destination_concurrency_limit = 2
smtp_destination_rate_delay = 3s
smtp_extra_recipient_limit = 5
default_destination_rate_delay = 1s
The rate-limiting settings are critical. Phishing simulation servers that blast mail at full speed get blacklisted within hours. Two concurrent connections per destination with a three-second delay between messages keeps you under the radar of receiving mail servers.
Virtual Aliases
If you want all inbound mail on your phishing domains forwarded to a single collection address, create /etc/postfix/virtual:
@phishdomain.com phishing-testing@your-real-domain.com
@seconddomain.com phishing-testing@your-real-domain.com
Build the hash and reload:
sudo postmap /etc/postfix/virtual
sudo systemctl reload postfix
Transport Maps
If different domains should route through different relays, create /etc/postfix/transport:
phishdomain.com smtp:
seconddomain.com smtp:
sudo postmap /etc/postfix/transport
Step 3: TLS Certificates
Obtain certificates for each sending domain and the mail hostname. You need these before GoPhish landing pages will work over HTTPS.
sudo certbot certonly --standalone -d mail.phishdomain.com
sudo certbot certonly --standalone -d phishdomain.com
sudo certbot certonly --standalone -d seconddomain.com
Enable automatic renewal:
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
Step 4: Install GoPhish
Download the latest release:
cd /opt
sudo wget https://github.com/gophish/gophish/releases/download/v0.12.1/gophish-v0.12.1-linux-64bit.zip
sudo unzip gophish-v0.12.1-linux-64bit.zip -d gophish
sudo chmod +x /opt/gophish/gophish
Check the GoPhish releases page for the current version.
Configure GoPhish
Edit /opt/gophish/config.json:
{
"admin_server": {
"listen_url": "0.0.0.0:3333",
"use_tls": true,
"cert_path": "/etc/letsencrypt/live/mail.phishdomain.com/fullchain.pem",
"key_path": "/etc/letsencrypt/live/mail.phishdomain.com/privkey.pem"
},
"phish_server": {
"listen_url": "0.0.0.0:8080",
"use_tls": false
},
"db_name": "sqlite3",
"db_path": "gophish.db",
"migrations_prefix": "db/db_",
"contact_address": "",
"logging": {
"filename": "/opt/gophish/gophish.log",
"level": "info"
}
}
The phish server listens on 8080 without TLS because Apache will reverse-proxy it on port 443. Running GoPhish directly on 443 requires root; the reverse-proxy approach is cleaner.
Create a Systemd Service
Create /etc/systemd/system/gophish.service:
[Unit]
Description=GoPhish Phishing Simulation
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/gophish
ExecStart=/opt/gophish/gophish
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
User=root
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable gophish
sudo systemctl start gophish
First Login
Open https://your-server-ip:3333 in your browser. The default credentials are printed to the GoPhish log on first start:
sudo journalctl -u gophish --no-pager -n 20 | grep "Please login"
Log in and change the password immediately.
Step 5: Apache Reverse Proxy for Landing Pages
GoPhish serves landing pages on port 8080. Apache proxies these on port 443 with proper TLS termination, and you can serve different landing pages for different domains using virtual hosts.
sudo apt install -y apache2
sudo a2enmod proxy proxy_http ssl rewrite headers
Create a virtual host for each phishing domain. Example for /etc/apache2/sites-available/phishdomain.conf:
<VirtualHost *:80>
ServerName phishdomain.com
RewriteEngine On
RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName phishdomain.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/phishdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/phishdomain.com/privkey.pem
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto "https"
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000"
Header always set X-Content-Type-Options "nosniff"
</IfModule>
ErrorLog ${APACHE_LOG_DIR}/phish_error.log
CustomLog ${APACHE_LOG_DIR}/phish_access.log combined
</VirtualHost>
Enable the site:
sudo a2ensite phishdomain.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
Repeat for each sending domain, changing ServerName and certificate paths.
Step 6: DNS Configuration
This is where campaigns succeed or fail. Every sending domain needs a complete set of DNS records. Missing any one of them triggers spam filters at major providers.
A and MX Records
phishdomain.com. A 203.0.113.10
mail.phishdomain.com. A 203.0.113.10
phishdomain.com. MX 10 mail.phishdomain.com.
PTR Record (Reverse DNS)
Contact your hosting provider to set the PTR record for your server's IP. It must resolve to mail.phishdomain.com (your myhostname). Many providers expose this in their control panel.
10.113.0.203.in-addr.arpa. PTR mail.phishdomain.com.
Without a matching PTR, Gmail and Microsoft 365 will reject or spam-folder your mail. This is the single most common reason phishing simulations fail to deliver.
SPF Record
SPF tells receiving servers which IPs are authorised to send on behalf of your domain:
phishdomain.com. TXT "v=spf1 a mx ip4:203.0.113.10 -all"
a— the domain's A record is authorisedmx— the domain's MX server is authorisedip4:203.0.113.10— explicit IP authorisation-all— hard fail everything else
Use -all (hard fail), not ~all (soft fail). A soft fail tells receivers that unauthorised senders are suspicious but acceptable. A hard fail says they are definitively rejected. This improves your deliverability because it signals a well-configured domain.
DKIM
Install OpenDKIM:
sudo apt install -y opendkim opendkim-tools
Generate a key for each sending domain:
sudo mkdir -p /etc/opendkim/keys/phishdomain.com
sudo opendkim-genkey -b 2048 -d phishdomain.com -D /etc/opendkim/keys/phishdomain.com -s mail -v
sudo chown -R opendkim:opendkim /etc/opendkim
Configure /etc/opendkim.conf:
Syslog yes
Canonicalization relaxed/simple
Mode sv
SubDomains no
AutoRestart yes
SignatureAlgorithm rsa-sha256
KeyTable refile:/etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
InternalHosts refile:/etc/opendkim/trusted.hosts
ExternalIgnoreList refile:/etc/opendkim/trusted.hosts
Create /etc/opendkim/signing.table:
*@phishdomain.com mail._domainkey.phishdomain.com
*@seconddomain.com mail._domainkey.seconddomain.com
Create /etc/opendkim/key.table:
mail._domainkey.phishdomain.com phishdomain.com:mail:/etc/opendkim/keys/phishdomain.com/mail.private
mail._domainkey.seconddomain.com seconddomain.com:mail:/etc/opendkim/keys/seconddomain.com/mail.private
Create /etc/opendkim/trusted.hosts:
127.0.0.1
localhost
mail.phishdomain.com
Set the socket in /etc/default/opendkim:
SOCKET="inet:8891@localhost"
Add to /etc/postfix/main.cf:
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
Publish the DKIM public key. Display it:
sudo cat /etc/opendkim/keys/phishdomain.com/mail.txt
Add the output as a TXT record for mail._domainkey.phishdomain.com. Repeat for every sending domain.
Restart both:
sudo systemctl restart opendkim
sudo systemctl restart postfix
DMARC Record
_dmarc.phishdomain.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@phishdomain.com; adkim=r; aspf=r; pct=100"
p=quarantine— tells receivers to quarantine messages that fail SPF and DKIM alignment. For simulation domains,quarantineis appropriate;rejectis aggressive but works once you have confirmed alignment.rua— where aggregate reports go. Point this to an address you monitor.adkim=r— relaxed DKIM alignment (the d= domain can be a subdomain of the From domain)aspf=r— relaxed SPF alignment
CAA Records
CAA (Certificate Authority Authorization) records specify which certificate authorities are permitted to issue TLS certificates for your domain. Without a CAA record, any CA can issue a certificate; with one, only the listed CAs can.
For phishing simulation domains using Let's Encrypt:
phishdomain.com. CAA 0 issue "letsencrypt.org"
phishdomain.com. CAA 0 issuewild ";"
phishdomain.com. CAA 0 iodef "mailto:security@your-real-domain.com"
issue "letsencrypt.org"— only Let's Encrypt may issue certificates for this domainissuewild ";"— no CA may issue wildcard certificates (the semicolon denies all)iodef— where CAs send violation reports
This achieves two things. First, it prevents an attacker from obtaining a certificate for your simulation domain from a different CA, which would let them impersonate your phishing infrastructure. Second, it signals to security tools that the domain is properly managed — a bare domain with no CAA record is a minor flag in some email reputation systems.
If you use multiple CAs, add a separate issue record for each:
phishdomain.com. CAA 0 issue "letsencrypt.org"
phishdomain.com. CAA 0 issue "sectigo.com"
SRV Records
SRV (Service) records advertise the location and port of specific services. For a mail domain, these records tell clients and other servers where to find your mail services. They are not strictly required for delivery, but their presence makes a domain look like a properly configured mail environment — which is exactly what you want for simulation domains that need to pass scrutiny.
Mail Submission (RFC 6186)
These records allow mail clients to auto-discover your server settings:
_submission._tcp.phishdomain.com. SRV 0 1 587 mail.phishdomain.com.
_imaps._tcp.phishdomain.com. SRV 0 1 993 mail.phishdomain.com.
_imap._tcp.phishdomain.com. SRV 0 0 0 .
_pop3._tcp.phishdomain.com. SRV 0 0 0 .
_pop3s._tcp.phishdomain.com. SRV 0 0 0 .
_submission._tcp— advertises the SMTP submission port (587) for authenticated sending_imaps._tcp— advertises IMAPS (993) for encrypted IMAP access- The
0 0 0 .entries explicitly disable POP3, signalling that the domain does not offer legacy protocols — a mark of a modern mail deployment
MTA-STS
MTA-STS (Mail Transfer Agent Strict Transport Security) tells sending servers to require TLS when delivering to your domain. It works via a DNS record and a policy file:
_mta-sts.phishdomain.com. TXT "v=STSv1; id=20260910"
The id is an opaque string that changes when you update the policy. Receiving servers cache the policy until the id changes.
Serve the policy file at https://mta-sts.phishdomain.com/.well-known/mta-sts.txt:
version: STSv1
mode: enforce
mx: mail.phishdomain.com
max_age: 86400
Add an Apache virtual host for this subdomain, or serve it from your existing configuration.
SMTP TLS Reporting (TLSRPT)
Tells sending servers where to report TLS negotiation failures:
_smtp._tls.phishdomain.com. TXT "v=TLSRPTv1; rua=mailto:tls-reports@your-real-domain.com"
Complete DNS Zone Example
For reference, here is every record a fully configured sending domain needs:
; ─── A / MX ───────────────────────────────────────────────
phishdomain.com. A 203.0.113.10
mail.phishdomain.com. A 203.0.113.10
mta-sts.phishdomain.com. A 203.0.113.10
phishdomain.com. MX 10 mail.phishdomain.com.
; ─── SPF ──────────────────────────────────────────────────
phishdomain.com. TXT "v=spf1 a mx ip4:203.0.113.10 -all"
; ─── DKIM ─────────────────────────────────────────────────
mail._domainkey.phishdomain.com. TXT "v=DKIM1; h=sha256; k=rsa; p=MIIBIjAN..."
; ─── DMARC ────────────────────────────────────────────────
_dmarc.phishdomain.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@phishdomain.com; adkim=r; aspf=r; pct=100"
; ─── CAA ──────────────────────────────────────────────────
phishdomain.com. CAA 0 issue "letsencrypt.org"
phishdomain.com. CAA 0 issuewild ";"
phishdomain.com. CAA 0 iodef "mailto:security@your-real-domain.com"
; ─── SRV (mail service discovery) ─────────────────────────
_submission._tcp.phishdomain.com. SRV 0 1 587 mail.phishdomain.com.
_imaps._tcp.phishdomain.com. SRV 0 1 993 mail.phishdomain.com.
_imap._tcp.phishdomain.com. SRV 0 0 0 .
_pop3._tcp.phishdomain.com. SRV 0 0 0 .
_pop3s._tcp.phishdomain.com. SRV 0 0 0 .
; ─── MTA-STS / TLSRPT ────────────────────────────────────
_mta-sts.phishdomain.com. TXT "v=STSv1; id=20260910"
_smtp._tls.phishdomain.com. TXT "v=TLSRPTv1; rua=mailto:tls-reports@your-real-domain.com"
Apply this template to every sending domain you operate.
Step 7: Import Campaign Templates
The HailBytes GoPhish Training Templates repository is an excellent starting point. It contains 91 email templates across 27 industries — from corporate HR and payroll lures to QR-code phishing (quishing) and SMS phishing (smishing) scenarios — plus matching landing pages and educational content.
Clone the Repository
cd /opt
sudo git clone https://github.com/HailBytes/gophish-training-templates.git
Import Email Templates
In the GoPhish admin panel at https://your-server-ip:3333:
- Navigate to Email Templates
- Click New Template
- Open one of the template HTML files from
gophish-training-templates/in a text editor - Paste the HTML into the HTML tab
- Set a descriptive name (e.g.
Corporate - Password Reset) - Check Add Tracking Image to enable open tracking
- Save
The templates use GoPhish's template variables:
{{.FirstName}}— the target's first name{{.LastName}}— the target's last name{{.Email}}— the target's email address{{.Position}}— job title{{.From}}— the sender address{{.URL}}— the phishing link (auto-generated by GoPhish)
Import Landing Pages
- Navigate to Landing Pages
- Click New Page
- Paste the HTML from the
landing-pages/directory - Check Capture Submitted Data if you want to log credentials (handle with care — see the legal section below)
- Check Capture Passwords only if your engagement scope explicitly permits it
- Set a Redirect URL to the real service or to a training page after capture
Configure Sending Profiles
- Navigate to Sending Profiles
- Click New Profile
- Set the From address (e.g.
IT Support <support@phishdomain.com>) - Set the Host to
localhost:25(Postfix on the same machine) - Leave username and password blank (Postfix is configured to accept from localhost without auth)
- Send a test email to verify delivery
Create a separate sending profile for each domain you use. This lets you match the sender domain to the campaign theme — a financial lure from a finance-themed domain, an IT alert from a tech-themed domain.
Step 8: Building Effective Campaigns
Campaign Structure
The HailBytes repository suggests a progressive difficulty model:
- Level 1 — Obvious: clear spelling errors, generic greetings, suspicious URLs. Establishes a baseline click rate.
- Level 2 — Moderate: branded templates, personalised greetings, plausible pretexts. Tests basic awareness.
- Level 3 — Sophisticated: industry-specific lures, current events, pixel-perfect branding. Tests advanced awareness.
- Level 4 — Targeted: spear-phishing with researched context, multi-stage (e.g. a phone call followed by an email). Tests resilience under pressure.
Run quarterly baseline campaigns at Level 2 across the entire organisation. Run targeted campaigns at Level 3-4 for high-risk roles (finance, HR, IT admin).
User Groups
In GoPhish, create groups that match your organisation's structure:
- Navigate to Users & Groups
- Click New Group
- Import from CSV:
First Name, Last Name, Email, Position
John,Smith,john.smith@target-org.com,Finance Manager
Jane,Doe,jane.doe@target-org.com,HR Director
Segment groups by department so you can run department-specific campaigns and compare results.
Launching a Campaign
- Navigate to Campaigns
- Click New Campaign
- Name it descriptively (e.g.
Q3 2026 — IT Password Reset — All Staff) - Select the email template, landing page, sending profile and user group
- Set the URL to your phishing domain (e.g.
https://phishdomain.com) - Set Launch Date and optionally Send By Date to stagger delivery
- Use Send By Date to spread emails across several hours — a batch of 500 identical emails arriving in the same minute triggers rate limiters
Staggering Delivery
GoPhish distributes emails evenly between the launch date and the send-by date. For a campaign of 200 users, setting a four-hour window means roughly one email per 72 seconds. This is sustainable for most receiving mail servers and avoids triggering volume-based blocks.
Step 9: Monitoring and Reporting
Real-Time Dashboard
The GoPhish dashboard shows:
- Emails Sent — total delivered
- Emails Opened — tracking pixel loaded (not reliable for plain-text clients)
- Links Clicked — the target visited the landing page
- Data Submitted — credentials or form data captured
- Reported — the target reported the email (requires a reporting integration)
Key Metrics to Track
The HailBytes documentation recommends these KPIs:
- Click rate — aim to reduce below 5% for Level 2 campaigns within four quarters
- Reporting rate — aim for over 80% of phishing emails reported
- Time to report — under one hour from delivery
- Repeat offender rate — identify users who click in successive campaigns for targeted training
- Training completion — 95%+ completion of the educational module shown after a click
Exporting Results
GoPhish exports campaign results as CSV. Download from the campaign detail page and use them for management reporting. The CSV includes timestamps for every event (sent, opened, clicked, submitted), which lets you calculate time-to-click distributions.
Step 10: Hardening the Platform
Restrict GoPhish Admin Access
The admin panel on port 3333 should only be accessible from your management network:
sudo ufw delete allow 3333/tcp
sudo ufw allow from 198.51.100.0/24 to any port 3333
File Permissions
sudo chmod 600 /opt/gophish/config.json
sudo chmod 600 /opt/gophish/gophish.db
Log Rotation
Create /etc/logrotate.d/gophish:
/opt/gophish/gophish.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
}
Database Backups
GoPhish uses SQLite by default. Back up the database daily:
sudo crontab -e
0 2 * * * cp /opt/gophish/gophish.db /var/backups/gophish-$(date +\%F).db
IP Reputation Monitoring
Check your server's IP reputation weekly. If it appears on a blacklist, stop all campaigns and request delisting before the reputation damage compounds:
# Check against major blacklists
dig +short 10.113.0.203.zen.spamhaus.org
dig +short 10.113.0.203.bl.spamcop.net
dig +short 10.113.0.203.b.barracudacentral.org
Replace 10.113.0.203 with your IP in reverse-octet order.
Step 11: Managing Multiple Sending Domains
For a portfolio of sending domains, each domain needs its own complete DNS configuration as described in Step 6. Automate the DKIM key generation:
#!/bin/bash
DOMAINS="phishdomain.com seconddomain.com thirddomain.com"
for DOMAIN in $DOMAINS; do
sudo mkdir -p /etc/opendkim/keys/$DOMAIN
sudo opendkim-genkey -b 2048 -d $DOMAIN \
-D /etc/opendkim/keys/$DOMAIN -s mail -v
echo "*@$DOMAIN mail._domainkey.$DOMAIN" >> /etc/opendkim/signing.table
echo "mail._domainkey.$DOMAIN $DOMAIN:mail:/etc/opendkim/keys/$DOMAIN/mail.private" >> /etc/opendkim/key.table
done
sudo chown -R opendkim:opendkim /etc/opendkim
sudo systemctl restart opendkim
sudo systemctl restart postfix
Then publish each domain's DKIM public key to DNS. Display all of them:
for DOMAIN in phishdomain.com seconddomain.com thirddomain.com; do
echo "=== $DOMAIN ==="
cat /etc/opendkim/keys/$DOMAIN/mail.txt
echo ""
done
Step 12: Validating Your Configuration
Before running your first campaign, validate every layer.
DNS
dig +short phishdomain.com A
dig +short phishdomain.com MX
dig +short phishdomain.com TXT
dig +short _dmarc.phishdomain.com TXT
dig +short mail._domainkey.phishdomain.com TXT
dig +short phishdomain.com CAA
dig +short _submission._tcp.phishdomain.com SRV
dig +short _mta-sts.phishdomain.com TXT
SPF and DKIM
Send a test message to check-auth@verifier.port25.com. The bounce-back report shows your SPF, DKIM and DMARC results.
Mail Flow
Send a test to a Gmail address and inspect the headers. Look for:
Authentication-Results:
spf=pass
dkim=pass
dmarc=pass
All three should show pass. If any shows fail, fix it before launching a campaign.
TLS
openssl s_client -connect mail.phishdomain.com:25 -starttls smtp
Confirm the certificate chain is valid and the protocol is TLS 1.2 or higher.
Legal and Ethical Framework
Phishing simulation is authorised offensive testing. Without proper authorisation, it is a criminal offence in most jurisdictions.
- Written authorisation — obtain signed approval from the organisation's leadership before any campaign. This should name the testing scope, the domains, the target audience, and the data handling policy.
- Education, not punishment — the purpose is to improve awareness, not to discipline. Users who click should receive immediate, constructive training — not a reprimand.
- Data handling — if you capture credentials, handle them as sensitive data. Encrypt the database, restrict access, and delete captured credentials within 24 hours of the campaign ending.
- Confidentiality — individual results should be reported only in aggregate unless the engagement scope specifically permits named reporting.
- Coordination — inform the target organisation's IT security team before launching. A phishing simulation that triggers an incident response wastes everyone's time.
Summary
The stack is GoPhish for campaign management, Postfix for delivery with rate limiting, Apache for TLS-terminated landing pages, and OpenDKIM for message signing. Every sending domain needs the full DNS suite — A, MX, PTR, SPF, DKIM, DMARC, CAA, SRV, MTA-STS and TLSRPT — configured before you send your first message. The HailBytes template repository gives you 91 ready-made email templates across 27 industries with matching landing pages and a progressive difficulty framework. Start at Level 1, establish a baseline, and work up. The platform delivers mail; the DNS makes it arrive; the templates make it convincing; and the metrics tell you whether your organisation is getting better.