Postfix¶
Postfix uses Userli to decide
- which domains and mailboxes exist,
- where aliases go (including
postmaster@andabuse@), - which sender addresses a user may use,
- how many emails a user may send (SMTP quota),
- whether an SMTP client may authenticate (SASL).
The connection is made by the userli-postfix-adapter, a small Go service running next to Postfix. It implements the Postfix socketmap protocol, a policy server for rate limiting and a Dovecot-compatible SASL server.
flowchart LR
P[Postfix] -->|socketmap :10001| A[userli-postfix-adapter]
P -->|policy :10003| A
P -->|SASL :10006| A
A -->|HTTPS /api/postfix| U[Userli]
A --- R[(Redis)]
On the Userli host¶
Create an API token with the scope postfix:
bin/console app:api-token:create --name "Postfix" --scopes postfix
On the Postfix host¶
Run the adapter¶
Install the adapter from its releases or run its container image. It needs Redis for caching and rate limiting. Main settings:
| Variable | Description |
|---|---|
USERLI_BASE_URL |
URL of Userli, e.g. https://users.example.org |
USERLI_TOKEN |
API token with the postfix scope |
REDIS_URL |
Redis connection, e.g. redis://localhost:6379/0 |
SASL_LISTEN_ADDR |
Enables SMTP authentication, e.g. :10006 or /var/spool/postfix/private/auth |
POSTFIX_RECIPIENT_DELIMITER |
Your recipient_delimiter, e.g. + |
See the adapter README for all options and its metrics.
Lookups¶
virtual_mailbox_domains = socketmap:inet:localhost:10001:domain
virtual_mailbox_maps = socketmap:inet:localhost:10001:mailbox
virtual_alias_maps = socketmap:inet:localhost:10001:alias
smtpd_sender_login_maps = socketmap:inet:localhost:10001:senders
Deliver mail to Dovecot via LMTP, for example
virtual_transport = lmtp:unix:private/dovecot-lmtp.
To stop users from sending with addresses that don't belong to them, add
reject_sender_login_mismatch to smtpd_sender_restrictions on the
submission port.
SMTP authentication¶
smtpd_sasl_type = dovecot
smtpd_sasl_path = inet:localhost:10006
smtpd_sasl_auth_enable = yes
Authentication fails for deleted accounts and accounts that have to change their password. Accounts with the role Spam can authenticate, but the policy server limits what they can send. You can also use Dovecot's SASL server instead.
Rate limiting¶
smtpd_end_of_data_restrictions = check_policy_service inet:localhost:10003
The limits come from Userli: per user or alias, or the global default (see Admin Guide → Settings).
Sending restrictions¶
smtpd_recipient_restrictions =
check_policy_service inet:localhost:10003,
permit_sasl_authenticated,
reject_unauth_destination
For authenticated senders the adapter reads sending_allowed and
allowed_recipients from the SMTP quota response. If sending is not allowed,
the adapter rejects every recipient except the allowed ones. This is how
accounts with the role Spam can only write to the
support address. If Userli is
unreachable, the adapter defers the mail (450) instead of letting it pass.
Warning
Place the policy service before permit_sasl_authenticated. Without it,
accounts with the role Spam can send to anyone. Update the adapter and
Postfix before you upgrade Userli, because older adapters ignore these
fields.
Test¶
postmap -q "example.org" socketmap:inet:localhost:10001:domain
postmap -q "user@example.org" socketmap:inet:localhost:10001:mailbox
postmap -q "alias@example.org" socketmap:inet:localhost:10001:alias
postmap -q "user@example.org" socketmap:inet:localhost:10001:senders
Lookups are cached in Userli and in the adapter for a few minutes. Changes may take a short time to reach Postfix.