docs: Revise `bind-smtp-network-interface.md`

This commit is contained in:
Brennan Kinney 2025-02-05 09:57:30 +13:00 committed by GitHub
parent 0e61f170fd
commit 146c1b5eca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 50 additions and 38 deletions

View File

@ -6,20 +6,27 @@ hide:
!!! warning "Advice not extensively tested" !!! warning "Advice not extensively tested"
This configuration advice is a community contribution which has only been verified as a solution when using `network: host`, where you have direct access to the host interfaces. This configuration advice is a community contribution.
It may be applicable in other network modes if the container has control of the outbound IPs to bind to. This is not the case with bridge networks that typically bind to a private range network for containers which are bridged to a public interface via Docker. If your Docker host has multiple public IPv4 or IPv6 IP addresses, it may be beneficial to bind outgoing SMTP connections to a specific IP.
If your Docker host is running multiple IPv4 and IPv6 IP-addresses, it may be beneficial to bind outgoing SMTP connections to specific IP-address / interface. When the IP address for DMS is inconsistent, it may fail to pass common security checks when interacting with other mail servers:
- When a mail is sent outbound from DMS, it greets the MTA it is connecting to with a EHLO (DMS FQDN) which might be verified against the IP resolved, and that a `PTR` record for that IP resolves an address back to the same IP. - When a mail is sent outbound from DMS, it connects to the external MTA and greets it with an EHLO (the DMS FQDN) which the MTA might verify that the EHLO address resolves to the same IP that DMS is connecting to the MTA from, and that a `PTR` record for that same IP resolves back to that same IP (_the `PTR` record address may not need to match the DMS FQDN_).
- A similar check with SPF can be against the envelope-sender address which may verify a DNS record like MX / A is valid (_or a similar restriction check from an MTA like [Postfix has with `reject_unknown_sender`][gh-pr::3465::comment-restrictions]_). - SPF is common requirement which verifies the SPF `TXT` DNS record for the _envelope sender address_ is valid when it references any DNS values (`MX`, `A`, `AAAA`).
- If the IP address is inconsistent for those connections from DMS, these DNS checks are likely to fail. - There may be other security checks handled by an MTA, like [Postfix supports with `reject_unknown_sender`][gh-pr::3465::comment-restrictions].
!!! note "IP addresses for documentation"
IP addresses shown in the below examples (`198.51.100.42` + `2001:DB8::42`) are placeholders, they are IP addresses reserved for documentation by IANA (_[RFC-5737 (IPv4)][rfc-5737] and [RFC-3849 (IPv6)][rfc-3849]_). Replace them with the IP addresses you want DMS to send mail through.
## Directly binding
This approach is for when the DMS container uses a [`network_mode`][docker-docs::compose-config::network-mode] / [`networks`][docker-docs::compose-config::networks] where the host IP is available to bind internally, such as [host][docker-docs::network-driver::host] and [macvlan][docker-docs::network-driver::macvlan].
This can be configured by [overriding the default Postfix configurations][docs::overrides-postfix] DMS provides. Create `postfix-master.cf` and `postfix-main.cf` files for your config volume (`docker-data/dms/config`). This can be configured by [overriding the default Postfix configurations][docs::overrides-postfix] DMS provides. Create `postfix-master.cf` and `postfix-main.cf` files for your config volume (`docker-data/dms/config`).
In `postfix-main.cf` you'll have to set the [`smtp_bind_address`][postfix-docs::smtp-bind-address-ipv4] and [`smtp_bind_address6`][postfix-docs::smtp-bind-address-ipv6] In `postfix-main.cf` you'll have to set the [`smtp_bind_address`][postfix-docs::smtp-bind-address-ipv4] and [`smtp_bind_address6`][postfix-docs::smtp-bind-address-ipv6] to the respective IP-address on the server you want to use.
to the respective IP-address on the server you want to use.
!!! example !!! example
@ -32,7 +39,9 @@ to the respective IP-address on the server you want to use.
!!! bug "Inheriting the bind from `main.cf` can misconfigure services" !!! bug "Inheriting the bind from `main.cf` can misconfigure services"
One problem when setting `smtp_bind_address` in `main.cf` is that it will be inherited by any services in `master.cf` that extend the `smtp` transport. One of these is `smtp-amavis`, which is explicitly configured to listen / connect via loopback (localhost / `127.0.0.1`). One problem when setting `smtp_bind_address` in `main.cf` is that it will be inherited by any services in `master.cf` that extend the `smtp` transport.
One of these is `smtp-amavis`, which is explicitly configured to listen / connect via loopback (`localhost` / `127.0.0.1`).
A `postfix-master.cf` override can workaround that issue by ensuring `smtp-amavis` binds to the expected internal IP: A `postfix-master.cf` override can workaround that issue by ensuring `smtp-amavis` binds to the expected internal IP:
@ -50,15 +59,17 @@ to the respective IP-address on the server you want to use.
smtp/inet/smtp_bind_address6 = 2001:DB8::42 smtp/inet/smtp_bind_address6 = 2001:DB8::42
``` ```
If that avoids the concern with `smtp-amavis`, you may still need to additionally override for the [`relay` transport][gh-src::postfix-master-cf::relay-transport] as well if you have configured DMS to relay mail. If that avoids the concern with `smtp-amavis`, you may still need to additionally override for the [`relay` transport][gh-src::postfix-master-cf::relay-transport] as well if you have configured DMS to send mail through a relay service.
=== "Bridged Networks" ## Bridged Networks
When your DMS container is using a bridge network, you'll instead need to restrict which IP address inbound and outbound traffic is routed through via the bridged interface. When your DMS container is using a bridge network, you'll instead need to restrict which IP address inbound and outbound traffic is routed through via the bridged interface.
!!! info
For **inbound** traffic, you may configure this at whatever scope is most appropriate for you: For **inbound** traffic, you may configure this at whatever scope is most appropriate for you:
- **Daemon:** Change the [default bind address][inbound-ip::docker-docs::daemon] configured in `/etc/docker/daemon.json` (default `0.0.0.0`) - **Daemon:** Change the [default bind address][inbound-ip::docker-docs::daemon] configured in `/etc/docker/daemon.json` (default `0.0.0.0`).
- **Network:** Assign the [`host_binding_ipv4` bridge driver option][inbound-ip::docker-docs::network] as shown in the below `compose.yaml` snippet. - **Network:** Assign the [`host_binding_ipv4` bridge driver option][inbound-ip::docker-docs::network] as shown in the below `compose.yaml` snippet.
- **Container:** Provide an explicit host IP address when [publishing a port][inbound-ip::docker-docs::container]. - **Container:** Provide an explicit host IP address when [publishing a port][inbound-ip::docker-docs::container].
@ -69,7 +80,7 @@ to the respective IP-address on the server you want to use.
- This IP address must belong to a network interface to be routed through it. - This IP address must belong to a network interface to be routed through it.
- IPv6 support via `host_ipv6` [requires at least Docker v25][outbind-ip::host-ipv6]. - IPv6 support via `host_ipv6` [requires at least Docker v25][outbind-ip::host-ipv6].
--- !!! example
Here is a `compose.yaml` snippet that applies the inbound + outbound settings to the default bridge network Docker Compose creates (_if it already exists, you will need to ensure it's re-created to apply the updated settings_): Here is a `compose.yaml` snippet that applies the inbound + outbound settings to the default bridge network Docker Compose creates (_if it already exists, you will need to ensure it's re-created to apply the updated settings_):
@ -83,9 +94,10 @@ to the respective IP-address on the server you want to use.
com.docker.network.host_ipv4: 198.51.100.42 com.docker.network.host_ipv4: 198.51.100.42
``` ```
!!! note "IP addresses for documentation" [docker-docs::network-driver::host]: https://docs.docker.com/engine/network/drivers/host
[docker-docs::network-driver::macvlan]: https://docs.docker.com/engine/network/drivers/macvlan
IP addresses shown in above examples (`198.51.100.42` + `2001:DB8::42`) are placeholders, they are IP addresses reserved for documentation by IANA (_[RFC-5737 (IPv4)][rfc-5737] and [RFC-3849 (IPv6)][rfc-3849]_). Replace them with the IP addresses you want DMS to send mail through. [docker-docs::compose-config::network-mode]: https://docs.docker.com/reference/compose-file/services/#network_mode
[docker-docs::compose-config::networks]: https://docs.docker.com/reference/compose-file/services/#networks
[docs::overrides-postfix]: ../../config/advanced/override-defaults/postfix.md [docs::overrides-postfix]: ../../config/advanced/override-defaults/postfix.md
[postfix-docs::smtp-bind-address-ipv4]: https://www.postfix.org/postconf.5.html#smtp_bind_address [postfix-docs::smtp-bind-address-ipv4]: https://www.postfix.org/postconf.5.html#smtp_bind_address