# Postfix MailBaby Smarthost on Ubuntu and Debian: Secure Setup

Source: https://srvscripts.com/guides/postfix-mailbaby-smarthost-ubuntu-debian/
Updated: 2026-10-03
Publisher: srvScripts (https://srvscripts.com/)

Plain Ubuntu and Debian servers, whether they run a web application, a monitoring stack or a panel-free hosting setup, usually send mail straight from their own IP with a Postfix default install. That works until the IP lands on a blocklist. Pointing Postfix at MailBaby takes ten minutes and gives every application on the box a filtered, reputation-managed outbound path. This tutorial covers the relayhost, SASL credentials, TLS settings and a rate limit that keeps you under MailBaby’s hourly cap.

In short: Install libsasl2-modules, put [relay.mailbaby.net]:25 mbXXXXX:PASSWORD in /etc/postfix/sasl_passwd, run postmap on it, and set relayhost = [relay.mailbaby.net]:25, smtp_sasl_auth_enable = yes, smtp_sasl_password_maps =…

**Short answer:** Install `libsasl2-modules`, put `[relay.mailbaby.net]:25 mbXXXXX:PASSWORD` in `/etc/postfix/sasl_passwd`, run `postmap` on it, and set `relayhost = [relay.mailbaby.net]:25`, `smtp_sasl_auth_enable = yes`, `smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd`, `smtp_sasl_security_options = noanonymous`, `smtp_sasl_mechanism_filter = login` and `smtp_tls_security_level = may` with `postconf -e`, then reload Postfix. Rewrite local senders to an authorised domain, add `smtp_destination_rate_delay = 1s` to stay under the 6,000 per hour cap, and sign with OpenDKIM so recipients see your domain rather than MailBaby’s.

## Install the SASL module

Postfix needs the Cyrus SASL client library to authenticate to the relay. On both distributions:

```
apt update
apt install postfix libsasl2-modules
```

If Postfix is being installed fresh, choose “Internet Site” and enter the server’s fully qualified hostname when prompted. The hostname must have forward and reverse DNS, because MailBaby reads it in the HELO.

## Store the credentials

Create `/etc/postfix/sasl_passwd` containing one line: the relay host as Postfix will look it up, followed by the MailBaby username and password. The username is the bare `mbXXXXX` account name with no domain part.

```
[relay.mailbaby.net]:25    mb12345:YOUR_PASSWORD
```

The square brackets and port must match the `relayhost` value exactly, including the brackets. Then hash the file and lock the permissions:

```
postmap /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
```

Re-run `postmap` every time you edit the file; Postfix reads the `.db`, not the text.

## Configure main.cf

Apply the settings with `postconf` so they land correctly regardless of what the distribution’s default file contains:

```
postconf -e 'relayhost = [relay.mailbaby.net]:25'
postconf -e 'smtp_sasl_auth_enable = yes'
postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'
postconf -e 'smtp_sasl_security_options = noanonymous'
postconf -e 'smtp_sasl_mechanism_filter = login'
postconf -e 'smtp_tls_security_level = may'
postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt'
postconf -e 'smtp_tls_loglevel = 1'
```

Each line matters. The brackets around the hostname stop Postfix doing an MX lookup on `relay.mailbaby.net`. `noanonymous` prevents Postfix trying an anonymous mechanism first. `smtp_sasl_mechanism_filter = login` restricts the client to LOGIN, which is what MailBaby offers; without it Postfix may pick a mechanism the server does not advertise and fail with “no mechanism available”. `smtp_tls_security_level = may` enables opportunistic STARTTLS, which MailBaby requires before it will accept AUTH. If you prefer a hard requirement so that a downgrade can never happen, set it to `encrypt` instead; the relay always offers TLS so nothing breaks.

Reload:

```
systemctl reload postfix
```

## Keep the envelope sender sane

MailBaby validates the envelope sender’s domain against your authorised domains. Cron jobs and system daemons send as `root@hostname`, which is fine as long as the hostname’s domain is authorised, but a bare `root@localhost` will be rejected. Set the origin explicitly and rewrite local users:

```
postconf -e 'myorigin = example.com'
postconf -e 'sender_canonical_maps = hash:/etc/postfix/sender_canonical'
```

With `/etc/postfix/sender_canonical` containing:

```
root    alerts@example.com
www-data    noreply@example.com
```

Run `postmap /etc/postfix/sender_canonical` afterwards. Then add `include:spf-c.mailbaby.net` to the SPF record for `example.com`, as described in [the SPF guide](/guides/mailbaby-spf-record-domain-verification/).

## Stay under the hourly limit

MailBaby discards anything over 6,000 messages per hour from a single sender address rather than queueing it. Postfix can pace deliveries to the relay so a burst is spread out:

```
postconf -e 'smtp_destination_concurrency_limit = 4'
postconf -e 'smtp_destination_rate_delay = 1s'
postconf -e 'default_destination_recipient_limit = 50'
```

A one-second delay between deliveries to the same destination caps a single queue runner at roughly 3,600 messages per hour, with headroom for concurrent runners. Tune the delay to your real volume; an application that sends 200 messages a day does not need it, while a notification system that can burst thousands does.

## DKIM signing

Sign locally so that recipients see your domain in `Authentication-Results` rather than MailBaby’s. Install `opendkim`, generate a key for `example.com`, and add the milter to Postfix:

```
apt install opendkim opendkim-tools
opendkim-genkey -b 2048 -d example.com -s mail -D /etc/opendkim/keys/
postconf -e 'smtpd_milters = inet:127.0.0.1:8891'
postconf -e 'non_smtpd_milters = inet:127.0.0.1:8891'
postconf -e 'milter_default_action = accept'
```

Publish the contents of `mail.txt` as the `mail._domainkey` TXT record. MailBaby passes the signature through unchanged. Why that matters is covered in [the DKIM transport signing guide](/guides/mailbaby-dkim-transport-signing/).

## Verify

Send a message and watch the log:

```
echo "relay test" | mail -s "Postfix via MailBaby" you@example.org
tail -f /var/log/mail.log
```

A good delivery shows `relay=relay.mailbaby.net[IP]:25` and `status=sent (250 ...)`. Just before it you should see a line beginning `Trusted TLS connection established to relay.mailbaby.net`. Confirm authentication actually happened with `postconf -n | grep sasl` and check the received message’s headers for `spf=pass` and `dkim=pass`. The common pitfall is an edited `sasl_passwd` without a fresh `postmap`, which produces `SASL authentication failed; server relay.mailbaby.net said: 535` in the log while the text file looks correct. Run `postqueue -p` to see anything stuck and `postqueue -f` to retry once the credentials are fixed.

## Postfix MailBaby smarthost at a glance

**Official documentation:** [RFC 5321 (SMTP)](https://www.rfc-editor.org/rfc/rfc5321), [AlmaLinux wiki](https://wiki.almalinux.org/), [Linux man pages](https://man7.org/linux/man-pages/).

**Related guides:** [Warm up a new mail server IP or sending domain without landing in spam](https://srvscripts.com/guides/warm-up-new-mail-server-ip-domain/) · [Newsletters and mailing lists through MailBaby: staying under the 6,000/hour limit and out of spam folders](https://srvscripts.com/guides/mailbaby-newsletter-sending-limit/) · [MailBaby DKIM transport signing explained: why some mail shows “via mailbaby.net”](https://srvscripts.com/guides/mailbaby-dkim-transport-signing/).

## Frequently asked questions

### Why does Postfix say “no mechanism available” when authenticating to MailBaby?

Postfix picked a SASL mechanism the relay does not advertise, or the Cyrus client modules are missing. Install `libsasl2-modules`, set `smtp_sasl_mechanism_filter = login` so only LOGIN is tried, and confirm `smtp_sasl_security_options = noanonymous` so an anonymous mechanism is never attempted first.

### Does MailBaby require TLS from Postfix?

Yes. MailBaby refuses AUTH on an unencrypted session, so `smtp_tls_security_level` must be at least `may` for opportunistic STARTTLS. Setting it to `encrypt` makes TLS mandatory and is safe because the relay always offers it.

### Why are cron emails from root rejected by MailBaby?

The envelope sender is `root@localhost` or a hostname whose domain is not authorised on your account. Set `myorigin` to an authorised domain and use `sender_canonical_maps` to rewrite `root` and `www-data` to real addresses on that domain, then make sure its SPF record includes `spf-c.mailbaby.net`.
