This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 9ff07ac1d47ef63b97c7d72fbc72a621905c3050 Author: Benoit TELLIER <[email protected]> AuthorDate: Fri Aug 28 16:41:44 2026 +0700 [DOC] Spring Antora documentation --- .../assets/images/server-components-no-jmap.png | Bin 0 -> 87907 bytes docs/modules/servers/nav.adoc | 41 +++ docs/modules/servers/pages/index.adoc | 15 +- .../servers/pages/jpa/architecture/index.adoc | 2 +- .../servers/pages/jpa/operate/security.adoc | 2 - .../spring/architecture/implemented-standards.adoc | 10 + .../pages/{jpa => spring}/architecture/index.adoc | 146 +++++----- .../servers/pages/spring/configure/database.adoc | 116 ++++++++ .../servers/pages/spring/configure/dns.adoc | 13 + .../servers/pages/spring/configure/domainlist.adoc | 13 + .../servers/pages/spring/configure/dsn.adoc | 15 + .../servers/pages/spring/configure/fetchmail.adoc | 310 +++++++++++++++++++++ .../servers/pages/spring/configure/imap.adoc | 16 ++ .../servers/pages/spring/configure/index.adoc | 109 ++++++++ .../servers/pages/spring/configure/indexer.adoc | 46 +++ .../servers/pages/spring/configure/jmx.adoc | 20 ++ .../servers/pages/spring/configure/mailbox.adoc | 42 +++ .../pages/spring/configure/mailetcontainer.adoc | 13 + .../servers/pages/spring/configure/mailets.adoc | 17 ++ .../spring/configure/mailrepositorystore.adoc | 74 +++++ .../servers/pages/spring/configure/matchers.adoc | 16 ++ .../servers/pages/spring/configure/mta-sts.adoc | 13 + .../servers/pages/spring/configure/oidc.adoc | 15 + .../servers/pages/spring/configure/pop3.adoc | 13 + .../servers/pages/spring/configure/quota.adoc | 114 ++++++++ .../spring/configure/recipientrewritetable.adoc | 13 + .../servers/pages/spring/configure/server.adoc | 13 + .../servers/pages/spring/configure/sieve.adoc | 17 ++ .../servers/pages/spring/configure/smtp-hooks.adoc | 13 + .../servers/pages/spring/configure/smtp.adoc | 15 + .../servers/pages/spring/configure/ssl.adoc | 13 + .../pages/spring/configure/usersrepository.adoc | 13 + .../spring/customization/mail-processing.adoc | 11 + .../pages/spring/customization/smtp-hooks.adoc | 10 + docs/modules/servers/pages/spring/index.adoc | 104 +++++++ docs/modules/servers/pages/spring/operate/cli.adoc | 20 ++ .../servers/pages/spring/operate/index.adoc | 29 ++ docs/modules/servers/pages/spring/operate/jmx.adoc | 88 ++++++ .../servers/pages/spring/operate/logging.adoc | 106 +++++++ .../servers/pages/spring/operate/security.adoc | 13 + docs/modules/servers/pages/spring/run.adoc | 114 ++++++++ docs/modules/servers/partials/configure/dsn.adoc | 7 + docs/modules/servers/partials/configure/imap.adoc | 13 + docs/modules/servers/partials/configure/jmx.adoc | 4 + docs/modules/servers/partials/configure/smtp.adoc | 13 + .../partials/customization/mail-processing.adoc | 7 + docs/modules/servers/partials/operate/cli.adoc | 6 +- .../modules/servers/partials/operate/security.adoc | 23 ++ .../servers/partials/spring/deprecated.adoc | 13 + docs/ui-overrides/partials/head-styles.hbs | 17 +- 50 files changed, 1814 insertions(+), 72 deletions(-) diff --git a/docs/modules/servers/assets/images/server-components-no-jmap.png b/docs/modules/servers/assets/images/server-components-no-jmap.png new file mode 100644 index 0000000000..8400f03e93 Binary files /dev/null and b/docs/modules/servers/assets/images/server-components-no-jmap.png differ diff --git a/docs/modules/servers/nav.adoc b/docs/modules/servers/nav.adoc index f04bac2d22..e920693144 100644 --- a/docs/modules/servers/nav.adoc +++ b/docs/modules/servers/nav.adoc @@ -197,5 +197,46 @@ **** xref:jpa/customization/smtp-hooks.adoc[] **** xref:jpa/customization/webadmin-routes.adoc[] *** xref:jpa/smtp-only.adoc[] +** xref:spring/index.adoc[] +*** xref:spring/architecture/index.adoc[] +**** xref:spring/architecture/implemented-standards.adoc[] +*** xref:spring/run.adoc[Run] +*** xref:spring/configure/index.adoc[] +**** Protocols +***** xref:spring/configure/server.adoc[Common Server Configuration] +***** xref:spring/configure/oidc.adoc[OIDC Configuration] +***** xref:spring/configure/imap.adoc[imapserver.xml] +***** xref:spring/configure/jmx.adoc[jmx.properties] +***** xref:spring/configure/smtp.adoc[smtpserver.xml & lmtpserver.xml] +***** xref:spring/configure/smtp-hooks.adoc[Packaged SMTP hooks] +***** xref:spring/configure/pop3.adoc[pop3server.xml] +***** xref:spring/configure/ssl.adoc[SSL & TLS] +***** xref:spring/configure/sieve.adoc[Sieve & ManageSieve] +**** Storage dependencies +***** xref:spring/configure/database.adoc[james-database.properties] +***** xref:spring/configure/mailbox.adoc[mailbox.xml] +***** xref:spring/configure/indexer.adoc[indexer.xml] +**** Core components +***** xref:spring/configure/dns.adoc[dnsservice.xml] +***** xref:spring/configure/domainlist.adoc[domainlist.xml] +***** xref:spring/configure/mailetcontainer.adoc[mailetcontainer.xml] +***** xref:spring/configure/mailets.adoc[Packaged Mailets] +***** xref:spring/configure/matchers.adoc[Packaged Matchers] +***** xref:spring/configure/mailrepositorystore.adoc[mailrepositorystore.xml] +***** xref:spring/configure/recipientrewritetable.adoc[recipientrewritetable.xml] +***** xref:spring/configure/usersrepository.adoc[usersrepository.xml] +***** xref:spring/configure/quota.adoc[quota.xml] +**** Extensions +***** xref:spring/configure/fetchmail.adoc[fetchmail.xml] +***** xref:spring/configure/dsn.adoc[ESMTP DSN support] +***** xref:spring/configure/mta-sts.adoc[MTA-STS] +*** xref:spring/operate/index.adoc[Operate] +**** xref:spring/operate/logging.adoc[] +**** xref:spring/operate/jmx.adoc[] +**** xref:spring/operate/cli.adoc[] +**** xref:spring/operate/security.adoc[] +*** Extending behaviour +**** xref:spring/customization/mail-processing.adoc[] +**** xref:spring/customization/smtp-hooks.adoc[] ** xref:test.adoc[] ** xref:migrating.adoc[] diff --git a/docs/modules/servers/pages/index.adoc b/docs/modules/servers/pages/index.adoc index 5ecf823eab..7e57d97388 100644 --- a/docs/modules/servers/pages/index.adoc +++ b/docs/modules/servers/pages/index.adoc @@ -1,7 +1,7 @@ = Apache James Mail Servers :navtitle: Servers -James offers five types of ready-made Mail Servers. The servers are intended +James offers six types of ready-made Mail Servers. The servers are intended for those with different needs, ranging from Operators who are interested in setting up a server for the first time, to experienced teams of Developers @@ -16,6 +16,7 @@ The available James Servers are: * <<distributed,James Distributed Mail Server>> * <<postgres,James Postgres Mail Server>> * <<jpa,James JPA Mail Server>> (deprecated) + * <<spring,James Spring Mail Server>> (deprecated) * <<test,James Test Server>> Whichever one you pick, once it is up and running you will likely need to bring your existing emails into it: @@ -65,6 +66,18 @@ future release. Use the <<postgres,Postgres Server>> instead. +[#spring] +== James Spring Mail Server + +The xref:spring/index.adoc[*Spring Server*] is the historical packaging of James: a single node server, wired with +the Spring framework rather than with Guice, storing its data in a relational database accessed through JPA. + +*It is deprecated*: it is not actively maintained anymore, offers neither JMAP nor the WebAdmin administration API, +and only a subset of the James components can be wired into it. Moving to the <<jpa,JPA Server>> requires no data +migration, and the <<postgres,Postgres Server>> is the recommended target for a new deployment. + + + [#test] == James Test Server diff --git a/docs/modules/servers/pages/jpa/architecture/index.adoc b/docs/modules/servers/pages/jpa/architecture/index.adoc index 8181bd1063..93f10d80cd 100644 --- a/docs/modules/servers/pages/jpa/architecture/index.adoc +++ b/docs/modules/servers/pages/jpa/architecture/index.adoc @@ -55,7 +55,7 @@ and about their implementations. Here is a high level view of the various server components and their interactions: -image::server-components.png[Server components mobilized for SMTP & IMAP] +image::server-components-no-jmap.png[Server components mobilized for SMTP & IMAP] * The SMTP protocol receives a mail, and enqueues it on the MailQueue. * The MailetContainer will start processing the mail asynchronously and will take business decisions like storing diff --git a/docs/modules/servers/pages/jpa/operate/security.adoc b/docs/modules/servers/pages/jpa/operate/security.adoc index 5a5a49adf6..7565f6d7f6 100644 --- a/docs/modules/servers/pages/jpa/operate/security.adoc +++ b/docs/modules/servers/pages/jpa/operate/security.adoc @@ -5,8 +5,6 @@ :backend-name: database :no-jmap: -:no-jmap: - include::partial$jpa/deprecated.adoc[] include::partial$operate/security.adoc[] diff --git a/docs/modules/servers/pages/spring/architecture/implemented-standards.adoc b/docs/modules/servers/pages/spring/architecture/implemented-standards.adoc new file mode 100644 index 0000000000..3c90839c4c --- /dev/null +++ b/docs/modules/servers/pages/spring/architecture/implemented-standards.adoc @@ -0,0 +1,10 @@ += Spring James Server — Implemented standards +:navtitle: Implemented standards + +:server-name: Spring James server +:no-jmap: +:no-acl: + +include::partial$spring/deprecated.adoc[] + +include::partial$architecture/implemented-standards.adoc[] diff --git a/docs/modules/servers/pages/jpa/architecture/index.adoc b/docs/modules/servers/pages/spring/architecture/index.adoc similarity index 52% copy from docs/modules/servers/pages/jpa/architecture/index.adoc copy to docs/modules/servers/pages/spring/architecture/index.adoc index 8181bd1063..2cd4b13b85 100644 --- a/docs/modules/servers/pages/jpa/architecture/index.adoc +++ b/docs/modules/servers/pages/spring/architecture/index.adoc @@ -1,32 +1,44 @@ -= JPA James Server — Architecture += Spring James Server — Architecture :navtitle: Architecture -:server-name: JPA James server +:server-name: Spring James server :backend-name: the database -:xref-base: jpa -:pages-path: jpa +:xref-base: spring +:pages-path: spring :mailet-repository-path-prefix: file -include::partial$jpa/deprecated.adoc[] +include::partial$spring/deprecated.adoc[] This section presents the {server-name} architecture. +== The Spring container + +Unlike every other James application, this one is not wired with Guice. Its entry point, +`org.apache.james.app.spring.JamesAppSpringMain`, boots a Spring application context out of +link:https://github.com/apache/james-project/blob/master/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml[`spring-server.xml`], +which imports one context file per component - mailet container, DNS, Fetchmail, SMTP, LMTP, POP3, IMAP, +ManageSieve, mailbox, quotas, event system, ActiveMQ mail queue. + +Three components are selected at runtime by a Spring `BeanFactoryPostProcessor` reading a configuration file: + +* the *mailbox* implementation, from xref:{xref-base}/configure/mailbox.adoc[mailbox.xml]; +* the *search index*, from xref:{xref-base}/configure/indexer.adoc[indexer.xml]; +* the *quota* components, from xref:{xref-base}/configure/quota.adoc[quota.xml]. + +Everything else is fixed by `spring-server.xml`. Editing that file is possible, but it lives inside the +`james-server-spring` JAR, and any implementation you point it at must actually be on the classpath. + == Storage The {server-name} is a single node deployment, and leverages the following storage strategies: -image::storage_james_jpa.png[Storage responsibilities for the {server-name}] - -* A *relational database*, accessed through JDBC and JPA, holds all the structured data: domains, users, -recipient rewriting rules, Sieve scripts, mailboxes, message metadata as well as message content. -* The *local file system* backs the Lucene full text search index, the ActiveMQ mail queue and the file mail -repositories. -* *link:https://spamassassin.apache.org/[SpamAssassin] or link:https://rspamd.com/[Rspamd]* (optional) can be -used for Spam detection, and user feedback is supported. +* A *relational database*, accessed through JDBC and JPA, holds the structured data: domains, users, recipient +rewriting rules, mailboxes, message metadata as well as message content. +* The *local file system* backs the Lucene full text search index (`var/store/lucene`), the ActiveMQ mail queue +(`var/store/activemq`), the file mail repositories (`var/mail`) and the Sieve scripts (`var/sieve`). -Unlike the xref:distributed/index.adoc[Distributed] and xref:postgres/index.adoc[Postgres] servers, there is no -BlobStore: message headers and bodies are stored within the database itself, and no object storage can be -plugged in. +There is no BlobStore: message headers and bodies are stored within the database itself, and no object storage can +be plugged in. == Protocols @@ -34,7 +46,6 @@ The following protocols are supported and can be used to interact with the {serv * *SMTP* * *IMAP* -* xref:{xref-base}/operate/webadmin.adoc[WebAdmin] REST Administration API * *LMTP* * *POP3* @@ -42,20 +53,18 @@ The following protocol should be considered experimental: * *ManagedSieve* -*JMAP is not supported* by this application. +*JMAP is not supported* by this application, and neither is the *WebAdmin* REST administration API: administration +happens over xref:{xref-base}/operate/jmx.adoc[JMX]. Read more on xref:{xref-base}/architecture/implemented-standards.adoc[implemented standards]. == Components -This section presents the various components of the {server-name}, providing context about their interactions, -and about their implementations. - === High level view Here is a high level view of the various server components and their interactions: -image::server-components.png[Server components mobilized for SMTP & IMAP] +image::server-components-no-jmap.png[Server components mobilized for SMTP & IMAP] * The SMTP protocol receives a mail, and enqueues it on the MailQueue. * The MailetContainer will start processing the mail asynchronously and will take business decisions like storing @@ -82,16 +91,12 @@ of `mailet`, `matcher` and `processor`. * A `mail repository` allows storage of a mail as part of its processing. The default configuration relies on the `file` protocol, thus storing those mails on the local file system: ** `{mailet-repository-path-prefix}://var/mail/error/` : unexpected errors that occurred during mail processing. -Emails impacted by performance related exceptions, or logical bug within James code are typically stored here. -These mails could be reprocessed once the cause of the error is fixed. The `Mail.error` field can help diagnose -the issue. Correlation with logs can be achieved via the use of the `Mail.name` field. ** `{mailet-repository-path-prefix}://var/mail/address-error/` : mail addressed to a non-existing recipient of a -handled local domain. These mails could be reprocessed once the user is created, for instance. -** `{mailet-repository-path-prefix}://var/mail/relay-denied/` : mail for whom relay was denied: missing -authentication can, for instance, be a cause. In addition to prevent disasters upon miss configuration, an email -review of this mail repository can help refine a host spammer blacklist. -** `{mailet-repository-path-prefix}://var/mail/rrt-error/` : runtime error upon Recipient Rewriting occurred. -This is typically due to a loop. +handled local domain. +** `{mailet-repository-path-prefix}://var/mail/relay-denied/` : mail for whom relay was denied. + +Beware that, WebAdmin being absent, the {server-name} offers *no way to list or reprocess the content of a mail +repository*. Those folders have to be audited, and if needed re-injected, by hand. Read more about xref:{xref-base}/configure/mailetcontainer.adoc[mail processing configuration]. @@ -100,9 +105,9 @@ Read more about xref:{xref-base}/configure/mailetcontainer.adoc[mail processing An email queue is a mandatory component of SMTP servers. It decouples email reception from email processing: queued emails wait for processing until the recipient is available to receive them. -The {server-name} relies on an *embedded ActiveMQ broker*, persisting its data on the local file system. As a -consequence the mail queue is not shared between James instances, and mails enqueued on a node can only be -processed by that same node. +The {server-name} relies on an *embedded ActiveMQ broker*, persisting its data on the local file system with the +KahaDB persistence adapter. As a consequence the mail queue is not shared between James instances, and mails +enqueued on a node can only be processed by that same node. Delays are supported, which allows exponential wait delays upon remote delivery retries. @@ -110,23 +115,30 @@ Delays are supported, which allows exponential wait delays upon remote delivery Storage for emails belonging to users. -Metadata, headers and bodies are all stored within the database. Attachments are stored in the database as well, -provided `attachmentStorage.enabled` is set within -xref:{xref-base}/configure/database.adoc[james-database.properties]. +The implementation is chosen in xref:{xref-base}/configure/mailbox.adoc[mailbox.xml]. Two providers are wired into +the Spring context: + +* `jpa` (the default): metadata, headers and bodies are all stored within the relational database. +* `memory`: everything is kept in the JVM heap and lost upon restart. This one is only useful for tests. + +Attachments are not stored: unlike the Guice JPA application, the `attachmentStorage.enabled` property is not read +by this application. ==== Search index -Emails are indexed in an embedded link:https://lucene.apache.org/[Lucene] index, living on the local file system, +The search index is chosen in xref:{xref-base}/configure/indexer.adoc[indexer.xml]. Emails can be indexed in an +embedded link:https://lucene.apache.org/[Lucene] index, living on the local file system under `var/store/lucene`, in order to empower email search. Text extraction relies on an in-JVM Jsoup based text extractor: no Tika server can be plugged in. Being local, that index cannot be shared across instances, and needs to be rebuilt - via the -xref:{xref-base}/operate/webadmin.adoc#_reindexing_all_mails[reIndexing WebAdmin tasks] - if it is lost. +xref:{xref-base}/operate/cli.adoc#_re_indexing[reIndexing CLI commands] - if it is lost. ==== Quotas -Current quotas of users are held in a database projection. Limitations can be defined per user, per domain or -globally. +Quotas are, unlike in every other James application, *disabled by default*: the shipped +xref:{xref-base}/configure/quota.adoc[quota.xml] wires the `fake` implementations, which report unlimited quotas +and refuse modifications. Enabling them requires selecting the `jpa` backed components. ==== Event Bus @@ -139,7 +151,6 @@ Many different kind of events can be triggered during a mailbox operation, such ** `MailboxDeletion`: a mailbox has been deleted ** `MailboxAdded`: a mailbox has been added ** `MailboxRenamed`: a mailbox has been renamed -** `MailboxACLUpdated`: a mailbox got its rights and permissions updated * `MessageEvent`: event related to an operation regarding a message: ** `Added`: messages have been added to a mailbox ** `Expunged`: messages have been expunged from a mailbox @@ -147,12 +158,10 @@ Many different kind of events can be triggered during a mailbox operation, such ** `MessageMoveEvent`: messages have been moved from a mailbox to another * `QuotaUsageUpdatedEvent`: event related to quota update -Mailbox listeners can register themselves on this event bus system to be called when an event is fired. Read more -about xref:{xref-base}/configure/listeners.adoc[listeners configuration] and -xref:{xref-base}/customization/mailbox-listeners.adoc[writing your own listeners]. - -Note that, unlike the Distributed server, the event dead letter of the {server-name} is kept *in memory*: events -that failed to be processed are lost upon restart. +Only the listeners hardwired in the Spring context register themselves on that event bus - the quota updater and +the search indexer. *Registering additional mailbox listeners is not supported* by this application: `listeners.xml` +is a Guice only configuration file. The event dead letter is kept *in memory*: events that failed to be processed +are lost upon restart. === Data @@ -161,6 +170,7 @@ Storage for domains and users. Domains and users are persisted in the database. Users can alternatively be managed via a LDAP (read only), see xref:{xref-base}/configure/usersrepository.adoc[usersrepository.xml]. +[#_recipient_rewrite_tables] === Recipient rewrite tables Storage of Recipients Rewriting rules, in the database. @@ -168,29 +178,33 @@ Storage of Recipients Rewriting rules, in the database. James allows using various mapping types for better expressing the intent of your address rewriting logic: * *Domain mapping*: Rewrites the domain of mail addresses. Use it for technical purposes, user will not be -allowed to use the source in their FROM address headers. Domain mappings can be managed via the CLI and added via -xref:{xref-base}/operate/webadmin.adoc#_domain_mappings[WebAdmin]. +allowed to use the source in their FROM address headers. * *Domain aliases*: Rewrites the domain of mail addresses. Express the idea that both domains can be used -inter-changeably. Domain aliases can be managed via -xref:{xref-base}/operate/webadmin.adoc#_get_the_list_of_aliases_for_a_domain[WebAdmin]. +inter-changeably. * *Forwards*: Replaces the source address by another one. Vehicles the intent of forwarding incoming mails to -other users. Forwards can be managed via xref:{xref-base}/operate/webadmin.adoc#_address_forwards[WebAdmin]. +other users. * *Groups*: Replaces the source address by another one. Vehicles the intent of a group registration (feature poor -mailing list). Groups can be managed via xref:{xref-base}/operate/webadmin.adoc#_address_group[WebAdmin]. +mailing list). * *Aliases*: Replaces the source address by another one. Represents a user owned mail address, with which he can -interact as if it was his main mail address. Aliases can be managed via -xref:{xref-base}/operate/webadmin.adoc#_address_aliases[WebAdmin]. +interact as if it was his main mail address. * *Address mappings*: Replaces the source address by another one. Use for technical purposes, this mapping type -does not hold specific intent. Address mappings can be managed via the CLI or via -xref:{xref-base}/operate/webadmin.adoc#_address_mappings[WebAdmin]. -* *Regex mappings*: Applies the regex on the supplied address. Regex mappings can be managed via the CLI or via -xref:{xref-base}/operate/webadmin.adoc#_regex_mapping[WebAdmin]. -* *Error*: Throws an error upon processing. Errors can be managed via the CLI. +does not hold specific intent. +* *Regex mappings*: Applies the regex on the supplied address. +* *Error*: Throws an error upon processing. -=== Task Manager +The {server-name} exposes address, domain and regex mappings through the +xref:{xref-base}/operate/cli.adoc#_managing_mappings[CLI]. The other mapping types are only manageable via +WebAdmin, and thus cannot be administered on this application - they are however honoured at runtime if present in +the database. -Allows to control and schedule long running tasks run by other components. Among others it enables scheduling, -progress monitoring and cancellation of long running tasks. +=== Fetchmail + +Fetchmail is a component specific to this application. It periodically connects to external POP3 or IMAP accounts, +downloads their content, and injects it into the James spool, where it goes through regular mail processing. + +Read more about xref:{xref-base}/configure/fetchmail.adoc[fetchmail.xml]. + +=== Task Manager -The {server-name} runs a memory based task manager: tasks are executed by the node they were submitted to, and -their history is lost upon restart. +The {server-name} instantiates a memory based task manager, but exposes no interface to submit tasks to it: the +WebAdmin task routes are absent. Long running operations are triggered synchronously over JMX instead. diff --git a/docs/modules/servers/pages/spring/configure/database.adoc b/docs/modules/servers/pages/spring/configure/database.adoc new file mode 100644 index 0000000000..781687f3f4 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/database.adoc @@ -0,0 +1,116 @@ += Spring James Server — james-database.properties +:navtitle: james-database.properties + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +This file is required. It tells James which relational database to use, and how to connect to it. + +Consult this link:{sample-configuration-prefix-url}/james-database.properties[example] +to get some examples and hints. + +James accesses the database through JDBC, and maps its entities with the +link:https://openjpa.apache.org/[Apache OpenJPA] implementation of the Java Persistence Architecture, in order to +avoid vendor specific SQL. The entities themselves are declared in `conf/META-INF/persistence.xml`. + +The database instance needs to be reachable from the James server. The account being used requires the usual +`SELECT`, `INSERT`, `UPDATE` and `DELETE` privileges, as well as table creation privileges: the schema is created +upon the first start. + +== Connection settings + +.james-database.properties content +|=== +| Property name | explanation + +| database.driverClassName +| The class name of the JDBC driver to be used. The driver needs to be on the classpath, see +<<_using_alternative_jdbc_drivers>>. + +| database.url +| The JDBC connection URL for your database. + +| database.username +| The user of the database account to be used by this connection. + +| database.password +| The password of the database account to be used by this connection. + +| datasource.testOnBorrow +| Optional. Boolean, defaults to `false`. Validates the connection before handing it out of the pool. + +| datasource.validationQuery +| Optional. The query used for the above validation. It is database specific, `select 1` being a frequent value. + +| datasource.validationQueryTimeoutSec +| Optional. Integer, defaults to `-1` (no timeout). Timeout of the validation query, in seconds. +|=== + +The default configuration relies on the embedded link:https://h2database.com[H2] database, which requires no +additional set up but is only suited for tests and small deployments: + +.... +database.driverClassName=org.h2.Driver +database.url=jdbc:h2:file:../var/store/h2db;DB_CLOSE_DELAY=-1 +database.username=app +database.password=app +.... + +NOTE: Unlike the xref:jpa/configure/database.adoc[JPA James server], the {server-name} reads *only* the properties +listed above. The generic `datasource.*` and `openjpa.*` pass-through, as well as the `attachmentStorage.enabled` +property, are Guice specific and have no effect here. Attachments are consequently not extracted nor stored. + +== Connection pooling + +The JPA datasource and connection pooling is delegated to +link:https://commons.apache.org/proper/commons-dbcp/[commons-dbcp]. Its settings are *fixed by the Spring context* +and cannot be configured from `james-database.properties`. The notable ones are: + +* a maximum of 21 active connections. This value is deliberately higher than the default count of spooler threads: +a spooler thread normally requires one connection to process a mail, but OpenJPA may need an extra one on top of +that. If the pool is smaller than the spooler thread count the server can dead-lock, see +link:https://issues.apache.org/jira/browse/JAMES-1317[JAMES-1317]. Raise the spooler thread count in +xref:{xref-base}/configure/mailetcontainer.adoc[mailetcontainer.xml] with care. +* a 30 seconds maximum wait for a connection, so that a mail fails to be processed rather than the server freezing. +* abandoned connection removal after 300 seconds, with logging. + +Connection pooling requires the `openjpa.Multithreaded` system property to be set to `true`, which the start +scripts do. + +[#_using_alternative_jdbc_drivers] +== Using alternative JDBC drivers + +Only the H2 driver is shipped by default. Using another database requires adding its JDBC driver JAR to the +`conf/lib` folder, which `bin/setenv.sh` prepends to the classpath. Then restart James. + +Here is a PostgreSQL example. Create the database first, as PostgreSQL does not create it on the fly: + +.... +psql --username postgres --command "CREATE DATABASE james" +.... + +Download the matching link:https://jdbc.postgresql.org/download/[PostgreSQL JDBC driver] into `conf/lib`, and +point `james-database.properties` at it: + +.... +database.driverClassName=org.postgresql.Driver +database.url=jdbc:postgresql://postgres-host/james +database.username=postgres +database.password=postgres +.... + +When using PostgreSQL, add `standard_conforming_strings=off` to your PostgreSQL configuration, otherwise queries +relying on `LIKE ... ESCAPE` fail with `Invalid escape string`. + +The same procedure applies to MariaDB and MySQL: + +.... +database.driverClassName=org.mariadb.jdbc.Driver +database.url=jdbc:mariadb://mariadb/james +database.username=james +database.password=james +.... diff --git a/docs/modules/servers/pages/spring/configure/dns.adoc b/docs/modules/servers/pages/spring/configure/dns.adoc new file mode 100644 index 0000000000..b7fb55658b --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/dns.adoc @@ -0,0 +1,13 @@ += Spring James Server — dnsservice.xml +:navtitle: dnsservice.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/dns.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/domainlist.adoc b/docs/modules/servers/pages/spring/configure/domainlist.adoc new file mode 100644 index 0000000000..5f53e715b6 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/domainlist.adoc @@ -0,0 +1,13 @@ += Spring James Server — domainlist.xml +:navtitle: domainlist.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/domainlist.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/dsn.adoc b/docs/modules/servers/pages/spring/configure/dsn.adoc new file mode 100644 index 0000000000..5cd86747f8 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/dsn.adoc @@ -0,0 +1,15 @@ += Spring James Server — Delivery Submission Notifications +:navtitle: ESMTP DSN support + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-rd-error-handling: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/dsn.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/fetchmail.adoc b/docs/modules/servers/pages/spring/configure/fetchmail.adoc new file mode 100644 index 0000000000..8fe1ed69f5 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/fetchmail.adoc @@ -0,0 +1,310 @@ += Spring James Server — fetchmail.xml +:navtitle: fetchmail.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +Fetchmail is *specific to the {server-name}*: no Guice application wires it. + +It acts as a gateway between an external message store - an IMAP or POP3 server - and James. Mail is fetched from +the external message store and injected into the James input spool, where it goes through regular +xref:{xref-base}/configure/mailetcontainer.adoc[mail processing], just as if it had been delivered over SMTP. + +Fetchmail is useful when delivery via standard SMTP is not an option, as a means of consolidating mail delivered to +several external accounts into a single James account, or to apply the mail processing capabilities of James to +mail stored in an external message store. + +Consult this link:{sample-configuration-prefix-url}/fetchmail.xml[example] to get some examples and hints. + +== How Fetchmail works + +Mail is delivered by periodically running *fetch tasks* that read messages from an external message store and +inject them into the James input spool. Fetch tasks run concurrently. + +A set of *filters* applies to each fetch task. Each filter can reject a message matching its criteria. Rejected +messages are not injected into the spool; they are either marked as seen or deleted. When a filter is configured to +accept a matching message, the message is marked with a Mail Attribute, which the matcher/mailet chain can then +detect for further processing. + +Each fetch task is associated with a single host server. *Accounts* are defined on the fetch task, one per mailbox +to fetch from. Accounts run consecutively, which avoids conflicting fetch tasks operating concurrently on the same +mailboxes. + +Optionally, a fetch task can be configured with an `alllocal` account, which generates an account entry for each +user defined in the James user repository. This removes the need to manually add or remove account entries each +time a James user is added or removed. It requires the external server to support virtual mailboxes sharing the +same password for all users of a domain. + +Accounts can be configured either to deliver all the mail of an account to a specified recipient - the usual case, +when a mailbox is guaranteed to hold mail for a single recipient - or to deduce the intended recipient from the +mail headers, which is needed when a mailbox holds mail for several users. + +== Configuration + +Configuration is held in `fetchmail.xml`, under a single `fetchmail` element. + +.`fetchmail` element +|=== +| Name | explanation + +| `enabled` (attribute) +| Boolean. If `true`, the fetch tasks are run periodically. Defaults to `false`. + +| `threads` +| The size of the thread pool used to run the fetch tasks. + +| `jmxName` +| The name under which the Fetchmail scheduler is exposed over JMX. + +| `fetch` +| Zero or more fetch tasks, see below. +|=== + +=== The `fetch` element + +A fetch task is identified by its `name` attribute, which must be unique. It accepts the following child elements: + +.`fetch` element +|=== +| Element | explanation + +| `accounts` +| Required. Declares the accounts to fetch from, see below. + +| `host` +| Required. The DNS name or IP address of the external server. + +| `interval` +| Required. The period between two invocations of the fetch task, in milliseconds. If the previous invocation is +still running when the period expires, the new invocation is skipped. + +| `javaMailProviderName` +| Required. The JavaMail protocol provider to use, typically `pop3` or `imap`. + +| `javaMailFolderName` +| Required. The case-sensitive name of the root folder to fetch from. Always `INBOX` for POP3 servers. + +| `javaMailProperties` +| Optional. A list of `<property name="..." value="..."/>` elements passed to the JavaMail session. Relying on the +provider defaults is rarely appropriate: the default connection and I/O timeouts are infinite. + +| `fetchall` +| Required. Boolean. If `true`, all the mail is fetched. If `false`, only the mail the server did not mark as seen. + +| `recursesubfolders` +| Required. Boolean. Should sub-folders of the root folder be fetched as well? + +| `defaultdomain` +| Optional. The domain appended to a `From:` header that has a valid local part but no domain part. Defaults to the +canonical host name of the James server. + +| `fetched` +| Required. What happens to mail successfully injected into the spool. + +| `remoteReceivedHeader` +| Optional. The zero-based index of the `Received` header used to compute the remote address and host name of the +sending MTA. Typically `1`. When omitted, or set to `-1`, the remote address is `127.0.0.1` and the remote host +name `localhost`. + +| `maxmessagesize` +| Optional. The maximum permitted message size, and what happens beyond it. + +| `undeliverable` +| Required. What happens to mail that cannot be delivered. + +| `recipientnotfound` +| Required. What happens to mail for which a sole intended recipient cannot be determined. + +| `blacklist` +| Required. A tab, comma or space delimited list of recipient addresses whose mail is rejected. + +| `userundefined` +| Required. What happens to mail whose recipient is not a James user. + +| `remoterecipient` +| Required. What happens to mail whose recipient domain is not handled by James. +|=== + +=== Filter attributes + +The `fetched`, `maxmessagesize`, `undeliverable`, `recipientnotfound`, `blacklist`, `userundefined` and +`remoterecipient` elements share the same set of attributes: + +.Filter attributes +|=== +| Attribute | explanation + +| `reject` +| Boolean. If `true`, the matching mail is not injected into the spool. If `false`, it is injected with a dedicated +Mail Attribute added, which the matcher/mailet chain can detect - for instance +`org.apache.james.fetchmail.isBlacklistedRecipient` or `org.apache.james.fetchmail.isUserUndefined`. + +| `leaveonserver` +| Boolean. If `true`, the mail is left on the server. If `false`, it is marked for deletion. + +| `markseen` +| Boolean. If `true`, the mail left on the server is marked as seen. + +| `defer` (`recipientnotfound` only) +| Boolean. If `true`, processing is deferred to the next run of the fetch task, giving the other accounts a chance +to determine the recipient first. + +| `limit` (`maxmessagesize` only) +| Integer. The maximum message size in kilobytes. `0` means no limit. + +| `index` (`remoteReceivedHeader` only) +| Integer. The index of the `Received` header to read. +|=== + +WARNING: The POP3 protocol only mandates support for the `DELETED` flag. On most POP3 servers `markseen="true"` +therefore has no effect, and `fetchall` is inoperative. The only reliable way of not fetching the same mail over +and over is to delete it from the server with `leaveonserver="false"`. + +=== The `accounts` element + +`accounts` holds any number of `account` elements, and at most one `alllocal` element. + +.`account` attributes +|=== +| Attribute | explanation + +| `user` +| The user used to connect to the external server. + +| `password` +| The password used to connect to the external server. + +| `recipient` +| The recipient the messages are delivered to when the intended recipient cannot be determined, or is to be ignored. + +| `ignorercpt-header` +| Boolean. If `true`, mail is always delivered to `recipient`. If `false`, the intended recipient is deduced from +the mail headers. + +| `customrcpt-header` +| Optional. The name of a header holding the recipient, for instance `X-Envelope-To`. +|=== + +.`alllocal` attributes +|=== +| Attribute | explanation + +| `userprefix` / `usersuffix` +| Strings surrounding the James user name to build the user passed to the external server. + +| `password` +| The password used to connect to the external server. All the accounts have to share it. + +| `recipientprefix` / `recipientsuffix` +| Strings surrounding the James user name to build the local recipient. + +| `ignorercpt-header` +| Boolean, with the same meaning as for `account`. +|=== + +== Examples + +=== One account, one user + +When all the mail of an account belongs to a single user, ignore the recipient found in the headers: + +[source,xml] +---- +<accounts> + <account user="[email protected]" password="password1" + recipient="user1@localhost" ignorercpt-header="true"/> + <account user="[email protected]" password="password2" + recipient="user2@localhost" ignorercpt-header="true"/> +</accounts> +---- + +=== One account, many users + +When an account holds mail for many users, deduce the recipient from the headers, and tell James what to do when +it cannot: + +[source,xml] +---- +<accounts> + <account user="[email protected]" password="password" + recipient="fetchmail@localhost" ignorercpt-header="false"/> +</accounts> +<recipientnotfound defer="false" reject="false" leaveonserver="false" markseen="false"/> +---- + +=== Dynamic accounts + +When the external server supports virtual mailboxes, `alllocal` keeps the accounts in sync with the James user +repository. The block below delivers `[email protected]` to `userX@localhost` for every James user: + +[source,xml] +---- +<accounts> + <alllocal userprefix="" usersuffix="@external.domain.com" password="mypassword" + recipientprefix="" recipientsuffix="@localhost" ignorercpt-header="true"/> +</accounts> +---- + +Both can be combined, `alllocal` guaranteeing delivery for all the local users and a global `account` processing +the rest. In that case use `<recipientnotfound defer="true" .../>` so that newly arrived mail for local users is +left to the next run of the dynamic accounts. + +=== Fetching Gmail over POP3 + +Do not forget to enable POP3 in your Gmail account first. + +[source,xml] +---- +<fetchmail enabled="true"> + <fetch name="gmail.com"> + <accounts> + <account user="[email protected]" password="YOUR_PASSWORD" + recipient="YOUR_EMAIL_ADDRESS_IN_JAMES" ignorercpt-header="true"/> + </accounts> + <host>pop.gmail.com</host> + <interval>600000</interval> + <javaMailProviderName>pop3</javaMailProviderName> + <javaMailFolderName>INBOX</javaMailFolderName> + <javaMailProperties> + <property name="mail.pop3.ssl.enable" value="true"/> + </javaMailProperties> + <fetchall>false</fetchall> + <recursesubfolders>false</recursesubfolders> + <defaultdomain>localhost</defaultdomain> + <fetched leaveonserver="true" markseen="true"/> + <remotereceivedheader index="1" reject="true" leaveonserver="true" markseen="false"/> + <maxmessagesize limit="0" reject="false" leaveonserver="true" markseen="false"/> + <undeliverable leaveonserver="true" markseen="false"/> + <recipientnotfound defer="true" reject="true" leaveonserver="true" markseen="false"/> + <blacklist reject="true" leaveonserver="true" markseen="false">wibble@localhost</blacklist> + <userundefined reject="true" leaveonserver="true" markseen="false"/> + <remoterecipient reject="true" leaveonserver="true" markseen="false"/> + </fetch> +</fetchmail> +---- + +Fetching over IMAP4 is the same, with `imap` as the provider name, `imap.gmail.com` as the host and +`mail.imap.ssl.enable` as the JavaMail property. + +== Detecting fetched mail in the mailet container + +All the mail injected by Fetchmail carries the `org.apache.james.fetchmail.taskName` Mail Attribute, whose value is +the name of the fetch task. Use the xref:{xref-base}/configure/matchers.adoc#_hasmailattribute[HasMailAttribute] +matcher to detect all the mail injected by Fetchmail, and +xref:{xref-base}/configure/matchers.adoc#_hasmailattributewithvalue[HasMailAttributeWithValue] to detect the mail +of a given fetch task. + +== Caveats + +* All the virtual accounts and the global account of an `alllocal` block must share the same password. +* When using dynamic accounts, an account is generated and a fetch attempted for every James user, even when no +such mailbox exists on the server. This is inefficient, but not fatal. +* When combining `alllocal` with a global account, the user name of the global account must *not* be a James user. +Otherwise a dynamic account is generated for it and fetches all the mail before the global account has an +opportunity to run. +* Fetchmail is scheduled and monitored over xref:{xref-base}/operate/jmx.adoc[JMX], under the +`org.apache.james:type=component,name=fetchmail` MBean. diff --git a/docs/modules/servers/pages/spring/configure/imap.adoc b/docs/modules/servers/pages/spring/configure/imap.adoc new file mode 100644 index 0000000000..ff2c756bf0 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/imap.adoc @@ -0,0 +1,16 @@ += Spring James Server — imapserver.xml +:navtitle: imapserver.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-kerberos: +:no-imap-extensions: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/imap.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/index.adoc b/docs/modules/servers/pages/spring/configure/index.adoc new file mode 100644 index 0000000000..6c85b64bb8 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/index.adoc @@ -0,0 +1,109 @@ += Spring James Server — Configuration +:navtitle: Configuration + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:xref-base: spring/configure +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +This section presents how to configure the {server-name}. + +Unlike the Guice applications, every configuration file is *shipped within the archive*, in the `conf` folder, with +a default value. Editing them in place is the way to configure the server; the defaults are templates and are not +suitable for a production deployment as such. Files can be removed, in which case the corresponding functionality +is disabled or falls back on reasonable defaults. + +The following configuration files are exposed: + +== For protocols + +By omitting these files, the underlying protocols will be disabled. + +** xref:{xref-base}/imap.adoc[*imapserver.xml*] allows configuration for the IMAP protocol link:{sample-configuration-prefix-url}/imapserver.xml[example] +** xref:{xref-base}/jmx.adoc[*jmx.properties*] allows configuration of JMX, which backs both administration and the Command Line Interface link:{sample-configuration-prefix-url}/jmx.properties[example] +** xref:{xref-base}/smtp.adoc#_lmtp_configuration[*lmtpserver.xml*] allows configuring the LMTP protocol link:{sample-configuration-prefix-url}/lmtpserver.xml[example] +** *managesieveserver.xml* allows configuration for ManagedSieve (unsupported) link:{sample-configuration-prefix-url}/managesieveserver.xml[example] +** xref:{xref-base}/pop3.adoc[*pop3server.xml*] allows configuration for the POP3 protocol (experimental) link:{sample-configuration-prefix-url}/pop3server.xml[example] +** xref:{xref-base}/smtp.adoc[*smtpserver.xml*] allows configuration for the SMTP protocol link:{sample-configuration-prefix-url}/smtpserver.xml[example] +*** xref:{xref-base}/smtp-hooks.adoc[This page] list SMTP hooks that can be used out of the box with the {server-name}. +** xref:{xref-base}/ssl.adoc[This page] details SSL & TLS configuration. +** xref:{xref-base}/sieve.adoc[This page] details Sieve setup and how to enable ManageSieve. + +There is no `jmap.properties` nor `webadmin.properties`: neither the JMAP protocol nor the WebAdmin REST API are +part of this application. + +== For storage dependencies + +** xref:{xref-base}/database.adoc[*james-database.properties*] tells James which relational database to use, and +how to connect to it. This file is required. link:{sample-configuration-prefix-url}/james-database.properties[example] +** *META-INF/persistence.xml* declares the JPA persistence unit - the entities to map and the OpenJPA settings. It +should not need editing. link:{sample-configuration-prefix-url}/META-INF/persistence.xml[example] +** xref:{xref-base}/mailbox.adoc[*mailbox.xml*] selects the mailbox implementation link:{sample-configuration-prefix-url}/mailbox.xml[example] +** xref:{xref-base}/indexer.adoc[*indexer.xml*] selects the search index implementation link:{sample-configuration-prefix-url}/indexer.xml[example] + +The {server-name} needs no other storage dependency: full text search is backed by an embedded Lucene index and +the mail queue by an embedded ActiveMQ broker, both living on the local file system. As a consequence +*blobstore.properties*, *opensearch.properties*, *rabbitmq.properties*, *redis.properties*, *tika.properties* and +*search.properties* are not supported. + +== For core components + +** xref:{xref-base}/dns.adoc[*dnsservice.xml*] allows to configure DNS resolution link:{sample-configuration-prefix-url}/dnsservice.xml[example] +** xref:{xref-base}/domainlist.adoc[*domainlist.xml*] allows to configure Domain storage link:{sample-configuration-prefix-url}/domainlist.xml[example] +** xref:{xref-base}/mailetcontainer.adoc[*mailetcontainer.xml*] allows configuring mail processing link:{sample-configuration-prefix-url}/mailetcontainer.xml[example] +*** xref:{xref-base}/mailets.adoc[This page] lists mailets that can be used out of the box with the {server-name}. +*** xref:{xref-base}/matchers.adoc[This page] lists matchers that can be used out of the box with the {server-name}. +** xref:{xref-base}/mailrepositorystore.adoc[*mailrepositorystore.xml*] enables registration of allowed MailRepository protocols and links them to MailRepository implementations link:{sample-configuration-prefix-url}/mailrepositorystore.xml[example] +*** *sqlResources.xml* holds the SQL statements used by the `db` and `dbfile` mail repositories link:{sample-configuration-prefix-url}/sqlResources.xml[example] +** xref:{xref-base}/recipientrewritetable.adoc[*recipientrewritetable.xml*] enables advanced configuration for the Recipient Rewrite Table component link:{sample-configuration-prefix-url}/recipientrewritetable.xml[example] +** xref:{xref-base}/usersrepository.adoc[*usersrepository.xml*] allows configuration of user storage link:{sample-configuration-prefix-url}/usersrepository.xml[example] +** xref:{xref-base}/quota.adoc[*quota.xml*] selects and enables the quota components link:{sample-configuration-prefix-url}/quota.xml[example] +** *sieverepository.xml* declares where Sieve scripts are stored. Only +`org.apache.james.sieverepository.file.SieveFileRepository` is wired in. link:{sample-configuration-prefix-url}/sieverepository.xml[example] + +*healthcheck.properties* is not supported: healthchecks are surfaced by WebAdmin, which this application does not +ship. *batchsizes.properties* is Cassandra specific and not supported either. + +== For extensions + +** xref:{xref-base}/fetchmail.adoc[*fetchmail.xml*] configures the Fetchmail component, which fetches mails from +external POP3 / IMAP accounts. This component is specific to this application. link:{sample-configuration-prefix-url}/fetchmail.xml[example] +** xref:{xref-base}/dsn.adoc[This page] specifies how to support SMTP Delivery Submission Notification (link:https://tools.ietf.org/html/rfc3461[RFC-3461]) +** xref:{xref-base}/mta-sts.adoc[This page] documents how to configure MTA-STS (RFC-8461) + +*extensions.properties* and *listeners.xml* are Guice only files and are not read by this application. Extra JARs +are loaded by dropping them in `conf/lib`, which `bin/setenv.sh` prepends to the classpath. There is no +`jvm.properties` either: extra system properties are declared in `conf/setenv.sh`, which the start scripts +source. + +== Logging + +Logging relies on link:https://logging.apache.org/log4j/2.x/[Log4j 2] and is configured in *log4j2.xml*, rather +than on logback as in the Guice applications. See xref:spring/operate/logging.adoc[logging]. + +== System properties + +Some tuning can be done via system properties. The start scripts generated in `bin` already set a few of them; +additional ones can be declared in `conf/setenv.sh`, which both scripts source. This includes: + +.System properties +|=== +| Property name | explanation + +| james.message.memory.threshold +| (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB. +This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk. +Below, data is stored in memory. Above data is stored on disk. + +| james.message.usememorycopy +| Optional. Boolean. The start scripts set it to `false`, which is the recommended value. +Should MimeMessageWrapper use a copy of the message in memory? Or should bigger message exceeding +james.message.memory.threshold be copied to temporary files? + +| openjpa.Multithreaded +| Boolean. Set to `true` by the start scripts. Required for the JDBC connection pool to behave correctly. + +| james.jmx.unregister.log4j.mbeans +| Optional. Boolean. Defaults to `true`. Unregisters the Log4j MBeans on start up. +|=== diff --git a/docs/modules/servers/pages/spring/configure/indexer.adoc b/docs/modules/servers/pages/spring/configure/indexer.adoc new file mode 100644 index 0000000000..1a7c4a10df --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/indexer.adoc @@ -0,0 +1,46 @@ += Spring James Server — indexer.xml +:navtitle: indexer.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +This configuration file is specific to the {server-name}. It selects the search index backing IMAP `SEARCH` and, +along with it, the re-indexing implementation exposed to the xref:{xref-base}/operate/cli.adoc[CLI]. + +Consult this link:{sample-configuration-prefix-url}/indexer.xml[example] to get some examples and hints. + +[source,xml] +---- +<indexer> + <provider>luceneIndex</provider> +</indexer> +---- + +.indexer.xml content +|=== +| Element | explanation + +| provider +| The search index implementation to use. Defaults to `lazyIndex`. The shipped configuration sets `luceneIndex`. +|=== + +Two providers are wired into the Spring context: + +* *luceneIndex*: emails are indexed in an embedded link:https://lucene.apache.org/[Lucene] index living on the +local file system, under `var/store/lucene`. Text extraction relies on an in-JVM Jsoup based text extractor: no +Tika server can be plugged in. Suffix matching is enabled. This is the provider you want. +* *lazyIndex*: no index is maintained. Searches are answered by scanning the mailbox content through the mailbox +mapper, which does not scale, and the re-indexing commands throw. + +Any other value makes the server fail to start with `Indexer provider ... not supported!`. + +NOTE: Older versions of this documentation mentioned an `elasticsearch` provider. The corresponding Spring context +is no longer part of James, and selecting it makes the server fail to start. OpenSearch based indexing is only +available on the xref:distributed/index.adoc[Distributed] and xref:postgres/index.adoc[Postgres] servers. + +The Lucene index is local to the instance. If it is lost or gets out of sync, rebuild it with the +xref:{xref-base}/operate/cli.adoc#_re_indexing[`ReindexAll` CLI command]. diff --git a/docs/modules/servers/pages/spring/configure/jmx.adoc b/docs/modules/servers/pages/spring/configure/jmx.adoc new file mode 100644 index 0000000000..b90dafacaa --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/jmx.adoc @@ -0,0 +1,20 @@ += Spring James Server — jmx.properties +:navtitle: jmx.properties + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-guice-jmx: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/jmx.adoc[] + +NOTE: Unlike the Guice applications, the {server-name} always starts its JMX server: there is no `jmx.enabled` +switch, and credentials are never generated. `conf/jmxremote.password` ships with a default `james-admin` / +`changeme` pair *that you must change*, and `conf/jmxremote.access` grants it `readwrite`. Both files are read +relatively to the `conf` folder. diff --git a/docs/modules/servers/pages/spring/configure/mailbox.adoc b/docs/modules/servers/pages/spring/configure/mailbox.adoc new file mode 100644 index 0000000000..c55ac96191 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/mailbox.adoc @@ -0,0 +1,42 @@ += Spring James Server — mailbox.xml +:navtitle: mailbox.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +This configuration file is specific to the {server-name}: the Guice applications hard-wire their mailbox +implementation instead. It selects which mailbox manager, subscription manager and mapper factory the Spring +context registers. + +Consult this link:{sample-configuration-prefix-url}/mailbox.xml[example] to get some examples and hints. + +[source,xml] +---- +<mailbox> + <provider>jpa</provider> +</mailbox> +---- + +.mailbox.xml content +|=== +| Element | explanation + +| provider +| The mailbox implementation to use. Defaults to `jpa`. +|=== + +Two providers are wired into the Spring context: + +* *jpa*: mailboxes, message metadata, headers and bodies are stored in the relational database configured in +xref:{xref-base}/configure/database.adoc[james-database.properties]. This is the only provider suitable for a real +deployment. +* *memory*: everything is kept in the JVM heap, and lost upon restart. It is only useful for tests. + +Any other value makes the server fail to start with `Mailboxmanager provider ... not supported!`. + +NOTE: Older versions of this documentation mentioned a `maildir` provider. It has been removed from James and is +no longer selectable. diff --git a/docs/modules/servers/pages/spring/configure/mailetcontainer.adoc b/docs/modules/servers/pages/spring/configure/mailetcontainer.adoc new file mode 100644 index 0000000000..a7e348a6e1 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/mailetcontainer.adoc @@ -0,0 +1,13 @@ += Spring James Server — mailetcontainer.xml +:navtitle: mailetcontainer.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/mailetcontainer.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/mailets.adoc b/docs/modules/servers/pages/spring/configure/mailets.adoc new file mode 100644 index 0000000000..b339533753 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/mailets.adoc @@ -0,0 +1,17 @@ += Spring James Server — Mailets +:navtitle: Packaged Mailets + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-jmap: +:no-icalendar: +:no-vacation: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/mailets.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/mailrepositorystore.adoc b/docs/modules/servers/pages/spring/configure/mailrepositorystore.adoc new file mode 100644 index 0000000000..2eef63cfa9 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/mailrepositorystore.adoc @@ -0,0 +1,74 @@ += Spring James Server — mailrepositorystore.xml +:navtitle: mailrepositorystore.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +A `mail repository` allows storage of a mail as part of its processing. + +A mail repository is identified by its *url*, constituted of a *protocol* and a *path*. For instance in the url +`file://var/mail/error/`, `file` is the protocol and `var/mail/error` the path. + +The *mailrepositorystore.xml* file registers the available protocols, and binds them to an actual MailRepository +implementation. The class is resolved from the classpath and instantiated by Spring, so your own implementations +can be added by dropping their JAR in `conf/lib`, which `bin/setenv.sh` prepends to the classpath. + +== Configuration + +Consult this link:{sample-configuration-prefix-url}/mailrepositorystore.xml[example] +to get some examples and hints. + +[source,xml] +---- +<mailrepositorystore> + <mailrepositories> + <mailrepository class="org.apache.james.mailrepository.file.FileMailRepository"> + <protocols> + <protocol>file</protocol> + </protocols> + <config FIFO="false" CACHEKEYS="true"/> + </mailrepository> + </mailrepositories> +</mailrepositorystore> +---- + +`file` is the default protocol of the {server-name}, and +*org.apache.james.mailrepository.file.FileMailRepository* is the only implementation shipped with it. It stores +each mail as a file under the given path, relative to the James working directory. Its `config` element supports: + +.FileMailRepository config attributes +|=== +| Attribute | explanation + +| FIFO +| Boolean, defaults to `false`. Should the mails be listed in the order they were added? + +| CACHEKEYS +| Boolean, defaults to `true`. Keeps the repository keys in memory, which speeds up listing at the price of heap +usage. +|=== + +WARNING: The shipped `mailrepositorystore.xml` also declares a `db` and a `dbfile` protocol, both bound to +`org.apache.james.mailrepository.jdbc.JDBCMailRepository`. *That class has been removed from James and those two +declarations are dead*: routing a mail to a `db://` or `dbfile://` repository fails at runtime. Remove them from +your configuration, and use `file://` repositories instead. + +== sqlResources.xml + +`sqlResources.xml` holds the SQL statements of the components that issue raw JDBC queries rather than going +through JPA. Its `org.apache.james.mailrepository.jdbc.JDBCMailRepository` section is vestigial, for the reason +stated above. Its `GreyList` and `NetworkWhiteList` sections are still used by the corresponding +xref:{xref-base}/configure/smtp-hooks.adoc[SMTP handlers], which take the path of this file as a `sqlFile` +parameter. + +== Operating mail repositories + +The {server-name} ships no WebAdmin API, and the CLI exposes no mail repository command. There is consequently *no +supported way of listing, exporting or reprocessing the content of a mail repository* on this application: the +`var/mail` folders have to be audited by hand. This is one of the strongest reasons to move to the +xref:jpa/index.adoc[JPA James server]. diff --git a/docs/modules/servers/pages/spring/configure/matchers.adoc b/docs/modules/servers/pages/spring/configure/matchers.adoc new file mode 100644 index 0000000000..e5b242cef2 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/matchers.adoc @@ -0,0 +1,16 @@ += Spring James Server — Matchers +:navtitle: Packaged Matchers + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-jmap: +:no-dlp: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/matchers.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/mta-sts.adoc b/docs/modules/servers/pages/spring/configure/mta-sts.adoc new file mode 100644 index 0000000000..cb81839a19 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/mta-sts.adoc @@ -0,0 +1,13 @@ += Spring James Server — MTA-STS +:navtitle: MTA-STS + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/mta-sts.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/oidc.adoc b/docs/modules/servers/pages/spring/configure/oidc.adoc new file mode 100644 index 0000000000..8427fde980 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/oidc.adoc @@ -0,0 +1,15 @@ += Spring James Server — OIDC Configuration +:navtitle: OIDC Configuration + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-jmap: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/oidc.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/pop3.adoc b/docs/modules/servers/pages/spring/configure/pop3.adoc new file mode 100644 index 0000000000..beb91320a8 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/pop3.adoc @@ -0,0 +1,13 @@ += Spring James Server — pop3server.xml +:navtitle: pop3server.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/pop3.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/quota.adoc b/docs/modules/servers/pages/spring/configure/quota.adoc new file mode 100644 index 0000000000..67dfaf40ec --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/quota.adoc @@ -0,0 +1,114 @@ += Spring James Server — quota.xml +:navtitle: quota.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +Quotas are limitations on a group of mailboxes, called a *quota root*. They can limit the *size* or the *message +count* of that group. Read link:https://tools.ietf.org/html/rfc2087[RFC-2087] for full details. + +This configuration file is specific to the {server-name}: the Guice applications wire their quota components +themselves and always have quotas enabled. Here, *quotas are disabled by default*, and each of the components +below has to be selected explicitly. + +Consult this link:{sample-configuration-prefix-url}/quota.xml[example] to get some examples and hints. + +== Components + +The quota subsystem is made of five components, each configured by a `provider` element: + +.quota.xml content +|=== +| Element | Accepted values | explanation + +| quotaRootResolver.provider +| `default` +| Finds to which QUOTA ROOT a mailbox belongs. `default` groups the mailboxes per user, and is the only accepted +value. + +| currentQuotaManager.provider +| `none`, `inmemory`, `jpa` +| Holds the counters: how many messages, and which size, does a quota root currently hold. Use `none` when the +quota manager is `fake`, `jpa` to persist the counters in the database, `inmemory` to keep them in the heap - in +which case they need to be recomputed after each restart. + +| maxQuotaManager.provider +| `fake`, `inmemory`, `jpa` +| Holds the limits. `fake` always answers UNLIMITED and throws upon modification. `jpa` persists per user, per +domain and global limits in the database, and is the one to use. `inmemory` keeps them in the heap. + +| quotaManager.provider +| `fake`, `store` +| Assembles the current quota manager and the max quota manager. `fake` returns only UNKNOWN / UNLIMITED quotas, +`store` performs the actual computation. + +| updates.provider +| `fake`, `event` +| Governs how the counters are updated. `event` plugs a listener on the event bus, updating the counters upon +`APPEND`, `COPY` and `EXPUNGE`. `fake` does not update anything. +|=== + +Any other value makes the server fail to start. + +WARNING: The comments of the shipped `quota.xml` are partly out of date. They mention a `fixed` value for +`maxQuotaManager`, which is *not* implemented and makes the server fail to start, and they name the global limits +`defaultMaxMessage` / `defaultMaxStorage`, whereas the elements actually read are `globalMaxMessage` / +`globalMaxStorage`. + +== Enabling quotas + +The shipped configuration wires the `fake` implementations everywhere, so quotas are inactive. A working set up +persisting everything in the relational database is: + +[source,xml] +---- +<quota> + <quotaRootResolver> + <provider>default</provider> + </quotaRootResolver> + <currentQuotaManager> + <provider>jpa</provider> + </currentQuotaManager> + <maxQuotaManager> + <provider>jpa</provider> + <globalMaxMessage>100000</globalMaxMessage> + <globalMaxStorage>5368709120</globalMaxStorage> + </maxQuotaManager> + <quotaManager> + <provider>store</provider> + </quotaManager> + <updates> + <provider>event</provider> + </updates> +</quota> +---- + +== Setting limits + +The `maxQuotaManager` element accepts global limits, applying to every quota root, and per quota root overrides. +Sizes are expressed in bytes: + +[source,xml] +---- +<maxQuotaManager> + <provider>jpa</provider> + <globalMaxMessage>100000</globalMaxMessage> + <globalMaxStorage>5368709120</globalMaxStorage> + <maxMessage> + <quotaRoot>#private&[email protected]</quotaRoot> + <value>200000</value> + </maxMessage> + <maxStorage> + <quotaRoot>#private&[email protected]</quotaRoot> + <value>10737418240</value> + </maxStorage> +</maxQuotaManager> +---- + +Those values are applied to the max quota manager on every start up. Beware when combining them with the +xref:{xref-base}/operate/cli.adoc#_manage_quotas[CLI quota commands]: the configuration file wins over what the CLI +recorded the previous time. diff --git a/docs/modules/servers/pages/spring/configure/recipientrewritetable.adoc b/docs/modules/servers/pages/spring/configure/recipientrewritetable.adoc new file mode 100644 index 0000000000..8eeaa10899 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/recipientrewritetable.adoc @@ -0,0 +1,13 @@ += Spring James Server — recipientrewritetable.xml +:navtitle: recipientrewritetable.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/recipientrewritetable.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/server.adoc b/docs/modules/servers/pages/spring/configure/server.adoc new file mode 100644 index 0000000000..b41833b2e9 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/server.adoc @@ -0,0 +1,13 @@ += Spring James Server — Common Server Configuration +:navtitle: Common Server Configuration + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/server.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/sieve.adoc b/docs/modules/servers/pages/spring/configure/sieve.adoc new file mode 100644 index 0000000000..71ce9d7195 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/sieve.adoc @@ -0,0 +1,17 @@ += Spring James Server — Sieve & ManageSieve +:navtitle: Sieve & ManageSieve + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/sieve.adoc[] + +NOTE: The {server-name} stores Sieve scripts on the local file system, under `var/sieve`, using +`org.apache.james.sieverepository.file.SieveFileRepository`. This is configured in `sieverepository.xml`, and this +implementation is the only one wired into the Spring application. diff --git a/docs/modules/servers/pages/spring/configure/smtp-hooks.adoc b/docs/modules/servers/pages/spring/configure/smtp-hooks.adoc new file mode 100644 index 0000000000..dfc92309e5 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/smtp-hooks.adoc @@ -0,0 +1,13 @@ += Spring James Server — SMTP Hooks +:navtitle: Packaged SMTP hooks + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/smtp-hooks.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/smtp.adoc b/docs/modules/servers/pages/spring/configure/smtp.adoc new file mode 100644 index 0000000000..1d6588baf5 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/smtp.adoc @@ -0,0 +1,15 @@ += Spring James Server — smtpserver.xml +:navtitle: smtpserver.xml & lmtpserver.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +:no-kerberos: + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/smtp.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/ssl.adoc b/docs/modules/servers/pages/spring/configure/ssl.adoc new file mode 100644 index 0000000000..686176bfcb --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/ssl.adoc @@ -0,0 +1,13 @@ += Spring James Server — SSL & TLS configuration +:navtitle: SSL & TLS + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/ssl.adoc[] diff --git a/docs/modules/servers/pages/spring/configure/usersrepository.adoc b/docs/modules/servers/pages/spring/configure/usersrepository.adoc new file mode 100644 index 0000000000..367de369d7 --- /dev/null +++ b/docs/modules/servers/pages/spring/configure/usersrepository.adoc @@ -0,0 +1,13 @@ += Spring James Server — usersrepository.xml +:navtitle: usersrepository.xml + +:sample-configuration-prefix-url: https://github.com/apache/james-project/blob/master/server/apps/spring-app/src/main/resources +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:backend-name: the database +:mailet-repository-path-prefix: file + +include::partial$spring/deprecated.adoc[] + +include::partial$configure/usersrepository.adoc[] diff --git a/docs/modules/servers/pages/spring/customization/mail-processing.adoc b/docs/modules/servers/pages/spring/customization/mail-processing.adoc new file mode 100644 index 0000000000..1f7d7e45fb --- /dev/null +++ b/docs/modules/servers/pages/spring/customization/mail-processing.adoc @@ -0,0 +1,11 @@ += Spring James Server — Custom mail processing +:navtitle: Custom mail processing + +:pages-path: spring +:xref-base: spring +:server-name: Spring James server +:no-extensions-jars: + +include::partial$spring/deprecated.adoc[] + +include::partial$customization/mail-processing.adoc[] diff --git a/docs/modules/servers/pages/spring/customization/smtp-hooks.adoc b/docs/modules/servers/pages/spring/customization/smtp-hooks.adoc new file mode 100644 index 0000000000..c1256c013a --- /dev/null +++ b/docs/modules/servers/pages/spring/customization/smtp-hooks.adoc @@ -0,0 +1,10 @@ += Spring James Server — Custom SMTP hooks +:navtitle: Custom SMTP hooks + +:pages-path: spring +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +include::partial$customization/smtp-hooks.adoc[] diff --git a/docs/modules/servers/pages/spring/index.adoc b/docs/modules/servers/pages/spring/index.adoc new file mode 100644 index 0000000000..dfe9e1c4f7 --- /dev/null +++ b/docs/modules/servers/pages/spring/index.adoc @@ -0,0 +1,104 @@ += Spring James Mail Server +:navtitle: Spring James Application + +include::partial$spring/deprecated.adoc[] + +The Spring James server is the historical packaging of Apache James. It is a *single node* mail server, wired +together with the link:https://spring.io/projects/spring-framework[Spring Framework] rather than with Guice, and +packaged as the link:https://github.com/apache/james-project/tree/master/server/apps/spring-app[spring-app] +application. It is distributed as a ZIP/tar.gz archive containing a `bin`, `conf`, `lib`, `log` and `var` folder. + +Like the xref:jpa/index.adoc[JPA James server], it stores its data in a relational database, accessed through JDBC +and mapped with the link:https://openjpa.apache.org/[Apache OpenJPA] implementation of the Java Persistence +Architecture. Full text search relies on an embedded link:https://lucene.apache.org/[Lucene] index and the mail +queue on an embedded ActiveMQ broker, both living on the local file system. + +Its distinguishing trait is that each component is chosen by editing a configuration file - which mailbox +implementation, which search index, which quota strategy - which is why it is historically presented as the most +configurable packaging. In practice, the set of implementations that remain wired into the Spring context is +small, and is documented on the xref:spring/architecture/index.adoc[architecture page]. + +== Supported features + +The following protocols are supported: + +* *SMTP* and *LMTP* +* *IMAP* +* *POP3* +* *ManageSieve* +* *Fetchmail*, which retrieves emails from external POP3 / IMAP accounts and injects them in the James spool. This +component is *only* available in this application. + +The server is administered through *JMX*, either with a JMX console or with the packaged +xref:spring/operate/cli.adoc[command line interface]. + +The following components are *not* available in this application: + +* The *WebAdmin* REST administration API. As a consequence the tasks it exposes - reprocessing mail repositories, +managing the DropList, exporting mailboxes... - cannot be run, and no Prometheus metric endpoint is exposed. +* The *JMAP* protocol. +* The *Deleted Messages Vault*, the *BlobStore* and its object storage backends, *OpenSearch* based search, and +the *RabbitMQ* based distributed mail queue and event bus. +* User defined *mailbox listeners*: `listeners.xml` is a Guice-only configuration file. The event bus is in +memory, and its dead letter is lost upon restart. +* The Guice *extension mechanism*: there is no `extensions-jars` folder, and `extensions.properties` is not read. +Extra JARs - your own mailets, matchers and SMTP hooks, or a JDBC driver - are added by dropping them in +`conf/lib`, which `bin/setenv.sh` prepends to the classpath. Mailbox listeners, WebAdmin routes, IMAP extensions, +pre-deletion hooks and user defined Guice modules have no equivalent here. +* *Kerberos GSSAPI* authentication, which is packaged as a Guice loaded extension. +* *DropLists*, *Rspamd*, *SpamAssassin*, *ClamAV* and *S/MIME* mailets: the corresponding JARs are not part of the +distribution. + +Mailbox sharing is not supported either: the JPA mailbox does not persist ACLs, hence +link:https://datatracker.ietf.org/doc/html/rfc4314.html[RFC-4314] IMAP ACL is not implemented. + +[#_moving_to_the_jpa_james_server] +== Moving to the JPA James server + +The xref:jpa/index.adoc[JPA James server] is the direct Guice successor of this application: same relational +database, same OpenJPA mapping, same Lucene index, same embedded ActiveMQ mail queue. *Switching requires no data +migration*: both applications declare the very same JPA entities, so the tables holding your domains, users, +rewriting rules, mailboxes, message metadata and message content are read as they are. + +The procedure is: + +. Stop the Spring instance. +. Deploy the JPA application and copy the values of your `conf/james-database.properties` over. Pointed at the same +database, it picks up your existing data. The default of both applications is the very same embedded H2 database, +`jdbc:h2:file:../var/store/h2db`. +. Copy over the configuration files that are common to both applications - `domainlist.xml`, `usersrepository.xml`, +`recipientrewritetable.xml`, `dnsservice.xml`, `imapserver.xml`, `smtpserver.xml`, `lmtpserver.xml`, +`pop3server.xml`, `managesieveserver.xml`, `mailetcontainer.xml`, `mailrepositorystore.xml`, `jmx.properties` - and +review them against the +link:https://github.com/apache/james-project/tree/master/server/apps/jpa-app/sample-configuration[JPA samples]. +. Copy the `var/mail` folder, so that the mails held in the `file://` mail repositories are preserved. + +A few points deserve attention: + +* *Sieve scripts are not migrated*. The Spring application stores them as files under `var/sieve`, while the JPA +application stores them in the database. Users need to re-upload their scripts. +* *The Lucene index is not migrated*: it does not live at the same place. Rebuild it with the +xref:jpa/operate/webadmin.adoc#_reindexing_all_mails[reIndexing WebAdmin task] once the JPA server is up. +* *The mail queue is not migrated*. Let the Spring instance finish processing its spool before stopping it. +* The `db` and `dbfile` mail repository protocols, backed by the legacy `JDBCMailRepository` and `sqlResources.xml`, +*do not exist* in the JPA application. If you use them, drain those repositories before switching. +* Configuration files with no equivalent - `mailbox.xml`, `indexer.xml`, `quota.xml`, `fetchmail.xml`, +`sieverepository.xml`, `sqlResources.xml`, `log4j2.xml` - are dropped. Quotas are always enabled in the JPA +application, logging moves to `logback.xml`, and there is no Fetchmail replacement. + +In exchange you get the WebAdmin API, healthchecks, Prometheus metrics, the Guice extension mechanism, a +maintained logging stack and a Docker image. + +If you can afford a data migration, prefer moving directly to the xref:postgres/index.adoc[Postgres James server], +which is not deprecated. See xref:migrating.adoc[migrating existing data]. + +== Read further + +In this section of the documentation, we will introduce you to: + +* xref:spring/architecture/index.adoc[Architecture of the Spring James server] +* xref:spring/run.adoc[Run the Spring James server] +* xref:spring/configure/index.adoc[Configure the Spring James server] +* xref:spring/operate/index.adoc[Operate the Spring James server] +* xref:spring/customization/mail-processing.adoc[Write your own mailets and matchers] +* xref:spring/customization/smtp-hooks.adoc[Write your own SMTP hooks] diff --git a/docs/modules/servers/pages/spring/operate/cli.adoc b/docs/modules/servers/pages/spring/operate/cli.adoc new file mode 100644 index 0000000000..a9206db061 --- /dev/null +++ b/docs/modules/servers/pages/spring/operate/cli.adoc @@ -0,0 +1,20 @@ += Spring James Server — Command Line Interface +:navtitle: Command Line Interface + +:xref-base: spring +:server-name: Spring James server +:no-droplist: +:no-jar-cli: + +include::partial$spring/deprecated.adoc[] + +The command line client of the {server-name} is `bin/james-cli.sh` - `bin/james-cli.bat` on Windows - and is +generated alongside the start scripts. It is a JMX client: the server has to be running, and +xref:{xref-base}/operate/jmx.adoc[its JMX endpoint] reachable. + +.... +$ cd bin +$ ./james-cli.sh -h 127.0.0.1 -p 9999 -username james-admin -password changeme COMMAND +.... + +include::partial$operate/cli.adoc[] diff --git a/docs/modules/servers/pages/spring/operate/index.adoc b/docs/modules/servers/pages/spring/operate/index.adoc new file mode 100644 index 0000000000..40a7755956 --- /dev/null +++ b/docs/modules/servers/pages/spring/operate/index.adoc @@ -0,0 +1,29 @@ += Spring James Server — Operate the Spring server +:navtitle: Operate the Spring server + +:xref-base: spring +:server-name: Spring James server +:server-tag: Spring + +include::partial$spring/deprecated.adoc[] + +The following pages detail how to operate the {server-name}. + +Once you have a {server-name} up and running you then need to ensure it operates correctly and has a decent +performance. You may also need to perform some operation maintenance or recover from incidents. This section covers +these topics. + +Read more about xref:{xref-base}/operate/logging.adoc[Logging]. + +*Administration of this application happens entirely over JMX*, as it does not ship the WebAdmin REST API. The +xref:{xref-base}/operate/jmx.adoc[JMX page] lists the exposed MBeans, and the +xref:{xref-base}/operate/cli.adoc[Command line interface] wraps the most common operations. Both are documented as +discouraged for a reason: JMX has a track record of vulnerabilities, and must never be exposed outside of the +loopback interface. Read xref:{xref-base}/operate/security.adoc[the security page]. + +There is no metric endpoint, and no Grafana board: the Dropwizard metric registry is instantiated but not +published anywhere. Latency and throughput observations have to be derived from the logs. + +We also included a guide for xref:migrating.adoc[migrating existing data] into the {server-tag} server. Read +xref:spring/index.adoc#_moving_to_the_jpa_james_server[this section] to move away from it, towards the JPA +application. diff --git a/docs/modules/servers/pages/spring/operate/jmx.adoc b/docs/modules/servers/pages/spring/operate/jmx.adoc new file mode 100644 index 0000000000..82ff8f77db --- /dev/null +++ b/docs/modules/servers/pages/spring/operate/jmx.adoc @@ -0,0 +1,88 @@ += Spring James Server — Administer over JMX +:navtitle: Administer over JMX + +:xref-base: spring +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +JMX is the *only* administration interface of the {server-name}: it ships no WebAdmin REST API. The +xref:{xref-base}/operate/cli.adoc[command line interface] is a client of that same JMX endpoint. + +WARNING: JMX poses several security concerns and has been leveraged to conduct arbitrary code execution - see +`CVE-2017-12628`, `CVE-2023-26269` and `CVE-2023-51518` on xref:{xref-base}/operate/security.adoc[the security +page]. Keep it bound to `127.0.0.1`, which is the shipped default, set up authentication, and run James in +isolation. Because the {server-name} cannot be administered without it, turning JMX off is not an option here. + +== Connecting + +The endpoint is configured in xref:{xref-base}/configure/jmx.adoc[jmx.properties], and defaults to +`127.0.0.1:9999`. Any JMX client can connect to: + +.... +service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi +.... + +Authentication is read from `conf/jmxremote.password` and `conf/jmxremote.access`, which ship with a default +`james-admin` / `changeme` pair holding `readwrite` permission. *Change that password.* Unlike the Guice +applications, this one never generates credentials for you. + +With `jconsole`, select the *MBeans* tab and open the `org.apache.james` node to browse the attributes and invoke +the operations. + +== Exposed MBeans + +The Spring context registers the following management beans under the `org.apache.james` domain: + +|=== +| Object name | What it manages + +| `type=component,name=domainlist` +| The handled domains: list, add, remove, contains. + +| `type=component,name=usersrepository` +| The users: list, add, remove, change password, test existence. + +| `type=component,name=recipientrewritetable` +| The address, domain, regex and error mappings. + +| `type=component,name=mailboxmanagerbean` +| The user mailboxes: list, create, delete, delete all the mailboxes of a user, import an EML file. + +| `type=component,name=quotamanagerbean` +| The quota roots and their limits. Only meaningful once quotas have been enabled in +xref:{xref-base}/configure/quota.adoc[quota.xml]. + +| `type=component,name=reindexerbean` +| Re-indexing of a mailbox, or of the whole server. A no-op when `indexer.xml` selects the `lazyIndex` provider. + +| `type=component,name=sievemanagerbean` +| The Sieve scripts and their quotas. + +| `type=component,name=mailboxcopier` +| Copies the content of one mailbox manager into another one. Experimental. + +| `type=component,name=dnsservice` +| The DNS resolution statistics. + +| `type=component,name=fetchmail` +| The xref:{xref-base}/configure/fetchmail.adoc[Fetchmail] scheduler. + +| `type=component,component=mailetcontainer,name=mailspooler` +| The mail spooler: thread count, and the count of mails currently being processed. +|=== + +Note what is *not* there: no mail repository management, no task manager, no health checks, no DropList, no event +dead letter. Those operations only exist through WebAdmin, and are therefore out of reach on this application. + +The mailet container additionally exposes per processor, per mailet and per matcher beans when +`enableJmx="true"` is set on a processor in +xref:{xref-base}/configure/mailetcontainer.adoc[mailetcontainer.xml], which is a convenient way of observing where +the mails go. + +== Changing the log level at runtime + +Log4j 2 registers its own MBeans, which allow changing a logger level without restarting. They are unregistered on +start up by default; set the `james.jmx.unregister.log4j.mbeans` system property to `false` in `conf/setenv.sh` to +keep them. Editing `conf/log4j2.xml` is the supported way, and is picked up within 30 seconds, see +xref:{xref-base}/operate/logging.adoc[logging]. diff --git a/docs/modules/servers/pages/spring/operate/logging.adoc b/docs/modules/servers/pages/spring/operate/logging.adoc new file mode 100644 index 0000000000..b6fa9a4a0e --- /dev/null +++ b/docs/modules/servers/pages/spring/operate/logging.adoc @@ -0,0 +1,106 @@ += Spring James Server — Logging +:navtitle: Logging + +:xref-base: spring +:server-name: Spring James server +:backend-name: database + +include::partial$spring/deprecated.adoc[] + +We recommend to closely monitoring *ERROR* and *WARNING* logs. Those logs should be considered not normal. + +If you encounter some suspicious logs: + +* If you have any doubt about the log being caused by a bug in James source code, please reach us via the bug +tracker, the user mailing list or our Gitter channel (see our xref:james-site::index.adoc[community page]) +* They can be due to insufficient performance from tier applications (eg {backend-name} timeouts). In such case we +advise you to conduct a close review of performances at the tier level. + +When reporting ERROR or WARNING logs, consider adding the full logs, and related data (eg the raw content of a mail +triggering an issue) to the bug report in order to ease resolution. + +== Logging configuration + +Unlike the Guice applications, which rely on link:http://logback.qos.ch/[logback], the {server-name} logs through +link:https://logging.apache.org/log4j/2.x/[Log4j 2], configured in `conf/log4j2.xml`. That file is scanned every 30 +seconds, so a level change is picked up without restarting the server. + +Every logger writes to the console and to a rolling file in the `log` folder. The shipped configuration declares, +amongst others: + +|=== +| Logger | File + +| `org.apache.james` +| `log/james.log` + +| `org.springframework` +| `log/springframework.log` + +| `openjpa` and `org.apache.openjpa` +| `log/openjpa.log` + +| `org.apache.james.transport` and `org.apache.james.protocols` +| `log/james_transport-protocols.log` + +| `org.apache.james.imapserver` +| `log/james_imapserver.log` + +| `org.apache.james.smtpserver` +| `log/james_smtpserver.log` + +| `org.apache.james.lmtpserver` +| `log/james_lmtpserver.log` + +| `org.apache.james.pop3server` +| `log/james_pop3server.log` + +| `org.apache.james.mailetcontainer` +| `log/james_mailetcontainer.log` + +| `org.apache.james.mailrepositorystore` +| `log/james_mailrepositorystore.log` + +| `org.apache.james.usersrepository` +| `log/james_usersrepository.log` + +| `org.apache.james.domainlist` +| `log/james_domainlist.log` + +| `org.apache.james.fetchmail` +| `log/james_fetchmail.log` + +| `org.apache.james.dnsservice` +| `log/james_dnsservice.log` +|=== + +The `logDir` property at the top of the file governs where those files are written, and defaults to +`${sys:app.home:-..}/log`. + +== Raising the log level of a protocol + +Protocol level troubleshooting is best done by raising the level of the corresponding logger. For instance, to +follow the whole SMTP dialogue: + +[source,xml] +---- +<Logger name="org.apache.james.smtpserver" level="debug" additivity="false"> + <AppenderRef ref="Console" level="info"/> + <AppenderRef ref="SMTPSERVER" level="debug"/> +</Logger> +---- + +The session identifier is logged along each line, which lets you follow a whole transaction even under +concurrency. Responses in the `4xx` and `5xx` ranges are logged at `INFO`, the rest at `DEBUG`. The same applies to +`org.apache.james.imapserver` and `org.apache.james.pop3server`. + +Beware that debug level protocol logs contain the content of the emails being processed, and, on unencrypted +channels, the credentials sent by your users. + +== Structured logging + +Log4j 2 can output JSON with its `JsonTemplateLayout`, in place of the shipped `PatternLayout`. The corresponding +JAR - `log4j-layout-template-json` - is not part of the distribution, and has to be dropped in `conf/lib` first. + +The protocol layer populates the logging MDC with the session context - remote IP, protocol, session identifier, +and the authenticated user once known - so it is worth including the MDC in whichever layout you settle on. diff --git a/docs/modules/servers/pages/spring/operate/security.adoc b/docs/modules/servers/pages/spring/operate/security.adoc new file mode 100644 index 0000000000..70e4d582db --- /dev/null +++ b/docs/modules/servers/pages/spring/operate/security.adoc @@ -0,0 +1,13 @@ += Spring James Server — Security +:navtitle: Security + +:xref-base: spring +:server-name: Spring James server +:backend-name: database +:no-jmap: +:no-webadmin: +:no-spam: + +include::partial$spring/deprecated.adoc[] + +include::partial$operate/security.adoc[] diff --git a/docs/modules/servers/pages/spring/run.adoc b/docs/modules/servers/pages/spring/run.adoc new file mode 100644 index 0000000000..eb40047e7e --- /dev/null +++ b/docs/modules/servers/pages/spring/run.adoc @@ -0,0 +1,114 @@ += Spring James Server — Run +:navtitle: Run + +:server-name: Spring James server + +include::partial$spring/deprecated.adoc[] + +The {server-name} is distributed as a binary archive to be run on a Java Virtual Machine. *No Docker image is +published for it.* + +== Requirements + +* A Java {java-version} JRE. `JAVA_HOME` needs to point at the JRE home directory. +* A relational database. By default the embedded H2 database is used, and requires no set up. See +xref:spring/configure/database.adoc[james-database.properties] for using another one. +* On Linux/Unix, `root` privileges - or the corresponding capabilities - are needed to bind the IANA registered +ports of SMTP (25), POP3 (110) and IMAP (143). On Windows, Administrator privileges are needed. +* The server launches with `-Xms128m -Xmx512m`. Adjust it depending on your load. + +== Building the artifact + +The archive is built from +link:https://github.com/apache/james-project[the James git repository], with a Java {java-version} SDK and Maven 3: + +.... +mvn clean install -DskipTests +.... + +This produces `server/apps/spring-app/target/james-server-spring-app.zip` and its `tar.gz` counterpart. + +== Deploying + +Unpack the archive in your installation directory. You obtain the following layout: + +.... +bin/ start scripts, and the james-cli client +conf/ the configuration files, and conf/lib for the extra JARs +lib/ the James JARs +log/ the log files +var/ the mail repositories, the Sieve scripts, the Lucene index, the ActiveMQ store and the H2 database +.... + +The `conf` folder ships every configuration file with sane defaults, which you need to review before running in +production. Read xref:spring/configure/index.adoc[the configuration section]. At the very least: + +* Set the postmaster address in `conf/mailetcontainer.xml`. +* Change the JMX credentials in `conf/jmxremote.password`, which ships with a default `james-admin` / `changeme` +pair. +* Generate a keystore if you intend to run SSL or STARTTLS: + +.... +$ keytool -genkey -alias james -keyalg RSA -storetype PKCS12 -keystore conf/keystore +.... + +== Running + +The archive ships two ways of starting the server, both in the `bin` folder: + +* `run.sh` / `run.bat` runs James in the foreground. +* `james` is a link:https://wrapper.tanukisoftware.com/[Java Service Wrapper] daemon script, supporting +`start`, `stop`, `restart`, `status` and `console`. On Linux it requires `libc6`. + +.... +$ cd bin +$ ./james start +.... + +Additional JVM options and classpath entries are set in `conf/setenv.sh`, which is sourced by both scripts. +`conf/lib/*` is always prepended to the classpath: this is where JDBC drivers and your own extensions belong. + +Logs are written to the `log` folder, `log/james.log` being the main one. See +xref:spring/operate/logging.adoc[logging]. + +== Creating domains and users + +A fresh server holds no domain and no user. Both are created with the packaged +xref:spring/operate/cli.adoc[command line interface], which talks JMX: + +.... +$ cd bin +$ ./james-cli.sh -h 127.0.0.1 -p 9999 -username james-admin -password changeme adddomain mydomain.tld +$ ./james-cli.sh -h 127.0.0.1 -p 9999 -username james-admin -password changeme adduser [email protected] mypassword +.... + +Virtual hosting is enabled by default, so the user name is the full email address. + +== Testing your installation + +Send an email over SMTP: + +.... +$ telnet 127.0.0.1 25 +220 mydomain.tld SMTP Server (JAMES SMTP Server) ready +ehlo test +250-mydomain.tld Hello test (localhost [127.0.0.1]) +250-PIPELINING +250-ENHANCEDSTATUSCODES +250 8BITMIME +mail from:<[email protected]> +250 2.1.0 Sender <[email protected]> OK +rcpt to:<[email protected]> +250 2.1.5 Recipient <[email protected]> OK +data +354 Ok Send data ending with <CRLF>.<CRLF> +subject: test + +this is a test +. +250 2.6.0 Message received +quit +.... + +Then retrieve it over IMAP (port 143) or POP3 (port 110), and check `log/james.log` along the way. Actions taken by +James on incoming mail are driven by `conf/mailetcontainer.xml`. diff --git a/docs/modules/servers/partials/configure/dsn.adoc b/docs/modules/servers/partials/configure/dsn.adoc index 87ee6ea6c7..542459c5dc 100644 --- a/docs/modules/servers/partials/configure/dsn.adoc +++ b/docs/modules/servers/partials/configure/dsn.adoc @@ -31,9 +31,16 @@ For this simply add the `DSN hooks` in the handler chain in `smtpserver.xml` : == Enabling DSN generation as part of mail processing +ifndef::no-rd-error-handling[] For the below conditions to be matched we assume you follow xref:{pages-path}/configure/remote-delivery-error-handling.adoc[RemoteDelivery error handling for MXs], which is a requirement for detailed RemoteDelivery error and delay handling on top of the {server-name}. +endif::[] +ifdef::no-rd-error-handling[] +For the below conditions to be matched we assume RemoteDelivery is set up to categorise its failures with the +`IsRemoteDeliveryPermanentError` and `IsRemoteDeliveryTemporaryError` matchers, which is a requirement for detailed +RemoteDelivery error and delay handling on top of the {server-name}. +endif::[] Here is a sample xref:{pages-path}/configure/mailetcontainer.adoc[mailetcontainer.xml] achieving the following DSN generation: diff --git a/docs/modules/servers/partials/configure/imap.adoc b/docs/modules/servers/partials/configure/imap.adoc index 459c88d66e..97249222dc 100644 --- a/docs/modules/servers/partials/configure/imap.adoc +++ b/docs/modules/servers/partials/configure/imap.adoc @@ -118,15 +118,24 @@ It is an optional boolean that defaults to `true`. | Optional comma-separated list of SASL mechanism factory class names. When present, this list replaces the default mechanisms. Built-in factories can be named by their simple class name; extension factories must use their fully qualified class name. +ifndef::no-kerberos[] See xref:{pages-path}/configure/kerberos.adoc[Kerberos GSSAPI authentication] for an extension example. +endif::[] | `auth.requireSSL` +ifndef::no-kerberos[] | Configures whether the authentication mechanisms `PLAIN`, `LOGIN`, and optional `GSSAPI` require a secure connection (TLS or STARTTLS). +endif::[] +ifdef::no-kerberos[] +| Configures whether the authentication mechanisms `PLAIN` and `LOGIN` require a secure connection (TLS or STARTTLS). +endif::[] It has no effect on other authentication mechanisms. For `PLAIN` and `LOGIN`, it has no effect if `plainAuthEnabled` is `false`. The value is optional. For `PLAIN` and `LOGIN`, if not configured, it uses the value of `plainAuthDisallowed` (which defaults to `true`) as fallback. +ifndef::no-kerberos[] For `GSSAPI`, if not configured, it defaults to `true`. +endif::[] | `auth.adminUsers` | Configures admin users that are authorized to impersonate any IMAP user. @@ -137,9 +146,11 @@ It is an optional element containing `adminUser` elements. | Configures authentication via OIDC. The configuration is described in more detail xref:{pages-path}/configure/oidc.adoc[here]. +ifndef::no-kerberos[] | `auth.gssapi` | Configures optional Kerberos authentication through the `GSSAPI` SASL mechanism. The configuration is described in more detail xref:{pages-path}/configure/kerberos.adoc[here]. +endif::[] |=== @@ -210,6 +221,7 @@ Sample configuration: Note that commands are delayed prior to their execution and thus are not subject to the setting `concurrentRequests` until they are executed. +ifndef::no-imap-extensions[] == Extending IMAP IMAP decoders, processors and encoders can be customized. @@ -242,6 +254,7 @@ This element can be used multiple times. Using this enables configuring custom IMAP extensions without touching the code responsible for loading the configuration. |=== +endif::[] == Auto-Configuration for Mail User Agents diff --git a/docs/modules/servers/partials/configure/jmx.adoc b/docs/modules/servers/partials/configure/jmx.adoc index 706bd52298..8f68393185 100644 --- a/docs/modules/servers/partials/configure/jmx.adoc +++ b/docs/modules/servers/partials/configure/jmx.adoc @@ -17,8 +17,10 @@ in GIT to get some examples and hints. |=== | Property name | explanation +ifndef::no-guice-jmx[] | jmx.enabled | Boolean. Should the JMX server be enabled? Defaults to `true`. +endif::[] | jmx.address |The IP address (host name) the MBean Server will bind/listen to. @@ -49,8 +51,10 @@ File's content example: james-admin readwrite ``` +ifndef::no-guice-jmx[] When James runs with option `-Djames.jmx.credential.generation=true`, James will automatically generate `jmxremote.password` if the file does not exist. Then the default username is `james-admin` and a random password. This option defaults to true. +endif::[] === James-cli diff --git a/docs/modules/servers/partials/configure/smtp.adoc b/docs/modules/servers/partials/configure/smtp.adoc index 341aefe033..e1cb27b62e 100644 --- a/docs/modules/servers/partials/configure/smtp.adoc +++ b/docs/modules/servers/partials/configure/smtp.adoc @@ -151,14 +151,18 @@ However, if authentication capabilities are not announced, only the mechanisms ` | 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`. +ifndef::no-kerberos[] The optional `GSSAPI` mechanism also uses this value to reject authentication attempts over an insecure connection. +endif::[] It is an optional boolean that defaults to `true`. For the built-in mechanisms, this configures only the **announcement** of authentication capabilities. Even if authentication capabilities are not announced, clients can still use the SMTP AUTH command with `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`. +ifndef::no-kerberos[] When `GSSAPI` is configured and `auth.requireSSL` is `true`, it is both unannounced and unavailable on insecure connections. +endif::[] | `auth.plainAuthEnabled` | Enables the authentication mechanisms `PLAIN` and `LOGIN`. @@ -168,15 +172,19 @@ It is an optional boolean that defaults to `true`. | Optional comma-separated list of SASL mechanism factory class names. When present, this list replaces the default mechanisms. Built-in factories can be named by their simple class name; extension factories must use their fully qualified class name. +ifndef::no-kerberos[] See xref:{pages-path}/configure/kerberos.adoc[Kerberos GSSAPI authentication] for an extension example. +endif::[] | `auth.oidc` | Configures authentication via OIDC. The configuration is described in more detail xref:{pages-path}/configure/oidc.adoc[here]. +ifndef::no-kerberos[] | `auth.gssapi` | Configures optional Kerberos authentication through the `GSSAPI` SASL mechanism. The configuration is described in more detail xref:{pages-path}/configure/kerberos.adoc[here]. +endif::[] | `auth.required` | Requires authentication for submitting an email to the SMTP server. @@ -192,7 +200,12 @@ Note that `authorizedAddresses` are considered authenticated. == Security +ifndef::no-kerberos[] James supports authentication with username / password (`PLAIN` and `LOGIN`), OIDC (`XOAUTH2` and `OAUTHBEARER`), and optional Kerberos (`GSSAPI`). +endif::[] +ifdef::no-kerberos[] +James supports authentication with username / password (`PLAIN` and `LOGIN`) and OIDC (`XOAUTH2` and `OAUTHBEARER`). +endif::[] SMTP authentication is essential to prevent sender address spoofing and open relays. For the concepts explained below, the distinction between local and external users is important. diff --git a/docs/modules/servers/partials/customization/mail-processing.adoc b/docs/modules/servers/partials/customization/mail-processing.adoc index ff1e4d92b4..f0260c7fe6 100644 --- a/docs/modules/servers/partials/customization/mail-processing.adoc +++ b/docs/modules/servers/partials/customization/mail-processing.adoc @@ -151,6 +151,13 @@ Then, we will write the *mailetcontainer.xml* file expressing the logic we want: </mailetcontainer> .... +ifndef::no-extensions-jars[] Finally, we will start a James server using that. We will rely on docker default image for simplicity. We need to be using the *mailetcontainer.xml* configuration that we had been writing and position the jar in the *extensions-jars* folder (specific to guice). +endif::[] +ifdef::no-extensions-jars[] +Finally, we will start a James server using that. We need to be using the *mailetcontainer.xml* configuration that +we had been writing, and to position the jar in the *conf/lib* folder, which the `bin/setenv.sh` script prepends to +the classpath of the {server-name}. +endif::[] diff --git a/docs/modules/servers/partials/operate/cli.adoc b/docs/modules/servers/partials/operate/cli.adoc index d37ece4780..12002136dc 100644 --- a/docs/modules/servers/partials/operate/cli.adoc +++ b/docs/modules/servers/partials/operate/cli.adoc @@ -1,3 +1,4 @@ +ifndef::no-jar-cli[] The {server-name} is packed with a command line client. To run this command line client simply execute: @@ -6,6 +7,7 @@ To run this command line client simply execute: java -jar /root/james-cli.jar -h 127.0.0.1 -p 9999 COMMAND .... +endif::[] The following document will explain you which are the available options for *COMMAND*. @@ -288,6 +290,7 @@ level. Note: syntax is similar to what was exposed previously. {cli} GetGlobalMaxStorageQuota .... +ifndef::no-droplist[] === Manage DropList The DropList, also known as the mail blacklist, is a collection of @@ -331,6 +334,7 @@ Testing a denied entity existence (should returns `allowed` or `blocked`) {cli} DropListQuery domain owner.com [email protected] .... +endif::[] == Re-indexing James allow you to index your emails in a search engine, for making @@ -348,7 +352,7 @@ To re-index all mails of all mailboxes of all users, type: And for a specific mailbox: .... -{cli} Reindex #private [email protected] INBOX +{cli} ReindexMailbox #private [email protected] INBOX .... == Sieve scripts quota diff --git a/docs/modules/servers/partials/operate/security.adoc b/docs/modules/servers/partials/operate/security.adoc index dcaf5d3404..17226b13cd 100644 --- a/docs/modules/servers/partials/operate/security.adoc +++ b/docs/modules/servers/partials/operate/security.adoc @@ -53,14 +53,26 @@ forced to store users in James be sure to choose `PBKDF2` as a hashing algorithm are supported via the `verifyFailureDelay` property. Note that IMAP / SMTP connections are closed after 3 authentication failures. +ifndef::no-webadmin[] - 5. Ensure that xref:{xref-base}/configure/webadmin.adoc[WebAdmin] is not exposed unencrypted to the outer world. Doing so trivially exposes yourself. You can either disable it, activate JWT security, or restrict it to listen only on localhost. +endif::[] +ifdef::no-webadmin[] + - 5. The only administrative interface of the {server-name} is JMX. Ensure it is not exposed to the outer world: keep +it bound to `localhost` and set up authentication, as documented in xref:{xref-base}/configure/jmx.adoc[jmx.properties]. +endif::[] ifndef::no-jmap[] - 6. Set up `HTTPS` for http based protocols, namely *JMAP* and *WebAdmin*. We recommend the use of a reverse proxy like Nginx. endif::[] ifdef::no-jmap[] +ifndef::no-webadmin[] - 6. Set up `HTTPS` for *WebAdmin*. We recommend the use of a reverse proxy like Nginx. +endif::[] +ifdef::no-webadmin[] + - 6. Terminate `SSL`/`TLS` for every protocol you expose - SMTP, IMAP, POP3 and ManageSieve - either directly within +James or behind a reverse proxy. See xref:{xref-base}/configure/ssl.adoc[SSL & TLS]. +endif::[] endif::[] - 7. Set up link:https://james.apache.org/howTo/spf.html[SPF] and link:https://james.apache.org/howTo/dkim.html[DKIM] @@ -85,12 +97,23 @@ using `auth.plainAuthEnabled=false`. - 2. Verify link:https://james.apache.org/howTo/spf.html[SPF] and xref:{xref-base}/configure/mailets.adoc#_dkimverify[DKIM] for your incoming emails. +ifndef::no-webadmin[] - 3. Set up reasonable xref:{xref-base}/operate/webadmin.adoc#_administrating_quotas[storage quota] for your users. +endif::[] +ifdef::no-webadmin[] + - 3. Set up reasonable xref:{xref-base}/operate/cli.adoc#_manage_quotas[storage quota] for your users. +endif::[] +ifndef::no-spam[] - 4. We recommend setting up anti-spam and anti-virus solutions. James comes with some xref:{xref-base}/configure/spam.adoc[Rspamd and SpamAssassin] integration, and some xref:{xref-base}/configure/mailets.adoc#_clamavscan[ClamAV] tooling exists. Rspamd supports anti-phishing modules. Filtering with third party systems upstream is also possible. +endif::[] +ifdef::no-spam[] + - 4. We recommend setting up anti-spam and anti-virus solutions. Filtering with third party systems upstream of the +{server-name} is the simplest option. +endif::[] - 5. In order to limit your attack surface, disable protocols you or your users do not use. This includes the JMAP protocol, POP3, ManagedSieve, etc... Be conservative on what you expose. diff --git a/docs/modules/servers/partials/spring/deprecated.adoc b/docs/modules/servers/partials/spring/deprecated.adoc new file mode 100644 index 0000000000..d0c21210f8 --- /dev/null +++ b/docs/modules/servers/partials/spring/deprecated.adoc @@ -0,0 +1,13 @@ +[WARNING.deprecation-banner-red] +==== +*The Spring James server is deprecated and should not be deployed anymore.* +It receives no new features, only a subset of the James components can be wired into it, and it is bound to the +legacy, fully blocking Spring stack. It ships neither JMAP nor the WebAdmin administration API: it can only be +administered through JMX. + +*Moving to the xref:jpa/index.adoc[JPA James server] is strongly advised, and requires no data migration*: both +applications persist their data with the very same JPA entities, in the same relational database. Point the JPA +application at the database and the `var` folder your Spring instance was using, and your domains, users, +rewriting rules, mailboxes and emails are there. Read xref:spring/index.adoc#_moving_to_the_jpa_james_server[the +migration section] for the few details that need attention. +==== diff --git a/docs/ui-overrides/partials/head-styles.hbs b/docs/ui-overrides/partials/head-styles.hbs index 33c8d0f06e..98b1539aaa 100644 --- a/docs/ui-overrides/partials/head-styles.hbs +++ b/docs/ui-overrides/partials/head-styles.hbs @@ -1,7 +1,8 @@ <link rel="stylesheet" href="{{{uiRootPath}}}/css/site.css"> <style> /* Yellow banner used to flag deprecated applications, see the `deprecation-banner` role. */ - .doc .admonitionblock.deprecation-banner { + .doc .admonitionblock.deprecation-banner, + .doc .admonitionblock.deprecation-banner-red { margin: 0 0 1.5rem; } .doc .admonitionblock.deprecation-banner td.content { @@ -13,4 +14,18 @@ background-color: #f0b429; color: #4a3b00; } + /* Red banner used to flag applications that should no longer be deployed at all, + see the `deprecation-banner-red` role. */ + .doc .admonitionblock.deprecation-banner-red td.content { + background: #ffeeee; + border-left: 4px solid #cf1124; + color: #610316; + } + .doc .admonitionblock.deprecation-banner-red td.content a { + color: #ab091e; + } + .doc .admonitionblock.deprecation-banner-red td.icon i.icon-warning { + background-color: #cf1124; + color: #fff; + } </style> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
