Differences between revisions 10 and 25 (spanning 15 versions)
Revision 10 as of 2023-05-26 16:06:32
Size: 7942
Comment:
Revision 25 as of 2025-02-18 00:07:17
Size: 5432
Comment: Tested an old draft, was not a useful revision
Deletions are marked like this. Additions are marked like this.
Line 52: Line 52:
== Usage ==

For unencrypted and unauthenticated connections, try a connection string like `smtp+insecure+none://example.com:25`.

----


Line 54: Line 62:
Before trying to configure Postfix, ensure that you understand the [[Postfix/Design|design]] of Postfix.

See also [[Postfix/Encryption|encryption]] and [[Postfix/Authentication|authentication]].
Line 58: Line 70:
Mail is received, routed, and queued by `master(8)`.

Set `myhostname` and `mydomain` to the fully-qualified names.
Set `myhostname` and `mydomain` to the fully-qualified names. Set `mydomains` to the set of all 'trusted' networks. Set `mydestination` to the set of all domains that should be considered 'local'.
Line 65: Line 75:
}}}

----



=== Local Delivery ===

`master(8)` interprets these addresses as local: `$myhostname`, `localhost.$mydomain`, and `localhost`. To override this, set `mydestination`.

{{{
mydestination = www1.$mydomain localhost localhost.localdomain
}}}

Alternatively, see '''Address Rewriting''' below and plan to re-route `$myhostname`.

If mail is destined for the local host, it is queued for `local(8)` to handle. (Any of `bounce(8)`, `defer(8)` or `trace(8)` may then be called.)

The local part of the email address is extracted and casefolded to lowercase.

Mail is delivered to a user-specific folder under `mail_spool_directory`, i.e. `/var/spool/mail/root`. (Alternatively, mail can be delivered into users' home directories via `home_mailbox`.) The following manipulations are made to locally-delivered mail:

 * prepend a `From SENDER DATETIME` envelope header
 * prepend an `X-Original-To:` header
 * prepend an `Delivered-To:` header
 * prepend a `Return-Path:` header
 * prepend a `>` character to lines beginning with `From `
 * append an empty line

Also, the mailbox is locked while delivery is in progress; if an error occurs, the mailbox is truncated to its original length. Delivery is executed with the permissions of the recipient.



==== Custom Delivery ====

A custom delivery command can be provided with `mailbox_command_maps` or `mailbox_command`.

In most cases, the command is executed with the recipient's permissions. If the recipient is `root`, a custom delivery command is executed with `default_privs`.



==== Qmail ====

For `qmail`-style mailboxes, the value of `mail_spool_directory` or `home_mailbox` must end in a forward slash (`/`).

{{{
home_mailbox = Maildir/
}}}

The following manipulations are made to locally-delivered `qmail`-style mail:
 * prepend a `Delivered-To:` header
 * prepend an `X-Original-To:` header
 * prepend a `Return-Path:` header

----



=== Forwarding ===

When attempting delivery, `forward_path` is scanned for a `forward(5)` file (i.e. `~/.forward`). These looks like:

{{{
[email protected] # anything after # is ignored
"|/path/to/examplemda"
}}}

Forwarded mail is sent as a new message with the `Delivered-To:` header, to prevent loops.

Note that the second line is only allowable if `allow_mail_to_commands` is set to:

{{{
allow_mail_to_commands = alias,forward,include
}}}

The default `alias,forward` disallows custom commands.

----



=== Routing ===
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
mydestination = $myhostname $mydomain www.$mydomain localhost localhost.localdomain
}}}

By default mail is only accepted...

 * from clients in trusted networks (`$mynetworks`)
 * from clients that authenticated with SASL
 * for remote addresses matching `$relay_domains`
 * for local addresses found in `$mydestination` (defaulting to `$myhostname`, `localhost.$mydomain`, and `localhost`)

To adjust restrictions, try configuring `smtpd_relay_restrictions` or (the older and less-preferred method) `smtpd_recipient_restrictions`.



=== Routing Mail ===
Line 166: Line 110:
The first part of each line is a pattern. The second part is an instruction beginning with `local`, `lmtp`, `smtp`, or `relay`. The `local` instruction expands to the `local_transport` setting, which itself defaults to `local:$myhostname`. Bracketing an address prevents a MX record lookup; the A record alone is looked up and used naively. The first part of each line is a pattern. The second part is an instruction:

 * a `local` instruction attempts [[Postfix/LocalDelivery|local delivery]] to the specified address
   * a bare `local` instruction expands to the `local_transport` setting, which itself defaults to `local:$myhostname`
 * a `lmtp` instruction forwards mail to an [[Email/LMTP|LMTP]] server
 * a `smtp` instruction forwards mail to an [[Email/SMTP|SMTP]] server
 * a `relay` instruction causes mail to [[Postfix/Relaying|relayed]]

Bracketing an address prevents a [[Protocols/DNS#Records|MX record]] lookup; the [[Protocols/DNS#Records|A record]] alone is looked up and used naively. If even A record lookup should be skipped (i.e. for a name defined in the [[Linux/Hosts|hosts file]]), additionally specify `smtp_dns_support_level = disabled`.
Line 178: Line 130:
==== Relaying ====

The `relay` instruction in a `transport(5)` file causes mail to be relayed to another SMTP server.

Use of a relay server often requires authentication and encryttion. Try:

{{{
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl/sasl_passwd
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
}}}

`/etc/postfix/sasl/sasl_passwd` should look like:

{{{
[smtp.gmail.com]:587 [email protected]:wwwwxxxxyyyyzzzz
}}}

Run `postmap /etc/postfix/sasl/sasl_passwd` and a hashed file will be produced. If your `postmap(1)` does not use LMDB, replace the `lmdb:` with whatever algorithm ''was'' used.

----


Line 206: Line 132:
To rewrite addresses as they are received, try:

{{{
smtp_generic_maps = lmdb:/etc/postfix/generic
}}}

A `generic(5)` file (i.e. `/etc/postfix/generic`) looks like:

{{{
root@localdomain [email protected]
root [email protected]
@localdomain [email protected]
}}}

The first part of each line is a pattern. The second part is the address that overwrites a matching address.

Note the second line only rewrites addresses using a domain in `$myorigin`, `$mydestination`, `$inet_interfaces`, or `$proxy_interfaces`. The matching also happens in that hierarchical order: by full address, then by local part, then by domain part.

Run `postmap /etc/postfix/generic` and a hashed file will be produced. If your `postmap(1)` does not use LMDB, replace the `lmdb:` with whatever algorithm ''was'' used.

----
See [[Postfix/Rewriting|here]].
Line 232: Line 138:
`master(8)` expects mail posted locally to use `myhostname` as the sender's domain. To override this, set `myorigin`. `master(8)` expects mail posted locally to use `$myhostname` as the sender's domain. To override this, set `myorigin`.

Postfix

postfix(1) is an SMTP mail transfer agent.


Installation

Most Linux and BSD distributions offer a postfix package.

For systemd-capable systems, start and enable postfix.service.

For BSD distributions, try:

postfix start

Containers

postfix(1) is designed to be launched from userspace, rather than being a binary that can be invoked in the foreground. However, a new start-fg subcommand was added in version 3.3.

Consider the following Dockerfile as a template.

FROM alpine:latest
RUN apk add --no-cache postfix
EXPOSE 25
CMD ["postfix", "start-fg"]

To publish this service on an interface like 10.0.0.1, try:

sudo docker build --tag postfix .
sudo docker run --detach --name my-postfix \
  --restart=always \
  --publish 10.0.0.1:25:25 \
  postfix


Usage

For unencrypted and unauthenticated connections, try a connection string like smtp+insecure+none://example.com:25.


Configuration

Before trying to configure Postfix, ensure that you understand the design of Postfix.

See also encryption and authentication.

Receiving Mail

Set myhostname and mydomain to the fully-qualified names. Set mydomains to the set of all 'trusted' networks. Set mydestination to the set of all domains that should be considered 'local'.

myhostname = www1.example.com
mydomain = example.com
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
mydestination = $myhostname $mydomain www.$mydomain localhost localhost.localdomain

By default mail is only accepted...

  • from clients in trusted networks ($mynetworks)

  • from clients that authenticated with SASL
  • for remote addresses matching $relay_domains

  • for local addresses found in $mydestination (defaulting to $myhostname, localhost.$mydomain, and localhost)

To adjust restrictions, try configuring smtpd_relay_restrictions or (the older and less-preferred method) smtpd_recipient_restrictions.

Routing Mail

To route mail based on the recipient domain, try:

transport_maps = lmdb:/etc/postfix/transport

A transport(5) file (i.e. /etc/postfix/transport) looks like:

admin@localhost      relay:[smtp.gmail.com]:587
service1.example.com lmtp:unix:/path/to/service.sock
example.com          lmtp:0.0.0.0:24
.example.com         lmtp:0.0.0.0:24
localhost            local
.localdomain         local
*                    relay:[smtp.gmail.com]:587

The first part of each line is a pattern. The second part is an instruction:

  • a local instruction attempts local delivery to the specified address

    • a bare local instruction expands to the local_transport setting, which itself defaults to local:$myhostname

  • a lmtp instruction forwards mail to an LMTP server

  • a smtp instruction forwards mail to an SMTP server

  • a relay instruction causes mail to relayed

Bracketing an address prevents a MX record lookup; the A record alone is looked up and used naively. If even A record lookup should be skipped (i.e. for a name defined in the hosts file), additionally specify smtp_dns_support_level = disabled.

Domains prefixed with a dot (.) are a pattern for all subdomains. The example above captures localhost and *.localdomain for local delivery.

The asterisk (*) domain is a fallback route, used only if nothing else matches.

The matching happens in the hierarchical order shown above: by full address, then by full domain part, then by subdomain part, and finally the fallback.

Run postmap /etc/postfix/transport and a hashed file will be produced. If your postmap(1) does not use LMDB, replace the lmdb: with whatever algorithm was used.

Address Rewriting

See here.

Posting Mail

master(8) expects mail posted locally to use $myhostname as the sender's domain. To override this, set myorigin.

myorigin = $mydomain


Administration

Testing the service

Install mailx and send an empty email.

To test mail relay to external hosts, try:

mail -s 'Test Email' '[email protected]' </dev/null

Alternatively, try using telnet.

Reviewing the queue

Two useful administrative utilities exist for reviewing the mail queue: postqueue(1) and postcat(1).

To view the mail queue, try:

postqueue -p

This will display the queued messages, the senders and recipients, and a mail ID.

To force all queued mail to be sent now, run:

postqueue -f

To instead force a singular message to be send now, run:

postqueue -i MAILID

To instead inspect a message in the queue, try:

postcat -vq MAILID


See also

postfix(1)

Postfix project documentation


CategoryRicottone

Postfix (last edited 2025-02-18 00:11:40 by DominicRicottone)