This is an automated email from the ASF dual-hosted git repository. Arsnael pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit c7408253d958eba594d7d520fc36304500ec291d Author: Felix Auringer <[email protected]> AuthorDate: Fri May 15 10:17:48 2026 +0200 refactor(docs): completely rewrite docs for IMAP, SMTP, LMTP, ManageSieve, POP3, and TLS This includes the following major corrections: IMAP: - `auth.requireSSL`: This does not enforce TLS for authentication with OIDC - `disabledCaps`: Make clear that capabilities are enabled but only not advertised - Negative values for `timeout` throw an error. - Option `provisionDefaultMailboxes` was undocumented. POP3: - Properly document `handlerchain`. ManageSieve: No major corrections. SMTP: - Properly document `handlerchain`. - `authRequired` does not enforce authentication. - `auth.announce` influences announcement for PLAIN/LOGIN but disables OIDC. - `auth.requireSSL` only disallows clear text for OIDC. - `disabledFeatures`: Make clear that the features are not disabled. - Update security recommendations and add some warnings. LMTP: - Properly document `handlerchain`. TLS: - Document all options. - Strongly recommend to use implicit TLS everywhere except port 25. - Update commands for PEM and keystore certs. - Add some examples for using ACME clients for proper certificates. --- docs/modules/servers/partials/configure/imap.adoc | 409 +++++++++----------- docs/modules/servers/partials/configure/pop3.adoc | 82 +--- docs/modules/servers/partials/configure/sieve.adoc | 88 +---- docs/modules/servers/partials/configure/smtp.adoc | 425 +++++++++------------ docs/modules/servers/partials/configure/ssl.adoc | 422 ++++++++++++-------- .../apache/james/imapserver/netty/IMAPServer.java | 2 +- 6 files changed, 661 insertions(+), 767 deletions(-) diff --git a/docs/modules/servers/partials/configure/imap.adoc b/docs/modules/servers/partials/configure/imap.adoc index b482fc6d59..daaa86acce 100644 --- a/docs/modules/servers/partials/configure/imap.adoc +++ b/docs/modules/servers/partials/configure/imap.adoc @@ -1,224 +1,177 @@ -Consult this link:{sample-configuration-prefix-url}/imapserver.xml[example] -to get some examples and hints. +Consult this link:{sample-configuration-prefix-url}/imapserver.xml[example] for guidance on how to configure IMAP. -The IMAP4 service is controlled by a configuration block in the imap4server.xml. -The imap4server tag defines the boundaries of the configuration block. It encloses -all the relevant configuration for the IMAP4 server. The behavior of the IMAP4 service is -controlled by the attributes and children of this tag. +The IMAP service is configured in the file `imapserver.xml`. +It contains one `imapservers` element that can contain multiple `imapserver` elements. -This tag has an optional boolean attribute - *enabled* - that defines whether the service is active or not. -The value defaults to "true" if not present. +The `imapserver` element can be configured using the common options described xref:{pages-path}/configure/server.adoc[here]. +Additional settings are described below. -The standard children of the imapserver tag are: - -.imapserver.xml content +.`imapserver` element |=== -| Property name | explanation - -| bind -| Configure this to bind to a specific inetaddress. This is an optional integer value. This value is the port on which this IMAP4 server is configured -to listen. If the tag or value is absent then the service -will bind to all network interfaces for the machine If the tag or value is omitted, the value will default to the standard IMAP4 port -port 143 is the well-known/IANA registered port for IMAP -port 993 is the well-known/IANA registered port for IMAPS ie over SSL/TLS - -| connectionBacklog -| Number of connection backlog of the server (maximum number of queued connection requests) - -| compress -| true or false - Use or don't use COMPRESS extension. Defaults to false. - -| maxLineLength -| Maximal allowed line-length before a BAD response will get returned to the client -This should be set with caution as a to high value can make the server a target for DOS (Denial of Service)! - -| inMemorySizeLimit -| Optional. Size limit before we will start to stream to a temporary file. -Defaults to 10MB. Must be a positive integer, optionally with a unit: B, K, M, G. - -| literalSizeLimit -| Optional. Maximum size of a literal (IMAP APPEND). -Defaults to 0 (unlimited). Must be a positive integer, optionally with a unit: B, K, M, G. - -| plainAuthDisallowed -| Deprecated. Should use `auth.plainAuthEnabled`, `auth.requireSSL` instead. -Whether to enable Authentication PLAIN if the connection is not encrypted via SSL or STARTTLS. Defaults to `true`. - -| auth.plainAuthEnabled -| Whether to enable Authentication PLAIN/ LOGIN command. Defaults to `true`. - -| auth.requireSSL -| true or false. Defaults to `true`. Whether to require SSL to authenticate. If this is required, the IMAP server will disable authentication on unencrypted channels. - -| auth.oidc.oidcConfigurationURL -| Provide OIDC url address for information to user. Only configure this when you want to authenticate IMAP server using a OIDC provider. - -| auth.oidc.jwksURL -| Provide url to get OIDC's JSON Web Key Set to validate user token. Only configure this when you want to authenticate IMAP server using a OIDC provider. - -| auth.oidc.claim -| Claim string uses to identify user. E.g: "email_address". Only configure this when you want to authenticate IMAP server using a OIDC provider. - -| auth.oidc.scope -| An OAuth scope that is valid to access the service (RF: RFC7628). Only configure this when you want to authenticate IMAP server using a OIDC provider. - -| auth.oidc.aud -| An OAuth audience to access the service (RF: RFC7628). Only configure this when you want to authenticate IMAP server using a OIDC provider. -Compulsory but can be relaxed with `-Djames.sasl.oidc.validate.aud=false` - -| auth.oidc.introspection.url -| Optional. An OAuth introspection token URL will be called to validate the token (RF: RFC7662). -Note that James always verifies the signature of the token even whether this configuration is provided or not. - -| auth.oidc.introspection.auth -| Optional. Provide Authorization in header request when introspecting token. -Eg: `Basic xyz` - -| auth.oidc.userinfo.url -| Optional. An Userinfo URL will be called to retrieve additional user information -(RF: OpenId.Core https://openid.net/specs/openid-connect-core-1_0.html). - -| auth.adminUsers.adminUser -| XML list of administrators able to impersonate any IMAP users. This is typically enable on non publicly exposed IMAP servers eg port 994 for admin support or migration. - -| timeout -| Default to 30 minutes. After this time, inactive channels that have not performed read, write, or both operation for a while -will be closed. Negative value disable this behaviour. - -| enableIdle -| Default to true. If enabled IDLE commands will generate a server heartbeat on a regular period. - -| idleTimeInterval -| Defaults to 120. Needs to be a strictly positive integer. - -| idleTimeIntervalUnit -| Default to SECONDS. Needs to be a parseable TimeUnit. +| Property Name | Explanation + +| `compress` +| Enables / Disables the IMAP COMPRESS extension +It is an optional boolean that defaults to `false`. + +| `maxLineLength` +| Sets the maximal allowed line-length. +If a request is too long, a BAD response is returned to the client. +This should be set with caution as larger values make the server more susceptible for denial of service attacks. +If OIDC is used, it must be relative large as the encoded access tokens can become quite large. +It is an optional integer with a generous default of 65536. +The default should be enough for all applications, even when using OIDC. + +| `inMemorySizeLimit` +| Sets a memory limit for incoming IMAP messages. +If a message is too large, it is streamed to a temporary file. +It is an optional value with a default of `10M` (10 mebibytes). +The last character of the value may be a unit. +Supported units are `B` for bytes, `K` for kibibyte (1,024 bytes), `M` for mebibyte (1,024 kibibytes), and `G` for gibibyte (1,024 mebibytes). +If no unit is given, the value is interpreted as bytes. + +| `literalSizeLimit` +| Sets a hard size limit for IMAP literals and incoming IMAP messages. +If exceeded, an exception is thrown. +This value is communicated to the client via the IMAP APPENDLIMIT extension. +It is optional and defaults to 0 (unlimited). +Unit parsing is the same as with `inMemorySizeLimit` above. + +| `timeout` +| Sets a timeout for connections. +If no read or write operations have been performed in this time, the connection is closed. +Optional integer in seconds that defaults to 1,800 (30 minutes). +The timeout can not be shorter than 30 minutes. + +| `auth` +| Configures user authentication. +More details of this element are given below. + +| `plainAuthDisallowed` +| Deprecated. If `auth.requireSSL` is not present, this is used as fallback. +It is an optional boolean that defaults to `true`. + +| `ignoreIDLEUponProcessing` +| Disables sending heartbeats to the client while processing its request. +It is an optional boolean that defaults to `true`. + +| `disabledCaps` +| Removes capabilities from the response of the IMAP CAPABILITY command. +This is an optional, pipe-separated list of strings. +By default, no capabilities are omitted. +Note that this only removes the capabilities from the response, it does not disable the capabilities! +It prevents standard-conformant clients from using commands that only work with the disabled capabilities but **it is not a security feature**. + +| `enableIdle` +| Allows the client to request live updates via the IMAP IDLE command. +It is an optional boolean that defaults to `true`. + +| `idleTimeInterval` +| Sets the interval in which the server sends heartbeats after the client issued an IDLE command. +If `enableIdle` is `false`, this has no effect. +It is an optinal integer that defaults to 120. + +| `idleTimeIntervalUnit` +| Sets the unit of `idleTimeInterval`. +If `enableIdle` is `false`, this has no effect. +It is an optional value which must be a parseable `TimeUnit` and defaults to `SECONDS`. + +| `maxQueueSize` +| Sets an upper bound for the IMAP throttler queue. +Requests that can not be queued are rejected and not executed. +It is an optional integer that defaults to 4,096. +A value of 0 disables the queue. + +| `concurrentRequests` +| Sets the maximum number of IMAP requests that are executed simultaneously. +All requests past that limit are queued. +It is an optional Integer that defaults to 20. +A negative value deactivates this feature and leads to unbounded concurrency. + +| `provisionDefaultMailboxes` +| Enables the provision of additional mailboxes. +By default, only `INBOX` is created. +If `true`, James additionally creates the mailboxes `Outbox`, `Sent`, `Trash`, `Drafts`, `Archive`, and `Spam` on first login of a user. +It is an optional boolean which defaults to `true`. + +| `idCommandResponse` +| Configures the server response to the IMAP ID command. +It is an optional element containing up to 30 `field` elements. +Every `field` element must have the attributes `name` and `value`. +See RFC 2971 for more details. -| disabledCaps -| Implemented server capabilities NOT to advertise to the client. Coma separated list. Defaults to no disabled capabilities. - -| jmxName -| The name given to the configuration - -| tls -| Set to true to support STARTTLS or SSL for the Socket. -To use this you need to copy sunjce_provider.jar to /path/james/lib directory. To create a new keystore execute: -`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore /path/to/james/conf/keystore`. -Please note that each IMAP server exposed on different port can specify its own keystore, independently from any other -TLS based protocols. - -| handler.helloName -| This is the name used by the server to identify itself in the IMAP4 -protocol. If autodetect is TRUE, the server will discover its -own host name and use that in the protocol. If discovery fails, -the value of 'localhost' is used. If autodetect is FALSE, James -will use the specified value. - -| connectiontimeout -| Connection timeout in seconds - -| connectionLimit -| Set the maximum simultaneous incoming connections for this service - -| connectionLimitPerIP -| Set the maximum simultaneous incoming connections per IP for this service - -| concurrentRequests -| Maximum number of IMAP requests executed simultaneously. Past that limit requests are queued. Defaults to 20. -Negative values deactivate this feature, leading to unbounded concurrency. - -| maxQueueSize -| Upper bound to the IMAP throttler queue. Upon burst, requests that cannot be queued are rejected and not executed. -Integer, defaults to 4096, must be positive, 0 means no queue. - -| proxyRequired -| Enables proxy support for this service for incoming connections. HAProxy's protocol -(https://www.haproxy.org/download/2.7/doc/proxy-protocol.txt) is used and might be compatible -with other proxies (e.g. traefik). If enabled, it is *required* to initiate the connection -using HAProxy's proxy protocol. - -| proxyFirst -| Whether proxy frames should be handled before SSL handshakes. This allows setting either the loadbalancer in TCP mode -(so transparent for SSL then Proxy frames needs to be handled first) or set up SSL termination between proxy and server -(more suited for some cloud vendors). Defaults to true (TCP transparent). +|=== -| bossWorkerCount -| Set the maximum count of boss threads. Boss threads are responsible for accepting incoming IMAP connections -and initializing associated resources. Optional integer, by default, boss threads are not used and this responsibility is being dealt with -by IO threads. +== Authentication -| ioWorkerCount -| Set the maximum count of IO threads. IO threads are responsible for receiving incoming IMAP messages and framing them -(split line by line). IO threads also take care of compression and SSL encryption. Their tasks are short-lived and non-blocking. -Optional integer, defaults to 2 times the count of CPUs. +The `auth` element mentioned above has the following options. -| ignoreIDLEUponProcessing -| true or false - Allow disabling the heartbeat handler. Defaults to true. +.`auth` element +|=== +| Property Name | Explanation -| useEpoll -| true or false - If true uses native EPOLL implementation for Netty otherwise uses NIO. Defaults to false. +| `auth.plainAuthEnabled` +| Enables the authentication mechanisms `PLAIN` and `LOGIN`. +It is an optional boolean that defaults to `true`. -| gracefulShutdown -| true or false - If true attempts a graceful shutdown, which is safer but can take time. Defaults to true. +| `auth.requireSSL` +| Configures whether the authentication mechanisms `PLAIN` and `LOGIN` require a secure connection (TLS or STARTTLS). +It has no effect on other authentication mechanisms. +It also has no effect if `plainAuthEnabled` is `false`. +The value is optional. +If not configured, it uses the value of `plainAuthDisallowed` (which defaults to `true`) as fallback. -| highWriteBufferWaterMark -| Netty's write buffer high watermark configuration. Unit supported: none, K, M. Netty defaults applied. +| `auth.adminUsers` +| Configures admin users that are authorized to impersonate any IMAP user. +It is an optional element containing `adminUser` elements. +**Do not configure this for publicly exposed IMAP servers!** -| lowWriteBufferWaterMark -| Netty's write buffer low watermark configuration. Unit supported: none, K, M. Netty defaults applied. +| `auth.oidc` +| Configures authentication via OIDC. +The configuration is described in more detail xref:{pages-path}/configure/oidc.adoc[here]. -| idCommandResponse.field -| Store the fields response for ID Command, with each tag containing a name-value pair corresponding to the attribute name. Ref: rfc2971 |=== -== OIDC setup -James IMAP support XOAUTH2 authentication mechanism which allow authenticating against a OIDC providers. -Please configure `auth.oidc` part to use this. - -We do supply an link:https://github.com/apache/james-project/tree/master/examples/oidc[example] of such a setup. -It uses the Keycloak OIDC provider, but usage of similar technologies is definitely doable. - == Traffic Shaping -James ships an optional link:https://netty.io/4.0/api/io/netty/handler/traffic/ChannelTrafficShapingHandler.html[Netty built in Traffic Shaping] that can be optionally configured. +Including a `trafficShaping` element enables an optional link:https://netty.io/4.0/api/io/netty/handler/traffic/ChannelTrafficShapingHandler.html[Netty traffic shaping handler]. +This adds the following functionality: -This enables both: - - Record per channel bandwidth consumption - - Allows defining per channel bandwidth limit, which helps at fairness and maintaining a good quality of service in terms of incoming/outgoing bandwidth. +- Recording per channel bandwidth consumption. +- Defining per channel bandwidth limit. This helps maintaining fairness and a good quality of service. Example: [source,xml] ---- - <imapserver> - <!-- ... --> - <trafficShaping> - <writeTrafficPerSecond>0</writeTrafficPerSecond> - <readTrafficPerSecond>0</readTrafficPerSecond> - <checkInterval>1000</checkInterval> - <maxDelays>15000</maxDelays> - </trafficShaping> - </imapserver> +<imapserver> + <!-- ... --> + <trafficShaping> + <writeTrafficPerSecond>0</writeTrafficPerSecond> + <readTrafficPerSecond>0</readTrafficPerSecond> + <checkInterval>1000</checkInterval> + <maxDelays>15000</maxDelays> + </trafficShaping> +</imapserver> ---- -Those tags maps to the corresponding Netty argument. - -If omitted no traffic handle is added to the channel pipeline. +All inner elements are optional. +The example above shows the default values. +The values are directly used for the instantiation of `io.netty.handler.traffic.ChannelTrafficShapingHandler`. -== IMAP command throttler +== Command Throttler -James ships an optional IMAP command throttler aimed at slowing down lower-quality clients that generate a high -volume of requests. It allows per command granularity and is applied at the scope of an IMAP session. +James ships an optional IMAP command throttler aimed at slowing down lower-quality clients that generate a high volume of requests. +It allows a different configuration for every command and is applied at the scope of an IMAP session. +The throttler is enabled by including a `perSessionCommandThrottling` element in the configuration. -The user can declare the list of commands on which throttling needs to be tracked and for each: +For every command, the following configurations are available. - - `thresholdCount`: below this number of occurrence, no throttling is applied. Integer. - - `additionalDelayPerOperation`: delay to be applied when exceeding the threshold. The delay is cumulative and thus - would always increase. Duration. - - `observationPeriod`: the count of observed commands is reset after this period thus stopping delays. Duration. - - `maxDelay`: maximum value the client will be delayed for. -- `resetOn`: String. Optional default to none. Needs to be a command name. If specified, this command name will reset -throttling on this specific entry. +- `thresholdCount`: Throttling is enabled after the client issued the command `thresholdCount` number of times. It is a mandatory integer. +- `additionalDelayPerOperation`: After the threshold above has been reached, a delay is introduced. It is calculated as the number of previous occurrences of the command times `additionalDelayPerOperation`. This means that with a threshold of 25 and a delay of 2ms, the 26th occurrence of the command has a delay of 50ms. It is a mandatory duration with unit. The unit should be `ms` (millisecond) or `s` (second) in most cases. +- `observationPeriod`: After this time, the counter for the command is reset. This removes the delay. It is a mandatory duration with unit. The unit should be `s` (second) or `m` (minute) in most cases. +- `maxDelay`: The maximum delay for the command. It is a mandatory duration with unit. The unit should be `ms` (millisecond) or `s` (second) in most cases. +- `resetOn`: An different IMAP command that resets counter and delay for the command. It is an optional string. By default, no IMAP command triggers a reset. Sample configuration: @@ -232,7 +185,7 @@ Sample configuration: <additionalDelayPerOperation>2ms</additionalDelayPerOperation> <observationPeriod>10m</observationPeriod> <maxDelay>1s</maxDelay> - <resetOn>APPEND</resetOn> <!-- Helps mitigate delays in Outlook upon sending email: a full refresh is needed for the operation to complete --> + <resetOn>APPEND</resetOn> <!-- Allows a full refresh after sending an email. --> </select> <append> <thresholdCount>5</thresholdCount> @@ -244,50 +197,64 @@ Sample configuration: </imapserver> ---- -Note that commands are delayed prior the execution and thus are not subject to the IMAP upper concurrency limit until -they are executed. +Note that commands are delayed prior to their execution and thus are not subject to the setting `concurrentRequests` until they are executed. == Extending IMAP -IMAP decoders, processors and encoder can be customized. xref:{pages-path}/customization/imap.adoc[Read more]. - -Check this link:https://github.com/apache/james-project/tree/master/examples/custom-imap[example]. +IMAP decoders, processors and encoders can be customized. +You can xref:{pages-path}/customization/imap.adoc[read more here]. The following configuration properties are available for extensions: -.imapserver.xml content +.`imapserver` element |=== -| Property name | explanation +| Property Name | Explanation + +| `imapPackages` +| Configures which packages to load for IMAP. +IMAP packages bundle decoders (IMAP command parsing), command processors, and encoders. +The setting is optional and defaults to `org.apache.James.modules.protocols.DefaultImapPackage`. +The element must contain a Java classpath and can appear multiple times. +If configured, the union of all packages is used. +Remember to include `DefaultImapPackage` if you want to use its functionality. + +| `additionalConnectionChecks` +| Configures an additional connection check. +A connection check decides whether the client IP of a connection is secure. +It must contain a Java classpath. +This element can be used multiple times. + +| `customProperties` +| This element can be used to set an arbitrary property. +The value must have the form `key=value`. +This element can be used multiple times. +Using this enables configuring custom IMAP extensions without touching the code responsible for loading the configuration. -| imapPackages -| Configure (union) of IMAP packages. IMAP packages bundles decoders (parsing IMAP commands) processors and encoders, -thus enable implementing new IMAP commands or replace existing IMAP processors. List of FQDNs, which can be located in -James extensions. - -| additionalConnectionChecks -| Configure (union) of additional connection checks. ConnectionCheck will check if the connection IP is secure or not. -| customProperties -| Properties for custom extension. Each tag is a property entry, and holds a string under the form key=value. |=== -== Mail user agents auto-configuration +== Auto-Configuration for Mail User Agents -Check this example on link:https://github.com/apache/james-project/tree/master/examples/imap-autoconf[Mail user agents auto-configuration]. +Check link:https://github.com/apache/james-project/tree/master/examples/imap-autoconf[this example] for the auto-configuration of mail user agents. -== Local cache for partial Fetch +== Local Cache for Partial Fetch -Because some clients uses partial fetch in order to emulate retriable download of individual body parts -we offer a way for James to cache in the IMAP session the latest partially fetched message. This is done using -a weak reference, a total size dedicated to the cache as well as a time to leave cache cleanup, all of this -being configurable. +Some clients use partial fetch in order to emulate retriable downloads of individual body parts. +Therefore, we offer a way for James to cache the latest partially fetched message in the IMAP session. +This is done using a weak reference. -Example: +The following configuration options are available. + +- `partialBodyFetchCacheEnabled`: Enables the cache. It is an optional boolean that defaults to `false`. +- `partialBodyFetchCacheDuration`: Configures how long partial bodies are cached. It is an optional integer with an optional unit. The default value is 2 minutes and the default unit is minute. The unit should be `s` (second) or `m` (minute) in most cases. +- `partialBodyFetchCacheSize`: Sets the size of the cache. It is an optional integer with an optional unit. The default value is 500 mebibyte and the default unit is byte. The unit should be `MiB` (mebibyte) or `GiB` (gibibyte) in most cases. + +Example with the default values: [source,xml] ---- <imapserver> - <partialBodyFetchCacheEnabled>true</partialBodyFetchCacheEnabled> - <partialBodyFetchCacheDuration>2min</partialBodyFetchCacheDuration> - <partialBodyFetchCacheSize>500 MiB</partialBodyFetchCacheSize> + <partialBodyFetchCacheEnabled>false</partialBodyFetchCacheEnabled> + <partialBodyFetchCacheDuration>2m</partialBodyFetchCacheDuration> + <partialBodyFetchCacheSize>500MiB</partialBodyFetchCacheSize> </imapserver> ----- \ No newline at end of file +---- diff --git a/docs/modules/servers/partials/configure/pop3.adoc b/docs/modules/servers/partials/configure/pop3.adoc index dc01589791..9987551795 100644 --- a/docs/modules/servers/partials/configure/pop3.adoc +++ b/docs/modules/servers/partials/configure/pop3.adoc @@ -1,74 +1,18 @@ -Consult this link:{sample-configuration-prefix-url}/pop3server.xml[example] -to get some examples and hints. +Consult this link:{sample-configuration-prefix-url}/pop3server.xml[example] for guidance on how to configure POP3. -The POP3 service is controlled by a configuration block in the pop3server.xml. -The pop3server tag defines the boundaries of the configuration block. It encloses -all the relevant configuration for the POP3 server. The behavior of the POP service is -controlled by the attributes and children of this tag. +The POP3 service is configured in the file `pop3server.xml`. +It contains one `pop3servers` element that can contain multiple `pop3server` elements. -This tag has an optional boolean attribute - *enabled* - that defines whether the service is active or not. -The value defaults to "true" if not present. +The `pop3server` element can be configured using the common options described xref:{pages-path}/configure/server.adoc[here]. -The standard children of the pop3server tag are: +Additionally, it contains a mandatory `handlerchain` element that configures the behavior of the server using handlers. +The `handlerchain` element has the following optional attributes: -.jmx.properties content -|=== -| Property name | explanation +- `coreHandlersPackage` is a string specifying a handler loader. All handlers of this loader are added to the end of the handlerchain. The default is `org.apache.james.pop3server.core.CoreCmdHandlerLoader`. +- `enableJmx` enables the JMX for this server. It is a boolean which is `true` by default. +- `jmxHandlersPackage` is a string specifying a handler loader for JMX. All handlers of this loader are added to the handlerchain after the core handlers. The default is `org.apache.james.pop3server.jmx.JMXHandlersLoader`. It only has an effect if `enableJmx` is `true`. -| bind -| Configure this to bind to a specific inetaddress. This is an optional integer value. -This value is the port on which this POP3 server is configured -to listen. If the tag or value is absent then the service -will bind to all network interfaces for the machine If the tag or value is omitted, -the value will default to the standard POP3 port, 11 -port 995 is the well-known/IANA registered port for POP3S ie over SSL/TLS -port 110 is the well-known/IANA registered port for Standard POP3 - -| connectionBacklog -| - -| tls -| Set to true to support STARTTLS or SSL for the Socket. -To create a new keystore execute: -`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore /path/to/james/conf/keystore` -Please note that each POP3 server exposed on different port can specify its own keystore, independently from any other -TLS based protocols. Read xref:{pages-path}/configure/ssl.adoc[SSL configuration page] for more information. - -| handler.helloName -| This is the name used by the server to identify itself in the POP3 -protocol. If autodetect is TRUE, the server will discover its -own host name and use that in the protocol. If discovery fails, -the value of 'localhost' is used. If autodetect is FALSE, James -will use the specified value. - -| handler.connectiontimeout -| Connection timeout in seconds - -| handler.connectionLimit -| Set the maximum simultaneous incoming connections for this service - -| handler.connectionLimitPerIP -| Set the maximum simultaneous incoming connections per IP for this service - -| handler.handlerchain -| This loads the core CommandHandlers. Only remove this if you really know what you are doing. - -| bossWorkerCount -| Set the maximum count of boss threads. Boss threads are responsible for accepting incoming POP3 connections -and initializing associated resources. Optional integer, by default, boss threads are not used and this responsibility is being dealt with -by IO threads. - -| ioWorkerCount -| Set the maximum count of IO threads. IO threads are responsible for receiving incoming POP3 messages and framing them -(split line by line). IO threads also take care of compression and SSL encryption. Their tasks are short-lived and non-blocking. -Optional integer, defaults to 2 times the count of CPUs. - -| maxExecutorCount -| Set the maximum count of worker threads. Worker threads takes care of potentially blocking tasks like executing POP3 requests. Optional integer, defaults to 16. - -| useEpoll -| true or false - If true uses native EPOLL implementation for Netty otherwise uses NIO. Defaults to false. - -| gracefulShutdown -| true or false - If true attempts a graceful shutdown, which is safer but can take time. Defaults to true. -|=== \ No newline at end of file +The `handlerchain` element may contain an arbitrary number of `handler` elements. +Every `handler` element must have the string attribute `class`. +They are inserted in order at the beginning of the handlerchain. +The handlers of the `coreHandlersPackage` or `jmxHandlersPackage` do not need their own `handler` elements. diff --git a/docs/modules/servers/partials/configure/sieve.adoc b/docs/modules/servers/partials/configure/sieve.adoc index 25f2219aff..47e62761b5 100644 --- a/docs/modules/servers/partials/configure/sieve.adoc +++ b/docs/modules/servers/partials/configure/sieve.adoc @@ -19,7 +19,7 @@ The following Sieve capabilities are supported by Apache James: To be correctly executed, please note that the *Sieve* mailet is required to be positioned prior the *LocalDelivery* mailet. -== Managing Sieve scripts +== Managing Sieve Scripts A user willing to manage his Sieve scripts on the server can do so via several means: @@ -28,86 +28,16 @@ He can ask an admin to upload his script via the xref:{pages-path}/operate/cli.a As James supports ManageSieve (link:https://datatracker.ietf.org/doc/html/rfc5804[RFC-5804]) a user can thus use compatible software to manage his Sieve scripts.</p> -== ManageSieve protocol +== ManageSieve Protocol -*WARNING*: ManageSieve protocol should be considered experimental. +*WARNING*: Support for the ManageSieve protocol should be considered experimental. -Consult link:{sample-configuration-prefix-url}/managesieveserver.xml[managesieveserver.xml] -in GIT to get some examples and hints. +Consult this link:{sample-configuration-prefix-url}/managesieveserver.xml[example] for guidance on how to configure ManageSieve. -The service is controlled by a configuration block in the managesieveserver.xml. -The managesieveserver tag defines the boundaries of the configuration block. It encloses -all the relevant configuration for the ManageSieve server. The behavior of the ManageSieve service is -controlled by the attributes and children of this tag. +The ManageSieve service is configured in the file `managesieveserver.xml`. +It contains one `managesieveservers` element that can contain multiple `managesieveserver` elements. -This tag has an optional boolean attribute - *enabled* - that defines whether the service is active or not. -The value defaults to "false" if -not present. +The `managesieveserver` element can be configured using the common options described xref:{pages-path}/configure/server.adoc[here]. -The standard children of the managesieveserver tag are: - -.managesieveserver.xml content -|=== -| Property name | explanation - -| bind -| Configure this to bind to a specific inetaddress. This is an optional integer value. This value is the port on which this ManageSieve server is configured to listen. If the tag or value is absent then the service -will bind to all network interfaces for the machine If the tag or value is omitted, the value will default to the standard ManageSieve port (port 4190 is the well-known/IANA registered port for ManageSieve.) - -| tls -| Set to true to support STARTTLS or SSL for the Socket. -To use this you need to copy sunjce_provider.jar to /path/james/lib directory. To create a new keystore execute: -`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore /path/to/james/conf/keystore`. -Please note that each ManageSieve server exposed on different port can specify its own keystore, independently from any other -TLS based protocols. - -| connectionBacklog -| Number of connection backlog of the server (maximum number of queued connection requests) - -| connectiontimeout -| Connection timeout in seconds - -| connectionLimit -| Set the maximum simultaneous incoming connections for this service - -| connectionLimitPerIP -| Set the maximum simultaneous incoming connections per IP for this service - -| bossWorkerCount -| Set the maximum count of boss threads. Boss threads are responsible for accepting incoming ManageSieve connections -and initializing associated resources. Optional integer, by default, boss threads are not used and this responsibility is being dealt with -by IO threads. - -| ioWorkerCount -| Set the maximum count of IO threads. IO threads are responsible for receiving incoming ManageSieve messages and framing them -(split line by line). IO threads also take care of compression and SSL encryption. Their tasks are short-lived and non-blocking. -Optional integer, defaults to 2 times the count of CPUs. - -| maxExecutorCount -| Set the maximum count of worker threads. Worker threads takes care of potentially blocking tasks like executing ManageSieve commands. -Optional integer, defaults to 16. - -| oidc -| If this property is present, OIDC will be configured and the following properties are mandatory (unless otherwise specified). - -| oidc.oidcConfigurationURL -| Your identity provider's OIDC discovery URL. This is currently not used for managesieve but is still required when OIDC is configured. - -| oidc.jwksURL -| URL to the endpoint for the JSON Web Key Set of your provider. This is used to locally validate tokens. - -| oidc.claim -| Name of the claim in the token you want to use as the identifier for the user (e.g. "email_address"). - -| oidc.scope -| OIDC scope. This is currently not used for managesieve but is still required when OIDC is configured. - -| oidc.introspection.url -| URL to your identity provider's introspection endpoint. It is optional and if specified James will use the endpoint to validate the token in addition to local validation. - -| oidc.introspection.auth -| Provide Authorization header for introspection requests (optional, e.g. `Basic xyz`). - -| oidc.userinfo.url -| URL to your identity provider's userinfo endpoint. It is optional and if specified James will use the endpoint to validate the token in addition to local validation. James will ignore this option if `oidc.introspection.url` is already configured. -|=== +Additionally, it can contain an optional `oidc` element. +The OIDC configuration is described xref:{pages-path}/configure/oidc.adoc[here]. diff --git a/docs/modules/servers/partials/configure/smtp.adoc b/docs/modules/servers/partials/configure/smtp.adoc index 5c794bacdf..c5da1dffa9 100644 --- a/docs/modules/servers/partials/configure/smtp.adoc +++ b/docs/modules/servers/partials/configure/smtp.adoc @@ -1,333 +1,290 @@ -== Incoming SMTP +Consult this link:{sample-configuration-prefix-url}/smtpserver.xml[example] for guidance on how to configure SMTP. -Consult this link:{sample-configuration-prefix-url}/smtpserver.xml[example] -to get some examples and hints. +The SMTP service is configured in the file `smtpserver.xml`. +It contains one `smtpservers` element that can contain multiple `smtpserver` elements. -The SMTP service is controlled by a configuration block in the smptserver.xml. -The smtpserver tag defines the boundaries of the configuration block. It encloses -all the relevant configuration for the SMTP server. The behavior of the SMTP service is -controlled by the attributes and children of this tag. +The `smtpserver` element can be configured using the common options described xref:{pages-path}/configure/server.adoc[here]. +Additional settings are described below. -This tag has an optional boolean attribute - *enabled* - that defines whether the service is active or not. The value defaults to "true" if -not present. - -The standard children of the smtpserver tag are: - -.smtpserver.xml content +.`smtpserver` element |=== -| Property name | explanation - -| bind -| A list of address:port separed by comma - This is an optional value. If present, this value is a string describing -the IP address to which this service should be bound. If the tag or value is absent then the service -will bind to all network interfaces for the machine on port 25. Port 25 is the well-known/IANA registered port for SMTP. -Port 465 is the well-known/IANA registered port for SMTP over TLS. - -| connectBacklog -|The IP address (host name) the MBean Server will bind/listen to. +| Property Name | Explanation -| tls -| Set to true to support STARTTLS or SSL for the Socket. -To use this you need to copy sunjce_provider.jar to /path/james/lib directory. To create a new keystore execute: -`keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore /path/to/james/conf/keystore`. -The algorithm is optional and only needs to be specified when using something other -than the Sun JCE provider - You could use IbmX509 with IBM Java runtime. -Please note that each SMTP/LMTP server exposed on different port can specify its own keystore, independently from any other -TLS based protocols. +| `auth` +| Configures user authentication. +More details of this element are given below. -| helloName -| This is a required tag with an optional body that defines the server name -used in the initial service greeting. The tag may have an optional attribute - *autodetect*. If -the autodetect attribute is present and true, the service will use the local hostname -returned by the Java libraries. If autodetect is absent or false, the body of the tag will be used. In -this case, if nobody is present, the value "localhost" will be used. +| `authRequired` +a| Deprecated. If `auth.announce` is not present, this is used as fallback. +It is an optional string that defaults to `false`. -| connectionTimeout -| This is an optional tag with a non-negative integer body. Connection timeout in seconds. +Its value is mapped to the allowed values for `auth.announce` (`always`, `never`, and `forUnauthorizedAddresses`) as described below. -| connectionLimit -| Set the maximum simultaneous incoming connections for this service. +- `true` maps to `forUnauthorizedAddresses`. +- `announce` maps to `always`. +- All other values (including the default `false`) map to `never`. -| connectionLimitPerIP -| Set the maximum simultaneous incoming connections per IP for this service. +| `authorizedAddresses` +| Configures IP networks that are considered trustworthy. +Normally, clients are only authorized to relay emails after a successful SMTP AUTH command. +If the remote IP of a connection is included in one of these networks, the client is authorized to relay without authentication. +It is an optional list separated by ``, `` (note the space). -| proxyRequired -| Enables proxy support for this service for incoming connections. HAProxy's protocol -(https://www.haproxy.org/download/2.7/doc/proxy-protocol.txt) is used and might be compatible -with other proxies (e.g. traefik). If enabled, it is *required* to initiate the connection -using HAProxy's proxy protocol. +**We strongly recommend to omit this element!** +Caution is especially required if James is behind a reverse proxy. +In that case, it is essential that PROXY protocol is used so that James sees the real client IP and not some internal IP that might be included in the `authorizedAddresses`. -| proxyFirst -| Whether proxy frames should be handled before SSL handshakes. This allows setting either the loadbalancer in TCP mode -(so transparent for SSL then Proxy frames needs to be handled first) or set up SSL termination between proxy and server -(more suited for some cloud vendors). Defaults to true (TCP transparent). +Networks may be specified as IP address or domain name, with an optional netmask. +`127.*`, `127.0.0.0/8`, `127.0.0.0/255.0.0.0`, and `localhost/8` are equivalent values that can all be parsed. +See `org.apache.james.dnsservice.library.inetnetwork` for more details. -| authRequired -| (deprecated) use auth.announce instead. +Also see the `RemoteAddrNotInNetwork` matcher in the transport processor. +You would generally use one **or** the other approach. -This is an optional tag with a boolean body. If true, then the server will -announce authentication after HELO command. If this tag is absent, or the value -is false then the client will not be prompted for authentication. Only simple user/password authentication is -supported at this time. Supported values: +| `maxmessagesize` +| Configures the maximum size of SMTP messages the server will accept. +If it is set to 0, no limit will be imposed. +Any value larger than 0 will enable the SMTP SIZE extension (RFC 1870) and enforce the limit. - * true: announced only to not authorizedAddresses +It is an optional integer which defaults to 0. +The last character of the value may be a unit. +Supported units are `B` for bytes, `K` for kibibyte (1,024 bytes), `M` for mebibyte (1,024 kibibytes), and `G` for gibibyte (1,024 mebibytes). +If no unit is given, the value is interpreted as kibibytes. - * false: don't announce AUTH. If absent, *authorizedAddresses* are set to a wildcard to accept all remote hosts. +| `heloEhloEnforcement` +| Configures whether to enforce the use of the HELO / EHLO salutation before a MAIL command is accepted. +It is an optional boolean that defaults to `true`. - * announce: like true, but always announce AUTH capability to clients +| `smtpGreeting` +| Sets the greeting which the server sends when a client connects. +It is an optional string. +If not configured, a greeting is constructed from the server `helloName`. -Please note that emails are only relayed if, and only if, the user did authenticate, or is in an authorized network, -regardless of this option. +| `addressBracketsEnforcement` +| Enforces that addresses in the MAIL and RCPT commands are enclosed in `<` and `>` as required by RFC 5321. +It is an optional boolean which defaults to `true`. -| auth.announce -| This is an optional tag. Possible values are: +| `verifyIdentity` +a| Configures how the identity in the MAIL command is verified for local users. -* never: Don't announce auth. +This is an optional string with the following possible values. -* always: always announce AUTH capability to clients. +- `strict`: If the email used in the MAIL command has a local domain, authentication is required. Verification succeeds if the authenticated user's email address or one of its aliases matches the sender address in the MAIL command. It prevents spoofing local email addresses on this server. Spoofing of external email addresses when sending to local users can not be prevented. For backward compatibility, `true` has the same effect as `strict`. +- `disabled`: The sender address is not verified. However, authentication is still required for relaying. This allows spoofing local email addresses on this server. External users can send emails to local users as any local user. Authenticated local users can send emails to local and external users as any local user. For backward compatibility, `false` has the same effect as `disabled`. +- `relaxed`: If the user is authenticated, this acts like `strict`. If the sender is local and not authenticated, a simple heuristic decides whether the sender is accepted. The heuristic categorizes a client that uses a valid domain in its EHLO command as a MX and as a MUA otherwise. Authentication is only required for MUAs, not for MXs. Note that this heuristic **can easily be circumvented**. See link:https://issues.apache.org/jira/browse/JAMES-4032[JAMES-4032] for the reasoning behind [...] -* forUnauthorizedAddresses: announced only to not authorizedAddresses +The default value is `strict`. +**Changing it always decreases the security** and should only be done if absolutely necessary. -Please note that emails are only relayed if, and only if, the user did authenticate, or is in an authorized network, -regardless of this option. +| `handlerchain` +a| Configures the behavior of the server using handlers. +The `handlerchain` element has the following optional attributes: -| auth.requireSSL -| This is an optional tag, defaults to true. If true, authentication is not advertised via capabilities on unencrypted -channels. +- `coreHandlersPackage` is a string specifying a handler loader. All handlers of this loader are added to the end of the handlerchain. The default is `org.apache.james.smtpserver.CoreCmdHandlerLoader`. +- `enableJmx` enables the JMX for this server. It is a boolean which is `true` by default. +- `jmxHandlersPackage` is a string specifying a handler loader for JMX. All handlers of this loader are added to the handlerchain after the core handlers. The default is `org.apache.james.smtpserver.jmx.JMXHandlersLoader`. It only has an effect if `enableJmx` is `true`. -| auth.plainAuthEnabled -| This is an optional tag, defaults to true. If false, AUTH PLAIN and AUTH LOGIN will not be exposed. This setting -can be used to enforce strong authentication mechanisms. +The `handlerchain` element may contain an arbitrary number of `handler` elements. +Every `handler` element must have the string attribute `class`. +They are inserted in order at the beginning of the handlerchain. +The handlers of the `coreHandlersPackage` or `jmxHandlersPackage` do not need their own `handler` elements. -| auth.required -| Authentication is required to send emails. Adapted for submission ports. +See xref:{pages-path}/configure/smtp-hooks.adoc[this page] for a list of handlers that are included in James. -Note that if false (legacy value and default for backward compatibility) then unauthenticated senders are allowed but -limited by sender verification (prevent spoofing) and relaying limits (must be authenticated to relay). +| `disabledFeatures` +| Removes features from the feature announcement sent to clients after their EHLO. +The element may be omitted or appear multiple times. +Every occurrence must contain exactly one feature. +By default, no features are omitted. -We encourage setting this value to true on submission ports (465 + 587). MUST be set to false on port 25 or for any port with MX external mail receival role. +Note that this only removes the features from the announcement, it does not disable the features! +It prevents standard-conformant clients from using commands that only work with the disabled features but **it is not a security feature**. -Please note that `authorizedAddresses` are considered authenticated. - -| auth.oidc.oidcConfigurationURL -| Provide OIDC url address for information to user. Only configure this when you want to authenticate SMTP server using a OIDC provider. - -| auth.oidc.jwksURL -| Provide url to get OIDC's JSON Web Key Set to validate user token. Only configure this when you want to authenticate SMTP server using a OIDC provider. +|=== -| auth.oidc.claim -| Claim string uses to identify user. E.g: "email_address". Only configure this when you want to authenticate SMTP server using a OIDC provider. +== Authentication -| auth.oidc.scope -| An OAuth scope that is valid to access the service (RF: RFC7628). Only configure this when you want to authenticate SMTP server using a OIDC provider. +The `auth` element mentioned above has the following options. -| auth.oidc.aud -| An OAuth audience to access the service (RF: RFC7628). Only configure this when you want to authenticate IMAP server using a OIDC provider. -Compulsory but can be relaxed with `-Djames.sasl.oidc.validate.aud=false` +.`auth` element +|=== +| Property Name | Explanation -| auth.oidc.introspection.url -| Optional. An OAuth introspection token URL will be called to validate the token (RF: RFC7662). -Note that James always verifies the signature of the token even whether this configuration is provided or not. +| `auth.announce` +a| Configures when to announce authentication to the client. +This is an optional string with the following possible values: -| auth.oidc.introspection.auth -| Optional. Provide Authorization in header request when introspecting token. -Eg: `Basic xyz` +- `never`: Do not announce authentication capabilities. +- `always`: Always announce authentication capabilities. +- `forUnauthorizedAddresses`: Announce authentication capabilities only to clients which are not in `authorizedAddresses`. -| auth.oidc.userinfo.url -| Optional. An Userinfo URL will be called to retrieve additional user information -(RF: OpenId.Core https://openid.net/specs/openid-connect-core-1_0.html). +If not configured, it uses the value of `authRequired` (of which the default maps to `never`) as fallback. -| authorizedAddresses -| Authorize specific addresses/networks. +Note that this configures only the **announcement** of authentication capabilities. +`auth.requireSSL` also has an influence on whether authentication capabilities are announced. -If you use SMTP AUTH, addresses that match those specified here will -be permitted to relay without SMTP AUTH. If you do not use SMTP -AUTH, and you specify addresses here, then only addresses that match -those specified will be permitted to relay. +Even if authentication capabilities are not announced, clients can still use the SMTP AUTH command. +However, if authentication capabilities are not announced, only the mechanisms `PLAIN` and `LOGIN` are available. +`XOAUTH2` and `OAUTHBEARER` are disabled if authentication capabilities are not announced. -Addresses may be specified as a IP address or domain name, with an -optional netmask, e.g., +| `auth.requireSSL` +| Configures whether announcing authentication capabilities requires a secure connection (TLS or STARTTLS). +If this value is `true` and the connection is not secure, authentication capabilities are not announced. +This always holds, even if `auth.announce` is set to `always`. -127.*, 127.0.0.0/8, 127.0.0.0/255.0.0.0, and localhost/8 are all the same +It is an optional boolean that defaults to `true`. -See also the RemoteAddrNotInNetwork matcher in the transport processor. -You would generally use one OR the other approach. +Note that this configures only the **announcement** of authentication capabilities. +Even if authentication capabilities are not announced, clients can still use the SMTP AUTH command with the mechanisms `PLAIN` and `LOGIN`. +However, as the mechanisms `XOAUTH2` and `OAUTHBEARER` are only available if authentication mechanisms are announced, those mechanisms can only be used in secure connections if `auth.requireSSL` is set to `true`. -| verifyIdentity -| This is an optional tag. This options governs MAIL FROM verifications, and prevents spoofing of the MAIL FROM -envelop field. +| `auth.plainAuthEnabled` +| Enables the authentication mechanisms `PLAIN` and `LOGIN`. +It is an optional boolean that defaults to `true`. -The following values are supported: +| `auth.oidc` +| Configures authentication via OIDC. +The configuration is described in more detail xref:{pages-path}/configure/oidc.adoc[here]. - - `strict`: use of a local domain in MAIL FROM requires the SMTP client to be authenticated with a matching user or one - of its aliases. It will verify that the sender address matches the address of the user or one of its alias (from user or domain aliases). - This prevents a user of your mail server from acting as someone else - - `disabled`: no check is performed and third party are free to send emails as local users. Note that relaying emails will - need third party to be authenticated thus preventing open relays. - - `relaxed`: Based on a simple heuristic to determine if the SMTP client is a MUA or a MX (use of a valid domain in EHLO), - we do act as `strict` for MUAs thus prompting them early for the need of authentication, but accept use of local MAIL FROM for - MX. Authentication can then be delayed to later, eg after DATA transaction with the DKIMHook which might allow email looping through - third party domains via mail redirection, effectively enforcing that the mail originates from our servers. See - link:https://issues.apache.org/jira/browse/JAMES-4032[JAMES-4032] for detailed explanation. +| `auth.required` +| Requires authentication for submitting an email to the SMTP server. +This configuration is intended for submission-only SMTP servers (e.g, port 587). +It should never be set to `true` on SMTP servers that receive emails from external servers as external users have no account and can not authenticate. +Therefore, it must be `false` for SMTP servers on port 25 and 465. -Backward compatibility is provided and thus the following values are supported: +It is an optional boolean that defaults to `false`. - - `true`: act as `strict` - - `false`: act as `disabled` +Note that `authorizedAddresses` are considered authenticated. -Please note that this parameter only intend to prevent spoofing, and still allow unauthenticated remote users (that do not use local identity) to send email to local users. +|=== -| maxmessagesize -| This is an optional tag with a non-negative integer body. It specifies the maximum -size, in kbytes, of any message that will be transmitted by this SMTP server. It is a service-wide, as opposed to -a per user, limit. If the value is zero then there is no limit. If the tag isn't specified, the service will -default to an unlimited message size. Must be a positive integer, optionally with a unit: B, K, M, G. +== Security -| heloEhloEnforcement -| This sets whether to enforce the use of HELO/EHLO salutation before a -MAIL command is accepted. If unspecified, the value defaults to true. +James supports authentication with username / password (`PLAIN` and `LOGIN`) and OIDC (`XOAUTH2` and `OAUTHBEARER`). +SMTP authentication is essential to prevent sender address spoofing and open relays. -| smtpGreeting -| This sets the SMTPGreeting which will be used when connect to the smtpserver -If none is specified a default is generated +For the concepts explained below, the distinction between local and external users is important. +James makes this distinction by matching the domain of an email address against the list of domains handled by it. +This list can be configured in xref:{pages-path}/configure/domainlist.adoc[*domainlist.xml*]. -| handlerchain -| The configuration handler chain. See xref:{pages-path}/configure/smtp-hooks.adoc[this page] for configuring out-of the -box extra SMTP handlers and hooks. +=== Open Relays -| bossWorkerCount -| Set the maximum count of boss threads. Boss threads are responsible for accepting incoming SMTP connections -and initializing associated resources. Optional integer, by default, boss threads are not used and this responsibility is being dealt with -by IO threads. +The process of sending an email from one email server to another is called relaying. +An open relay is an email server that allows any user to send emails to other email servers. +Open relays are used by spammers to send spam emails with spoofed sender addresses. +Open relays can be prevented using the SMTP AUTH extension. -| ioWorkerCount -| Set the maximum count of IO threads. IO threads are responsible for receiving incoming SMTP messages and framing them -(split line by line). IO threads also take care of compression and SSL encryption. Their tasks are short-lived and non-blocking. -Optional integer, defaults to 2 times the count of CPUs. +By default, James is not an open relay. +James relays emails if, and only if, they originate from one of the trusted sources below. -| maxExecutorCount -| Set the maximum count of worker threads. Worker threads takes care of potentially blocking tasks like executing SMTP commands. -Optional integer, defaults to 16. +- Authenticated SMTP/JMAP users +- Emails generated by the server (e.g., bounces) +- Emails originating from a trusted network (see `authorizedAddresses`) -| useEpoll -| true or false - If true uses native EPOLL implementation for Netty otherwise uses NIO. Defaults to false. +This means that emails are only relayed for local users as external users have no way of authenticating. +External users can still send emails to local users because those emails do not need to be relayed and therefore do not require authentication. -| gracefulShutdown -| true or false - If true attempts a graceful shutdown, which is safer but can take time. Defaults to true. +It is extremely important to prevent your server from being an open relay. +Aside from potential costs associated with usage by spammers, +open relays are identified as such relatively quickly because of the spam originating from them. +Hence, other SMTP servers routinely reject emails coming from open relays which severely impedes the ability of them to send emails to external users. -| disabledFeatures -| Extended SMTP features to hide in EHLO responses. -|=== +==== Verification -=== OIDC setup -James SMTP support XOAUTH2 authentication mechanism which allow authenticating against a OIDC providers. -Please configure `auth.oidc` part to use this. +To verify that you have not inadvertently configured your server as an open relay, you can use a service such as https://mxtoolbox.com/diagnostic.aspx[mxtoolbox.com]. +This checks among other things: -We do supply an link:https://github.com/apache/james-project/tree/master/examples/oidc[example] of such a setup. -It uses the Keycloak OIDC provider, but usage of similar technologies is definitely doable. +- Whether your email server is an open relay. +- Your DNS configuration, especially whether your email server has a valid record for reverse DNS. +- Support for secure connections with STARTTLS. -== About open relays +=== Spoofing -Authenticated SMTP is a method of securing your SMTP server. With SMTP AUTH enabled senders who wish to -relay mail through the SMTP server (that is, send mail that is eventually to be delivered to another SMTP -server) must authenticate themselves to Apache James Server before sending their message. Mail that is to be delivered -locally does not require authentication. This method ensures that spammers cannot use your SMTP server -to send unauthorized mail, while still enabling users who may not have fixed IP addresses to send their -messages. +In addition to preventing open relays, SMTP authentication can also be used to prevent spoofing. +Spoofing is the assumption of the identity of another person without authorization to do so. -Mail servers that allow spammers to send unauthorized email are known as open relays. So SMTP AUTH -is a mechanism for ensuring that your server is not an open relay. +For emails from local addresses, spoofing can be prevented by requiring authentication for a user with authorization for the sender address. +This can be configured with `verifyIdentity` as described above. -It is extremely important that your server not be configured as an open relay. Aside from potential -costs associated with usage by spammers, connections from servers that are determined to be open relays -are routinely rejected by SMTP servers. This can severely impede the ability of your mail server to -send mail. +Sender verification does not work for emails sent by an external address. +As external users can not authenticate, James has to trust the sender address. -At this time Apache James Server only supports simple user name / password authentication. +== LMTP Configuration -As mentioned above, SMTP AUTH requires that Apache James Server be able to distinguish between mail intended -for local delivery and mail intended for remote delivery. Apache James Server makes this determination by matching the -domain to which the mail was sent against the *DomainList* component, configured by -xref:{pages-path}/configure/domainlist.adoc[*domainlist.xml*]. +Consult this link:{sample-configuration-prefix-url}/lmtpserver.xml[example] for guidance on how to configure LMTP. -The {server-name} is configured out of the box so as to not serve as an open relay for spammers. This is done -by relayed emails originate from a trusted source. This includes: +The LMTP service is configured in the file `lmtpserver.xml`. +It contains one `lmtpservers` element that can contain multiple `lmtpserver` elements. -* Authenticated SMTP/JMAP users -* Mails generated by the server (eg: bounces) -* Mails originating from a trusted network as configured in *smtpserver.xml* +The `lmtpserver` element can be configured using most of the common options described xref:{pages-path}/configure/server.adoc[here]. +Additional settings are described below. -If you wish to ensure that authenticated users can only send email from their own account, you may -optionally set the verifyIdentity element of the smtpserver configuration block to "true". +**Note:** Neither any form of TLS nor proxies are supported. -=== Verification +.`lmtpserver` element +|=== +| Property Name | Explanation -Verify that you have not inadvertently configured your server as an open relay. This is most easily -accomplished by using the service provided at https://mxtoolbox.com/diagnostic.aspx[mxtoolbox.com]. mxtoolbox.com will -check your mail server and inform you if it is an open relay. This tool further more verifies additional properties like: +| `maxmessagesize` +| Configures the maximum size of LMTP messages the server will accept. +If it is set to 0, no limit will be imposed. +Any value larger than 0 will enable the SMTP SIZE extension (RFC 1870) and enforce the limit. -* Your DNS configuration, especially that you mail server IP has a valid reverse DNS entry -* That your SMTP connection is secured -* That you are not an OpenRelay -* This website also allow a quick lookup to ensure your mail server is not in public blacklists. +It is an optional integer which defaults to 0. +The last character of the value may be a unit. +Supported units are `B` for bytes, `K` for kibibyte (1,024 bytes), `M` for mebibyte (1,024 kibibytes), and `G` for gibibyte (1,024 mebibytes). +If no unit is given, the value is interpreted as kibibytes. -Of course it is also necessary to confirm that users and log in and send -mail through your server. This can be accomplished using any standard mail client (i.e. Thunderbird, Outlook, -Eudora, Evolution). +| `lmtpGreeting` +| Sets the greeting which the server sends when a client connects. +It is an optional string. +If not configured, a greeting is constructed from the server `helloName`. -== LMTP Configuration +| `handlerchain` +a| Configures the behavior of the server using handlers. +The `handlerchain` element has the following optional attributes: -Consult this link:{sample-configuration-prefix-url}/lmtpserver.xml[example] -to get some examples and hints. +- `coreHandlersPackage` is a string specifying a handler loader. All handlers of this loader are added to the end of the handlerchain. The default is `org.apache.james.lmtpserver.CoreCmdHandlerLoader`. +- `enableJmx` enables the JMX for this server. It is a boolean which is `true` by default. +- `jmxHandlersPackage` is a string specifying a handler loader for JMX. All handlers of this loader are added to the handlerchain after the core handlers. The default is `org.apache.james.lmtpserver.jmx.JMXHandlersLoader`. It only has an effect if `enableJmx` is `true`. -The configuration is the same of for SMTP. +The `handlerchain` element may contain an arbitrary number of `handler` elements. +Every `handler` element must have the string attribute `class`. +They are inserted in order at the beginning of the handlerchain. +The handlers of the `coreHandlersPackage` or `jmxHandlersPackage` do not need their own `handler` elements. -By default, it is deactivated. You can activate it alongside SMTP and bind for example on port 24. +|=== -The default LMTP server stores directly emails in user mailboxes, without further treatment. +=== LMTP Examples -However we do ship an alternative handler chain allowing to execute the mailet container, thus achieving a behaviour similar -to the default SMTP protocol. Here is how to achieve this: +The default LMTP server stores emails without further treatment in user mailboxes. +However, we do ship an alternative handlerchain allowing to execute a mailetcontainer, thus achieving a behavior similar to SMTP. +You can enable the mailetcontainer with the following configuration: [source,xml] .... <lmtpservers> <lmtpserver enabled="true"> - <jmxName>lmtpserver</jmxName> - <bind>0.0.0.0:24</bind> - <connectionBacklog>200</connectionBacklog> - <connectiontimeout>1200</connectiontimeout> - <connectionLimit>0</connectionLimit> - <connectionLimitPerIP>0</connectionLimitPerIP> - <maxmessagesize>0</maxmessagesize> + <!-- ... --> <handlerchain coreHandlersPackage="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader"> - <handler class="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader"/> </handlerchain> </lmtpserver> </lmtpservers> .... -Note that by default the mailet container is executed with all recipients at once and do not allow per recipient -error reporting. An option <code>splitExecution</code> allow to execute the mailet container for each recipient separately and mitigate this -limitation at the cost of performance. +Note that by default the mailetcontainer is executed with all recipients at once and does not allow per recipient error reporting. +The option `splitExecution` allows to execute the mailetcontainer for each recipient separately and mitigate this limitation at the cost of performance. [source,xml] .... <lmtpservers> <lmtpserver enabled="true"> - <jmxName>lmtpserver</jmxName> - <bind>0.0.0.0:24</bind> - <connectionBacklog>200</connectionBacklog> - <connectiontimeout>1200</connectiontimeout> - <connectionLimit>0</connectionLimit> - <connectionLimitPerIP>0</connectionLimitPerIP> - <maxmessagesize>0</maxmessagesize> + <!-- ... --> <handlerchain coreHandlersPackage="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader"> - <handler class="org.apache.james.lmtpserver.MailetContainerCmdHandlerLoader"/> <handler class="org.apache.james.lmtpserver.MailetContainerHandler"> <splitExecution>true</splitExecution> </handler> </handlerchain> </lmtpserver> </lmtpservers> -.... \ No newline at end of file +.... diff --git a/docs/modules/servers/partials/configure/ssl.adoc b/docs/modules/servers/partials/configure/ssl.adoc index 5cb4f9470c..46c4f99da8 100644 --- a/docs/modules/servers/partials/configure/ssl.adoc +++ b/docs/modules/servers/partials/configure/ssl.adoc @@ -1,21 +1,159 @@ -This document explains how to enable James 3.0 servers to use Transport Layer Security (TLS) -for encrypted client-server communication. +The servers +xref:{pages-path}/configure/smtp.adoc[SMTP], +xref:{pages-path}/configure/pop3.adoc[POP3], +xref:{pages-path}/configure/imap.adoc[IMAP], and +xref:{pages-path}/configure/sieve.adoc[Managesieve] +support TLS. +The configuration is the same for all of them and this document explains how to do it. -== Configure a Server to Use SSL/TLS +== Configure a Server to Use TLS -Each of the servers xref:{pages-path}/configure/smtp.adoc[SMTP - LMTP], -xref:{pages-path}/configure/pop3.adoc[POP3] and xref:{pages-path}/configure/imap.adoc[IMAP] -supports use of SSL/TLS. +As described in xref:{pages-path}/configure/server.adoc[SMTP], +there is a `tls` element inside the XML server element. -TLS (Transport Layer Security) and SSL (Secure Sockets Layer) are protocols that provide -data encryption and authentication between applications in scenarios where that data is -being sent across an insecure network, such as checking your email -(How does the Secure Socket Layer work?). The terms SSL and TLS are often used -interchangeably or in conjunction with each other (TLS/SSL), -but one is in fact the predecessor of the other — SSL 3.0 served as the basis -for TLS 1.0 which, as a result, is sometimes referred to as SSL 3.1. +It supports two attributes: -You need to add a block in the corresponding configuration file (smtpserver.xml, pop3server.xml, imapserver.xml,..) +- `socketTLS`: Enables STARTTLS for this server. The client can upgrade the connection using the `STARTTLS` command. +- `startTLS`: Enables implicit TLS on this port. + +By default, both attributes are `false`. +However, it is highly recommended to use TLS and set one of these to `true` for every server. +They can not both be `true` for one server. + +Additionally, the `tls` element can have the following child elements. +There are also examples after the table. + +.`tls` element +|=== +| Property Name | Explanation + +| `supportedCipherSuites` +| Contains the ciphersuites that should be enabled. +Every ciphersuite is in its own `cipherSuite` element. +If not configured, the library's default is used. + +| `supportedProtocols` +| Contains the protocols that should be enabled. +Every protocol is in its own `protocol` element. +If not configured, the library's default is used. + +| `keystore` +| The path to a keystore. +The keystore **must** have only one certificate. +Either the keystore or both private key and certificates must be configured. + +| `keystoreType` +| The type of the keystore. +It is an optinal string with the default value `JKS`. +A common alternative is `PKCS12`. + +| `privateKey` +| The path to a private key. +If configured, `certificates` must also be configured. + +| `certificates` +| A path to a certificate bundle. +The last certificate in the bundle is the one signed by a root CA. +If configured, `privateKey` must also be configured. + +| `secret` +| A secret for the keystore or private key. +It is optional. + +| `clientAuth` +a| Configures TLS client authentication. +If this is present, all clients are required to authenticate on the TLS level. +It has the following child elements: + +- `clientAuth.truststore`: An optional path to the truststore for verifying client certificates. The truststore can contain client certificates directly or CAs that issued client certificates. If not configured, the library's default is used. +- `clientAuth.truststoreType`: The type of the keystore. It is optional and defaults to `JKS`. +- `clientAuth.truststoreSecret`: An optional secret for the truststore. + +| `enableOCSPCRLChecks` +| Enables revocation checks for client authentication. +It is an optional boolean that is `false` by default. + +| `sessionCache.size` +| Sets the maximum number of TLS sessions in the session cache. +If not configured, the library's default is used. + +| `sessionCache.timeout` +| Sets the duration after which TLS sessions in the cache time out. +If not configured, the library's default is used. +It is an integer followed by an optional unit. +The default unit is `ms` (millisecond) and other reasonable values are `s` (second) or `m` (minute). + +|=== + +The paths in the table above are usually file paths and prefixed with `file://`. +They can either be relative (e.g., `file://conf/imap.crt`) or absolute (e.g., `file:///james/conf/imap.crt`). + +== TLS for Email Services + +Email was established before protocols like TLS that can secure TCP connections independent of the application layer. +Therefore, the email services on the initially established ports never had a security layer. +Because of backward compatibility, this will not change. +STARTTLS was introduced to negotiate a security layer over the insecure channel. +For it to work, both the server and the client must abort sessions if STARTTLS is not used. + +Alternatively, other ports that are expected to use implicit TLS have been established by RFC 8314. + +.Ports for email services +|=== +| Service | Client | Ports + +| SMTP +| Remote MX +| insecure: 25, TLS: not defined by RFC + +When trying to deliver emails to another email server using implicit TLS, James attempts to use port 465. + +| SMTP Submission +| MUA +| insecure: 587, TLS: 465 + +| IMAP +| MUA +| insecure: 143, TLS: 993 + +| POP3 +| MUA +| insecure: 110, TLS: 995 + +| LMTP +| Local MX +| insecure: 24, no TLS port defined + +TLS for LMTP is not supported by James. + +|=== + +As all modern email clients support TLS nowadays, there is no need to offer SMTP submission, IMAP, or POP3 without implicit TLS. +In most cases, it should suffice to offer only one version with implicit TLS for each of these services. + +As the MX DNS record only resolves to an IP, other email servers can not know whether the other server offers SMTP with implicit TLS and on which port. +Every email server **must** therefore offer SMTP on port 25. +You may choose to additionally offer SMTP with implicit TLS on port 465 as some email servers (e.g., James) also try that endpoint. +Note that you need to move the SMTP submission service with implicit TLS to another port in that case (this works well as it is only used by MUAs). + +As James does not support TLS or authentication for LMTP, +the port **must only be exposed** to the local SMTP server that uses it. + +**We strongly recommend that you enable STARTTLS for all services that you choose to offer without implicit TLS.** + +== Examples + +=== JKS with Password + +[source,xml] +.... +<tls socketTLS="false" startTLS="true"> + <keystore>file://conf/keystore</keystore> + <secret>yoursecret</secret> +</tls> +.... + +=== PKCS12 Keystore with Password [source,xml] .... @@ -23,33 +161,34 @@ You need to add a block in the corresponding configuration file (smtpserver.xml, <keystore>file://conf/keystore</keystore> <keystoreType>PKCS12</keystoreType> <secret>yoursecret</secret> - <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> </tls> .... -Alternatively TLS keys can be supplied via PEM files: +=== Certificates and Private Key as PEM Files [source,xml] .... <tls socketTLS="true" startTLS="false"> - <privateKey>file://conf/private.key</privateKey> - <certificates>file://conf/certs.self-signed.csr</certificates> + <privateKey>file://conf/imap.key</privateKey> + <certificates>file://conf/imap.crt</certificates> </tls> .... -An optional secret might be specified for the private key: +=== Certificates and Private Key with Password as PEM Files [source,xml] .... <tls socketTLS="true" startTLS="false"> - <privateKey>file://conf/private.key</privateKey> - <certificates>file://conf/certs.self-signed.csr</certificates> + <privateKey>file://conf/imap.key</privateKey> + <certificates>file://conf/imap.crt</certificates> <secret>yoursecret</secret> </tls> .... -Optionally, TLS protocols and/or cipher suites can be specified explicitly (smtpserver.xml, pop3server.xml, imapserver.xml,..). -Otherwise, the default protocols and cipher suites of the used JDK will be used: +=== Explicitly Selected Protocol Versions and Ciphersuites + +**Note:** Only modify the following settings if you know exactly what you are doing. +The configuration below is extremely insecure. [source,xml] .... @@ -64,52 +203,14 @@ Otherwise, the default protocols and cipher suites of the used JDK will be used: <cipherSuite>TLS_AES_256_GCM_SHA384</cipherSuite> <cipherSuite>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</cipherSuite> </supportedCipherSuites> + <!-- ... --> </tls> .... -Each of these block has an optional boolean configuration element <b>socketTLS</b> and <b>startTLS</b> which is used to toggle -use of SSL or TLS for the service. - -With socketTLS (SSL/TLS in Thunderbird), all the communication is encrypted. - -With startTLS (STARTTLS in Thunderbird), the preamble is readable, but the rest is encrypted. - -.... -* OK JAMES IMAP4rev1 Server Server 192.168.1.4 is ready. -* CAPABILITY IMAP4rev1 LITERAL+ CHILDREN WITHIN STARTTLS IDLE NAMESPACE UIDPLUS UNSELECT AUTH=PLAIN -1 OK CAPABILITY completed. -2 OK STARTTLS Begin TLS negotiation now. -... rest is encrypted... -.... - -You can only enable one of the both at the same time for a service. - -It is also recommended to change the port number on which the service will listen: - -* POP3 - port 110, Secure POP3 - port 995 -* IMAP - port 143, Secure IMAP4 - port 993 -* SMTP - port 25, Secure SMTP - port 465 - -You will now need to create your certificate store and place it in the james/conf/ folder with the name you defined in the keystore tag. - -Please note `JKS` keystore format is also supported (default value if no keystore type is specified): - -[source,xml] -.... -<tls socketTLS="false" startTLS="true"> - <keystore>file://conf/keystore</keystore> - <keystoreType>JKS</keystoreType> - <secret>yoursecret</secret> - <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> -</tls> -.... - - -=== TLS session cache +=== TLS Session Cache TLS session resumption allows clients to reconnect without performing a full TLS handshake, reducing CPU usage and connection latency. - -James caches completed TLS sessions server-side using the JDK `SSLSessionContext`. The cache size can be configured with `sessionCacheSize`: +James caches completed TLS sessions server-side using the JDK `SSLSessionContext`. [source,xml] .... @@ -118,22 +219,20 @@ James caches completed TLS sessions server-side using the JDK `SSLSessionContext <keystoreType>PKCS12</keystoreType> <secret>yoursecret</secret> - <sessionCache> - <size>1024</size> - <timeout>600s</timeout> - </sessionCache> + <sessionCache> + <size>1024</size> + <timeout>600s</timeout> + </sessionCache> </tls> .... When a cached session is found, the client and server skip the asymmetric key exchange and certificate verification, -reusing the previously negotiated symmetric keys. This is particularly effective for mail clients that open many -short-lived connections (e.g. mobile push sync). +reusing the previously negotiated symmetric keys. This is particularly effective for email clients that open many +short-lived connections (e.g., mobile push sync). -The `timeout` is expressed in seconds (`s`), minutes (`m`), or hours (`h`). If `sessionCache` is omitted, the JDK defaults are used. +=== Client Authentication -=== Client authentication via certificates - -When you enable TLS, you may also configure the server to require a client certificate for authentication: +When you enable TLS, you may also configure the server to require a client certificate for authentication. [source,xml] .... @@ -146,134 +245,131 @@ When you enable TLS, you may also configure the server to require a client certi <truststore>file://conf/truststore</truststore> <truststoreType>JKS</truststoreType> <truststoreSecret>yoursecret</truststoreSecret> - <enableOCSPCRLChecks>false</enableOCSPCRLChecks> </clientAuth> + <enableOCSPCRLChecks>false</enableOCSPCRLChecks> </tls> .... -James verifies client certificates against the provided truststore. You can fill it with trusted peer certificates directly, or an issuer certificate (CA) if you trust all certificates created by it. If you omit the truststore configuration, James will use the Java default truststore instead, effectively trusting any known CA. - -James can optionally enable OCSP verifications for client certificates against Certificate Revocation List referenced -in the certificate itself. +== Certificates by Well-Known Root CA (Preferred) -== Creating your own PEM keys +In order for MUAs and other email servers to trust the certificates by your email server out of the box, they need to be issued (at least transitively) by a trusted root CA. +The easiest and cheapest way to get such a certificate is by using ACME. -The following commands can be used to create self signed PEM keys: - -[source,xml] -.... -# Generating your private key -openssl genrsa -des3 -out private.key 2048 +We recommend to use either RSA (with at least 4,096 bits key size) or ECDSA as signature algorithm. +Those may not provide the best security but they are the algorithms with the best support among MUAs and MXs. +The tools presented below choose a reasonable default so you do not have to configure the algorithm at all. -# Creating your certificates -openssl req -new -key private.key -out certs.csr +Although most ACME clients are built for requesting certificates for websites, +you can easily use them to request certificates for an email server. +Some ACME clients that work well are Caddy and certbot. +You must only be able to set up an ACME client to listen on port 80 on the domain you want a certificate for. -# Signing the certificate yourself -openssl x509 -req -days 365 -in certs.csr -signkey private.key -out certs.self-signed.csr +A Caddy server with the following configuration file obtains a certificate for the domain `imap.example.internal`. -# Removing the password from the private key -# Not necessary if you supply the secret in the configuration -openssl rsa -in private.key -out private.nopass.key +.Caddyfile +[source] +.... +{ + email <Email address for Let's Encrypt> + events { + on cert_obtained exec cert-hook.sh {event.data.identifier} {event.data.private_key_path} {event.data.certificate_path} + } +} + +imap.example.internal { + respond 204 +} .... -You may then supply this TLS configuration: +With certbot, you can use the command -[source,xml] +[source] .... -<tls socketTLS="true" startTLS="false"> - <privateKey>file://conf/private.nopass.key</privateKey> - <certificates>file://conf/certs.self-signed.csr</certificates> -</tls> +certbot certonly \ + -c config.ini \ + --non-interactive \ + --cert-name imap \ + --domains imap.example.internal \ + --keep-until-expiring \ + --deploy-hook 'imap-deploy-hook.sh' .... -== Certificate Keystores - -This section gives more indication for users relying on keystores. - -=== Creating your own Certificate Keystore - -(Adapted from the Tomcat 4.1 documentation) - -James currently operates only on JKS or PKCS12 format keystores. This is Java's standard "Java KeyStore" format, and is -the format created by the keytool command-line utility. This tool is included in the JDK. - -To import an existing certificate into a JKS keystore, please read the documentation (in your JDK documentation package) -about keytool. - -To create a new keystore from scratch, containing a single self-signed Certificate, execute the following from a terminal -command line: +with the following config file to obtain a certificate for the same domain. +[source] .... -keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore your_keystore_filename +email = <Email address for Let's Encrypt> +agree-tos = true +authenticator = standalone +preferred-challenges = http .... -(The RSA algorithm should be preferred as a secure algorithm, and this also ensures general compatibility with other -servers and components.) - -As a suggested standard, create the keystore in the james/conf directory, with a name like james.keystore. - -After executing this command, you will first be prompted for the keystore password. +=== Automatic Certificate Renewal -Next, you will be prompted for general information about this Certificate, such as company, contact name, and so on. -This information may be displayed to users when importing into the certificate store of the client, so make sure that -the information provided here matches what they will expect. +As long as Caddy runs, it refreshes the certificate. +With a link:https://github.com/mholt/caddy-events-exec[plugin], Caddy can automatically execute a script after obtaining a new certificate. -Important: in the "distinguished name", set the "common name" (CN) to the DNS name of your James server, the one -you will use to access it from your mail client (like "mail.xyz.com"). +The solution with certbot requires you to execute the command regularly to refresh the certificate. +Using the deploy hook argument, a script can be executed after a certificate has been obtained. -Finally, you will be prompted for the key password, which is the password specifically for this Certificate -(as opposed to any other Certificates stored in the same keystore file). +These hooks should be used to make James aware of the new certificate. +First, the PEM files for private key and certificate must be copied to the path configured in James. +Afterward, James can be triggered to reload its certificates by POSTing to the `/servers?reload-certificate` endpoint of the webadmin API. -If everything was successful, you now have a keystore file with a Certificate that can be used by your server. +== Creating your own PEM Keys -You MUST have only one certificate in the keystore file used by James. +This approach should only be used during development. +The certificate will not be accepted by MUAs or other email servers. -=== Installing a Certificate provided by a Certificate Authority +The following commands can be used to create a self-signed PEM certificate: -(Adapted from the Tomcat 4.1 documentation - -To obtain and install a Certificate from a Certificate Authority (like verisign.com, thawte.com or trustcenter.de) -you should have read the previous section and then follow these instructions: - -==== Create a local Certificate Signing Request (CSR) - -In order to obtain a Certificate from the Certificate Authority of your choice you have to create a so called -Certificate Signing Request (CSR). That CSR will be used by the Certificate Authority to create a Certificate -that will identify your James server as "secure". To create a CSR follow these steps: +[source] +.... +# Generate a private key. +openssl genpkey -outform pem -out imap.key -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -* Create a local Certificate as described in the previous section. +# Create a self-signed certificate. +# Note that this is missing the SAN extension and is therefore not compliant to RFC 9525. +openssl x509 -new -set_subject '/CN=imap.example.internal' -key imap.key -keyform pem -outform pem -out imap.crt +.... -The CSR is then created with: +You may then supply this TLS configuration: +[source,xml] .... - keytool -certreq -keyalg RSA -alias james -file certreq.csr -keystore your_keystore_filename +<tls socketTLS="true" startTLS="false"> + <privateKey>file://conf/imap.key</privateKey> + <certificates>file://conf/imap.crt</certificates> +</tls> .... -Now you have a file called certreq.csr. The file is encoded in PEM format. You can submit it to the Certificate Authority -(look at the documentation of the Certificate Authority website on how to do this). In return you get a Certificate. +== Keystores -Now that you have your Certificate you can import it into you local keystore. First of all you may have to import a so -called Chain Certificate or Root Certificate into your keystore (the major Certificate Authorities are already in place, -so it's unlikely that you will need to perform this step). After that you can procede with importing your Certificate. +Keystores can be managed using the `keytool` utility which is included in the JDK. +It is possible to load certificates in the keystore that have been obtained by a trusted CA. -==== Optionally Importing a so called Chain Certificate or Root Certificate +The following approach shows how to create a keystore with a self-signed certificate and should only be used during development. +The certificate will not be accepted by MUAs or other email servers. -Download a Chain Certificate from the Certificate Authority you obtained the Certificate from. - -* For Verisign.com go to: http://www.verisign.com/support/install/intermediate.html -* For Trustcenter.de go to: http://www.trustcenter.de/certservices/cacerts/en/en.htm#server -* For Thawte.com go to: http://www.thawte.com/certs/trustmap.html (seems no longer valid) - -==== Import the Chain Certificate into you keystore +The following command creates a keystore with a self-signed certificate: +[source] .... -keytool -import -alias root -keystore your_keystore_filename -trustcacerts -file filename_of_the_chain_certificate +keytool \ + -alias imap \ + -genkeypair -keyalg rsa -keysize 4096 \ + -storetype pkcs12 -keystore keystore.p12 -storepass yoursecret \ + -dname 'CN=imap.example.internal' \ + -ext san=dns:imap.example.internal .... -And finally import your new Certificate (It must be in X509 format): +You may then supply this TLS configuration: +[source,xml] .... -keytool -import -alias james -keystore your_keystore_filename -trustcacerts -file your_certificate_filename +<tls socketTLS="true" startTLS="false"> + <keystore>file://conf/keystore.p12</keystore> + <keystoreType>PKCS12</keystoreType> + <secret>yoursecret</secret> +</tls> .... - -See also http://www.agentbob.info/agentbob/79.html[this page] \ No newline at end of file diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java index 89a2469a07..d0b43c0ff0 100644 --- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java +++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java @@ -156,7 +156,7 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC private static final String DEFAULT_TIME_UNIT = "SECONDS"; private static final String CAPABILITY_SEPARATOR = "|"; public static final int DEFAULT_MAX_LINE_LENGTH = 65536; // Use a big default - public static final Size DEFAULT_IN_MEMORY_SIZE_LIMIT = Size.of(10L, Size.Unit.M); // Use 10MB as default + public static final Size DEFAULT_IN_MEMORY_SIZE_LIMIT = Size.of(10L, Size.Unit.M); // Use 10MiB as default public static final int DEFAULT_TIMEOUT = 30 * 60; // default timeout is 30 minutes public static final int DEFAULT_LITERAL_SIZE_LIMIT = 0; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
