Mailing policy — no bulk mail from BOA hosts
BOA hosts (both hosted-BOA at omega8.cc and self-hosted BOA in production) are not intended for bulk-mail sending. This page explains why and what to do instead.
The policy
BOA hosts: transactional mail OK, bulk mail NOT OK.
Allowed (transactional):
- New-user-registration confirmations.
- Password-reset mails.
- Order receipts.
- Form-submission notifications.
- BOA's own system notifications (install/upgrade/incident reports).
- BOA-originated client notices — the Let's Encrypt renewal-failure notices (below).
Not allowed (bulk):
- Marketing newsletters to N+ recipients.
- Mass campaign sends.
- Automated drip sequences.
- Re-engagement emails to inactive users.
- Any send pattern that looks like marketing.
Why
1. IP reputation
A single BOA host serves many tenants' sites. One tenant's bulk-mail blunder (e.g. hitting a stale list and triggering high bounce rates) can land the host's IP on shared spam blocklists. That affects every other tenant's transactional mail — registrations bounce, password resets do not arrive, order confirmations get spam-foldered. Routing bulk mail through a dedicated email service provider (ESP) isolates the IP-reputation risk to that provider's actively-managed IP pool.
2. Anti-abuse enforcement
On hosted BOA (omega8.cc) this is enforced as a service-level policy:
bulk-mail attempts may result in a temporary outbound-25 firewall block, a support
ticket, or — in repeat cases — account suspension. This enforcement is operational
(monitoring + support action), not an automated BOA volume-throttle baked into the
stack — BOA ships no outbound-mail rate-limiter or volume monitor (the
sendmail_guard.sh monitor only kills rogue root-owned sendmail MTA processes;
it does not meter send volume).
On self-hosted BOA there is therefore no built-in throttle to rely on or disable: keeping within transactional limits is the operator's responsibility, and the upstream provider's own anti-spam policies (and any outbound-25 limits) still apply.
What to use instead
For bulk mail, use a dedicated Email Service Provider (ESP):
- Transactional + bulk: Postmark, SendGrid, Mailgun, Amazon SES.
- Bulk only / marketing: Mailchimp, ConvertKit, ActiveCampaign, Klaviyo.
Configure your Drupal site to use the ESP via SMTP relay or the provider's Drupal module. BOA does not care which ESP you use; the site sends through the ESP's API and BOA's local mail stack is bypassed for those sends.
Configuring an SMTP relay (transactional mail)
Even transactional mail benefits from going through an SMTP relay, especially if
you would rather not manage SPF / DKIM / DMARC on the BOA host directly. In
/root/.barracuda.cnf:
_SMTP_RELAY_HOST="smtp.your-provider.example.com"
_SMTP_RELAY_HOST defaults to empty ("") — direct local delivery — until you
set it. This sets the Postfix relayhost, so it suits an unauthenticated
relay (an IP-allowlisted provider, or your own outbound smarthost). After
barracuda upgrade, outbound mail flows through the relay instead of direct
delivery — unless local sendmail is enabled for hosted sites (next section).
For a relay that needs authentication, _SMTP_RELAY_HOST is the wrong tool —
it carries no credentials. BOA ships aegir/tools/bin/smtpgapps, but note two
limits before relying on it:
- Gmail-only. It is hard-wired to Gmail: it validates the argument as a Gmail
address, requires the password to be a 16-lowercase-letter Gmail App Password,
and writes an
/etc/msmtprcfixed tosmtp.gmail.com:587. Any other provider needs/etc/msmtprchand-edited afterwards. - It does not route mail on its own.
smtpgappsonly writes/etc/msmtprc(plus its log and logrotate). It does not touch Postfix,_SMTP_RELAY_HOST, or PHP'ssendmail_path(every BOAphp.inikeepssendmail_path = /usr/sbin/sendmail -t -i, i.e. Postfix). So configuring msmtp alone changes nothing — PHPmail()and system mail still go through Postfix until an operator manually wires msmtp into the delivery path.
Relay vs. sites-allowed local sendmail — mutually exclusive
_smtp_check (lib/functions/system.sh.inc) sets the Postfix relayhost from
_SMTP_RELAY_HOST only while /etc/boa/.allow.sendmail.cnf is absent. That
file is the pre-existing box-wide control that re-opens /usr/sbin/sendmail for
hosted-site use — without it the binary is chmod 750 root:allow-snail and
sites cannot use local sendmail at all; with it, 755.
The gate is self-correcting both ways: if the allow file appears while a
relayhost is already active, the next check reverts the relayhost line back to
empty and reloads Postfix — direct (no-relay) delivery again. The rationale, per
the gate's own comment: routing through the relay re-stamps mail to the relay's
single sending domain, which is only safe while the host MTA carries solely
backend/system mail. Once the allow file is present, hosted-site PHP mail()
enters the same Postfix queue and would be re-stamped too.
Net effect: combining _SMTP_RELAY_HOST with sites-allowed local sendmail
yields direct delivery for everything — if you need the relay, do not create
the allow file. An empty relayhost despite _SMTP_RELAY_HOST being set is
this gate working by design, not a lost setting.
Let's Encrypt renewal notices to clients
One class of BOA-originated transactional mail goes to your clients, not to
you: the nightly maintenance run (the per-account owl.sh night worker,
aegir/tools/system/night/10-account.sh) emails an account's client
(_CLIENT_EMAIL from that account's /root/.<user>.octopus.cnf) an actionable
notice when Let's Encrypt renewal keeps failing for their site(s) — update the
domain's DNS, disable Encryption, or remove the dead alias.
- On by default. Only the literal
_LE_CLIENT_NOTIFY=NOdisables the notices (quotes/spaces stripped, case-insensitive) — set it globally in/root/.barracuda.cnfor per account in/root/.<user>.octopus.cnf; the per-account value wins. - Throttled to once per 7 days per failing site via marker files
<account>/log/ctrl/le-notify.<domain>.info(mtime-based; characters outside[a-zA-Z0-9._-]in the domain become_). - Skipped entirely when
_CLIENT_EMAILis empty or the localrootalias. - The mail (sent via s-nail; subject:
Action needed: HTTPS certificate renewal failed for one or more of your sites) carries aReply-Toof the account owner's address (_MY_OCTO_EMAIL, falling back to the server admin_ADMIN_EMAIL), set only when it is a real address containing@— so a client's reply reaches a human instead of bouncing off theroot@<host>envelope sender.
The worker reads only the account's own night log and that account's own
_CLIENT_EMAIL, so a notice can never be cross-attributed to another account's
client. For the full per-account LE failure reporting — the operator report,
_INCIDENT_REPORT gating, ACME error mapping — see
SSL operations.
Checking outbound mail volume
# Outbound mail queue (Postfix)
mailq
# Outbound mail log
tail -f /var/log/mail.log
If mailq grows, something is stuck or there is a delivery problem. If
mail.log shows hundreds of sends per minute on a low-traffic host, you have a
bulk-mail leak (probably an unintended Drupal notification flood).
Higher per-day mail volume
For self-hosted BOA you can configure higher thresholds — but the IP-reputation risk does not go away; use an ESP instead. For hosted-BOA, talk to omega8.cc support before any campaign.
Related
- Security model — the broader model the bulk-mail policy supports.
- Control files & INI —
_SMTP_RELAY_HOSTand the other/root/.barracuda.cnfmail settings. - SSL operations — the per-account Let's Encrypt renewal reporting the client notices are part of.
- Troubleshooting — debugging SMTP SSL errors.