Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions content/momentum/4/config-options-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ The `Version` column indicated the version(s) of Momentum that support the optio
| [pool_name](/momentum/4/esmtp-listener#esmtp_listener.config) – Associate a threadpool with a listener | receiving |   | 4.0 and later | control_listener, eccluster_listener, ecstream_listener, esmtp_listener, http_listener, listen, xmpp_listener |
| [prefer_ipv6_mxs](/momentum/4/config/ref-prefer_ipv6_mxs) - Prefer IPv6 addresses over IPv4 addresses at a given MX priority level | sending | false | 4.0 and later | global |
| [prohibited_hosts](/momentum/4/config/ref-prohibited-hosts) – Prevent mail from being delivered to invalid destinations | sending |   | 4.0 and later | global |
| [proxy_protocol](/momentum/4/config/ref-proxy-protocol) – Read the originating client address from a PROXY protocol header (version 1; version 2 headers since 5.4) | receiving | false | 4.2.11 and later | control_listener, ecstream_listener, esmtp_listener, http_listener, listen, peer, xmpp_listener |
| [proxy_protocol_timeout](/momentum/4/config/ref-proxy-protocol-timeout) – How long to wait for a complete PROXY protocol header | receiving | 60 | 4.2.11 and later | control_listener, ecstream_listener, esmtp_listener, http_listener, listen, peer, xmpp_listener |
| [rcptto_timeout](/momentum/4/config/ref-rcptto-timeout) – Timeout after RCPT TO | sending | 300 | 4.0 and later | binding, binding_group, domain, global |
| **received_hostname** – Hostname that is placed in the received headers; these are added to the messages as it transits Momentum | receiving |   | 4.0 and later | esmtp_listener, listen, pathway, pathway_group, peer |
| [reconfig_message](/momentum/4/esmtp-listener-reconfig-message) – Message if the configuration has changed | receiving | 4.3.2 Reconfiguration in progress | 4.0 and later | esmtp_listener |
Expand Down
44 changes: 44 additions & 0 deletions content/momentum/4/config/ref-proxy-protocol-timeout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
lastUpdated: "08/03/2026"
title: "Proxy_Protocol_Timeout"
description: "proxy protocol timeout sets how long a listener with proxy protocol enabled waits for a complete PROXY protocol header before closing the connection."
---

<a name="conf.ref.proxy_protocol_timeout"></a>
## Name

Proxy_Protocol_Timeout — how long to wait for a complete PROXY protocol header.

## Synopsis

`Proxy_Protocol_Timeout = 60`

<a name="idp.proxy_protocol_timeout"></a>
## Description

On a listener with [Proxy_Protocol](/momentum/4/config/ref-proxy-protocol) enabled, this is the number of seconds the listener waits for a complete header before closing the connection.

The timeout covers the header only. Once the header has been read, the connection continues under the listener's normal timeouts, such as [Idle_Time](/momentum/4/config/ref-idle-time).

The default value is `60`. A value of `0` disables the timeout, which is not recommended: a client that opens a connection and sends a partial header would then occupy a session slot indefinitely.

A header is a few dozen bytes sent immediately on connection, so it should arrive within one round trip. The generous default exists to tolerate unusual networks; lowering it to a few seconds reclaims slots faster from clients that connect and then stall. Because a held slot counts against [Listener_Sessions](/momentum/4/config/ref-listener-sessions) and [Service_Sessions](/momentum/4/config/ref-service-sessions), a long timeout combined with a low session cap lets stalled connections crowd out real mail.

## Example

```
ESMTP_Listener {
Listen "10.0.0.5:25" {
Proxy_Protocol = true
Proxy_Protocol_Timeout = 10
}
}
```

## Scope

Set on any listener with `Proxy_Protocol` enabled, or on an individual `Listen` endpoint. It has no effect where `Proxy_Protocol` is not enabled.

## See Also

[Proxy_Protocol](/momentum/4/config/ref-proxy-protocol), [Idle_Time](/momentum/4/config/ref-idle-time), [Listener_Sessions](/momentum/4/config/ref-listener-sessions)
80 changes: 80 additions & 0 deletions content/momentum/4/config/ref-proxy-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
lastUpdated: "08/03/2026"
title: "Proxy_Protocol"
description: "proxy protocol makes a listener read a PROXY protocol header from each incoming connection and use the client address it reports instead of the address of the proxy or load balancer that connected. The version 1 text format has been accepted since 4.2.11; the version 2 binary format is accepted since Momentum 5.4."
---

<a name="conf.ref.proxy_protocol"></a>
## Name

Proxy_Protocol — read the originating client address from a PROXY protocol header.

## Synopsis

`Proxy_Protocol = false`

<a name="idp.proxy_protocol"></a>
## Description

> **NOTE: version 2 headers require Momentum 5.4.** The option itself dates from Momentum 4.2.11, but until 5.4 it accepted only the version 1 text header. Momentum 5.4 is the next on-prem release; on 5.3 and earlier, a version 2 header is rejected and the connection is closed. See “Versions and automatic detection” below.

When a listener sits behind a proxy or load balancer, every connection appears to come from the proxy. `Proxy_Protocol` makes the listener read a [PROXY protocol](http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) header at the start of each connection and adopt the client address it reports.

That address is then the one Momentum uses everywhere it refers to the connecting client, including:

* policy decisions such as `Relay_Hosts` and `Peer` scope matching,
* SPF evaluation,
* the reception entry in the mainlog and the address reported to policy scripts,
* inbound concurrency accounting.

The default value is `false`.

### Versions and automatic detection

The protocol has two header formats, and support for them arrived at different times:

* **Version 1** is a line of text, as sent by older load balancers and by AWS Classic Load Balancers. It has been accepted since the option was introduced in Momentum 4.2.11.
* **Version 2** is a binary header, and is what current HAProxy (`send-proxy-v2`), AWS Network Load Balancers and Envoy send. It is accepted **since Momentum 5.4**. On earlier releases a version 2 header is not recognised, and such a connection is closed without a banner — the symptom of pointing a version 2 sender at a listener running 5.3 or earlier.

From 5.4 on, both formats are accepted on the same endpoint and the listener tells them apart from the first byte of the connection. Nothing needs to be configured to select one, and no configuration change is needed when an upstream proxy is switched from version 1 to version 2.

Version 2 headers may carry extra type-length-value fields after the addresses — for example the AWS VPC endpoint identifier. These are read and discarded; their contents are not available to policy.

### The header is required

Once `Proxy_Protocol` is enabled on a listener, every connection to it **must** begin with a valid header. A client that sends none, or sends a malformed one, is disconnected without a banner. Reserve the listener for traffic that arrives through the proxy, and give direct clients a separate `Listen` endpoint.

Some headers deliberately carry no client address, and are accepted with the real connecting address left in place:

* the version 2 `LOCAL` command, which proxies use for their own health checks,
* a version 1 `PROXY UNKNOWN` line,
* an address family the listener does not use for policy, such as UNIX sockets.

### Trust

There is no source-address allowlist. Any client that can reach a listener with `Proxy_Protocol` enabled can assert whatever client address it likes, which means it can present itself as a relay-permitted host or defeat an IP-based block.

Trust is therefore scoped entirely by *which* endpoint has the option enabled. Only enable it on endpoints reachable from the proxy — bind them to an internal address, or restrict them with a firewall or security group.

## Example

```
ESMTP_Listener {
# behind the load balancer: adopt the client address it reports
Listen "10.0.0.5:25" {
Proxy_Protocol = true
Proxy_Protocol_Timeout = 30
}

# direct submission, no header expected
Listen "127.0.0.1:587" {}
}
```

## Scope

`Proxy_Protocol` is available on any listener, not only the `ESMTP_Listener`, and may be set on the listener itself or on an individual `Listen` endpoint. Setting it per `Listen` endpoint is usually what you want, so that proxied and direct traffic can be served side by side.

## See Also

[Proxy_Protocol_Timeout](/momentum/4/config/ref-proxy-protocol-timeout), [Configuring Inbound Mail Service Using SMTP](/momentum/4/esmtp-listener), [ha_proxy_client](/momentum/4/modules/ha-proxy-client) for sending a PROXY protocol header on outbound connections.
20 changes: 19 additions & 1 deletion content/momentum/4/esmtp-listener.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
lastUpdated: "03/26/2020"
lastUpdated: "08/03/2026"
title: "Configuring Inbound Mail Service Using SMTP"
description: "The ESMTP Listener is the listener that enables you to inject message using SMTP Momentum can listen on any number of Unix domain sockets and or IP port addresses for TCP IP service The ESMTP Listener supports all of the extended properties and extensions described below The ESMTP Listener is..."
---
Expand Down Expand Up @@ -49,6 +49,24 @@ The `Pool_Name` option associates the `accept-pool` ThreadPool with the listener

When using threaded accepts for listeners, you must provision the thread pool you intend to use via the ThreadPool directive. If the thread pool you name is not found or is unspecified, the IO pool will be used and a critical message will appear in your log.

### <a name="esmtp_listener.proxy_protocol"></a> Accepting Connections Through a Proxy or Load Balancer

If the listener is fronted by a proxy or load balancer, set [Proxy_Protocol](/momentum/4/config/ref-proxy-protocol) on that endpoint so the originating client address is taken from the PROXY protocol header instead of showing the proxy for every connection.

The version 1 (text) header has been accepted since Momentum 4.2.11. The version 2 (binary) header, which current HAProxy, AWS Network Load Balancers and Envoy send, is accepted **since Momentum 5.4**; on earlier releases such a connection is closed without a banner. From 5.4 on both formats are detected automatically, so no additional option selects between them.

Once enabled the header is required on every connection to that endpoint, so serve direct clients from a separate `Listen` stanza. [Proxy_Protocol_Timeout](/momentum/4/config/ref-proxy-protocol-timeout) bounds how long an incomplete header is waited for.

```
ESMTP_Listener {
Listen "10.0.0.5:25" {
Proxy_Protocol = true
Proxy_Protocol_Timeout = 10
}
Listen "127.0.0.1:587" {}
}
```

### <a name="esmtp_listener.concurrency"></a> Limiting Inbound Concurrency

You can cap the number of concurrent inbound sessions with two options:
Expand Down
10 changes: 9 additions & 1 deletion content/momentum/4/listeners.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
lastUpdated: "03/26/2020"
lastUpdated: "08/03/2026"
title: "Listeners"
description: "Momentum is built around a powerful event based scheduling engine A key part of that engine is responding to events that occur on inbound sockets known as listeners These listeners are configured in Momentum's configuration files The following is an example of a basic listener syntax In this example the..."
---
Expand Down Expand Up @@ -127,6 +127,14 @@ Listens on port 25 of the IPv6 address.

For a detailed discussion of IPv6 syntax see [“Listeners and IPv6 Addresses”](/momentum/4/listeners#listeners.ipv6).

### <a name="listeners.proxy_protocol"></a> Listeners Behind a Proxy or Load Balancer

When a listener sits behind a proxy or load balancer, every connection appears to come from the proxy rather than from the originating client. Enable [Proxy_Protocol](/momentum/4/config/ref-proxy-protocol) on that endpoint to read the client address from the PROXY protocol header the proxy prepends, so that policy, SPF and logging all see the real client.

The version 1 text header has been accepted since Momentum 4.2.11; the version 2 binary header is accepted **since Momentum 5.4** and is rejected on earlier releases.

The header is mandatory once the option is enabled, so keep proxied and direct traffic on separate `Listen` endpoints, and see [Proxy_Protocol_Timeout](/momentum/4/config/ref-proxy-protocol-timeout) for how long an incomplete header is tolerated.

### <a name="listeners.unix.domain.listener.syntax"></a> Unix Domain Listener Address Syntax

The following is an example of a Unix listen address configuration:
Expand Down
Loading