Listeners
Stalwart Mail Server offers the ability to configure multiple listeners, which are responsible for receiving incoming TCP connections. There is no limit to the number of listeners that can be created, and the behavior of each listener can be customized by the administrator.
Bind settings
Listeners are set up in the configuration file using the server.listener.<id>.bind
attribute and specifying the IP addresses and ports where the listener will receive incoming connections. A listener can be bound to multiple IP v4 or v6 addresses and ports, for example:
[server.listener."smtp"]
bind = ["10.0.0.21:25", "10.0.0.22:25", "a:3f::2"]
Or, to bind a listener to all interfaces:
[server.listener."smtp"]
bind = "[::]:25"
Protocol
Listeners require the protocol
attribute to be set to the protocol that the listener should use to receive incoming connections:
jmap
: JMAP protocol.imap
: IMAP protocol.smtp
: SMTP protocol.lmtp
: LMTP protocol.managesieve
: ManageSieve protocol.https
: HTTP protocol, user for the SMTP management interface.
For example, to start an SMTP server on port 25 and an IMAP server on port 143, you can use the following configuration:
[server.listener."smtp"]
bind = ["[::]:25"]
protocol = "smtp"
[server.listener."imap"]
bind = ["[::]:143"]
protocol = "imap"
TLS settings
The default settings for the server's TLS configuration can be found under the server.tls
key and include the following options:
enable
: Specifies whether the listener should use TLS encryption for incoming connections. If set totrue
, the listener will require clients to connect using an encrypted connection.implicit
: Specifies whether the listener should use implicit or explicit TLS encryption. If set tofalse
(the default), the listener will use explicit TLS encryption, which requires clients to initiate aSTARTTLS
command before upgrading the connection to an encrypted one. If set totrue
, the listener will use implicit TLS encryption, which requires the connection to be encrypted from the start.timeout
: Specifies the amount of time the listener should wait for a client to initiate the TLS handshake before timing out the connection.certificate
: Specifies the name of the certificate to use for the listener. The certificate must be defined in thecertificate.<name>
section of the configuration file.sni
: Specifies a list of subject names and certificates that the listener should use based on the subject name presented by the client during the TLS handshake. This is useful in scenarios where multiple hostnames are hosted on a single IP address.protocols
: Specifies the list of TLS protocols that the listener should allow clients to use.ciphers
: Specifies the list of ciphers that the listener should allow clients to use. If left empty, the listener will use the default ciphers defined by the TLS library.ignore-client-order
: Specifies whether the listener should ignore the order of ciphers presented by the client and use the order specified in the ciphers option. If set tofalse
, the listener will use the order presented by the client.
Supported TLS versions
The following TLS versions are supported:
TLSv1.3
TLSv1.2
TLS 1.1 is not supported due to its inherent security vulnerabilities and its subsequent deprecation by major standards bodies and browsers. By focusing on more modern and secure protocols, Stalwart ensures robust encryption and the utmost security for its users' communications.
Supported cipher suites
The following TLS 1.3 cipher suites are supported:
TLS13_AES_256_GCM_SHA384
TLS13_AES_128_GCM_SHA256
TLS13_CHACHA20_POLY1305_SHA256
As well as the following TLS 1.2 cipher suites:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Supported exchange groups
The following exchange groups are supported:
X25519
SECP256R1
SECP384R1
Example
The following example defines two SNI subjects (otherdomain.org and otherdomain.net) and specifies the TLS protocols and ciphers to use:
[server.tls]
enable = true
implicit = false
timeout = "1m"
certificate = "default"
sni = [ { subject = "otherdomain.org", certificate = "otherdomain_org" },
{ subject = "otherdomain.net", certificate = "otherdomain_net" } ]
protocols = [ "TLSv1.2", "TLSv1.3" ]
ciphers = [ "TLS13_AES_256_GCM_SHA384", "TLS13_AES_128_GCM_SHA256",
"TLS13_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"]
ignore-client-order = true
It is possible to override the default TLS settings on a per-listener basis as detailed in the following sections.
Certificates
TLS certificates are defined in the configuration file under the certificate.<name>
key and require the following parameters:
cert
: The path or content of the TLS certificate file. This can either be directly embedded in the configuration file or referenced from an external file using thefile://
prefix.private-key
: The path or content of the TLS private key file. This should not be embedded directly in the configuration file, and instead be referenced from an external file using thefile://
prefix.
The following example defines a TLS certificate named default
with an embedded certificate and the contents of the private key read from a file:
[certificate."default"]
cert = '''-----BEGIN CERTIFICATE-----
MIIFCTCCAvGgAwIBAgIUCgHGQYUqtelbHGVSzCVwBL3fyEUwDQYJKoZIhvcNAQEL
...
0fR8+xz9kDLf8xupV+X9heyFGHSyYU2Lveaevtr2Ij3weLRgJ6LbNALoeKXk
-----END CERTIFICATE-----
'''
private-key = "file:///opt/stalwart-smtp/etc/private/tls.key"
Maximum connections
Listeners can be configured to limit the number of simultaneous connections that they can handle at any given moment. This setting is controlled by the server.max-connections
parameter in the configuration file:
[server]
max-connections = 8192
This value can also be overridden on a per-listener basis by setting the max-connections
parameter in the listener's configuration, for example:
[server.listener."submissions"]
bind = ["[::]:465"]
protocol = "smtp"
tls.implicit = true
max-connections = 1024
TCP socket options
The default TCP socket options for the server can be found under the server.socket
key and include the following options:
reuse-addr:
Specifies whether the socket can be bound to an address that is already in use by another socket. Setting this option totrue
allows the socket to reuse the address and helps reduce the number of errors caused by trying to bind to an address that is already in use.reuse-port
: Specifies whether multiple sockets can be bound to the same address and port. Setting this option totrue
allows multiple sockets to listen on the same port, which can be useful in some load balancing scenarios.backlog
: Specifies the maximum number of incoming connections that can be pending in the backlog queue. When the number of incoming connections exceeds this value, new connections may be rejected.ttl
: Specifies the time-to-live (TTL) value for the socket, which determines how many hops a packet can make before it is discarded.send-buffer-size
: Specifies the size of the buffer used for sending data. Increasing the size of the buffer can help improve the performance of the socket, but also increases memory usage.recv-buffer-size
: Specifies the size of the buffer used for receiving data. Increasing the size of the buffer can help improve the performance of the socket, but also increases memory usage.linger
: Specifies the time to wait before closing a socket when there is still unsent data. Setting this option to a non-zero value can help ensure that all data is sent before the socket is closed.tos
: Specifies the type of service (TOS) value for the socket, which determines the priority of the traffic sent through the socket.nodelay
: Specifies whether the Nagle algorithm should be disabled for the socket. Setting this option totrue
can help improve the performance of the socket, but may also increase network traffic.
It is possible to override the default TCP socket options on a per-listener basis as detailed in the following sections.
Overriding defaults
Both the TLS settings and TCP socket options can be customized for each listener individually by adding the desired attribute to the server.listener.<id>
key of that specific listener. For example, to override implicit TLS for a listener:
[server.listener."submissions"]
tls.implicit = true
[server.tls]
implicit = false
Or, to increase the backlog for a certain listener:
[server.listener."smtp"]
socket.backlog = 2048
[server.socket]
backlog = 1024
Example
The following example defines an SMTP listener on port 25
, an SMTP submissions listener on port 587
and a secure SMTP submissions listener on port 465
with implicit TLS enabled:
[server.listener."smtp"]
bind = ["[::]:25"]
protocol = "smtp"
[server.listener."submission"]
bind = ["[::]:587"]
protocol = "smtp"
[server.listener."submissions"]
bind = ["[::]:465"]
protocol = "smtp"
tls.implicit = true
[server.listener."management"]
bind = ["127.0.0.1:8080"]
protocol = "http"