summaryrefslogtreecommitdiffstats
path: root/proto/MULTI_INSTANCE_README.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 12:06:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 12:06:34 +0000
commit5e61585d76ae77fd5e9e96ebabb57afa4d74880d (patch)
tree2b467823aaeebc7ef8bc9e3cabe8074eaef1666d /proto/MULTI_INSTANCE_README.html
parentInitial commit. (diff)
downloadpostfix-5e61585d76ae77fd5e9e96ebabb57afa4d74880d.tar.xz
postfix-5e61585d76ae77fd5e9e96ebabb57afa4d74880d.zip
Adding upstream version 3.5.24.upstream/3.5.24upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'proto/MULTI_INSTANCE_README.html')
-rw-r--r--proto/MULTI_INSTANCE_README.html1274
1 files changed, 1274 insertions, 0 deletions
diff --git a/proto/MULTI_INSTANCE_README.html b/proto/MULTI_INSTANCE_README.html
new file mode 100644
index 0000000..a2574df
--- /dev/null
+++ b/proto/MULTI_INSTANCE_README.html
@@ -0,0 +1,1274 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Managing multiple Postfix instances on a single host</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Managing
+multiple Postfix instances on a single host</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+<p> This document is a guide to managing multiple Postfix instances
+on a single host using the postmulti(1) instance manager. Multi-instance
+support is available with Postfix version 2.6 and later. See the
+postfix-wrapper(5) manual page for background on the instance
+management framework, and on how to deploy a custom instance manager.
+</p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#why"> Why multiple Postfix instances </a>
+
+<li><a href="#split"> Null-client instances versus service instances </a>
+
+<li><a href="#quick"> Multi-instance walk-through </a>
+
+<li><a href="#parts"> Components of a Postfix system </a>
+
+<li><a href="#default"> The default Postfix instance </a>
+
+<li><a href="#group"> Instance groups </a>
+
+<li><a href="#params"> Multi-instance configuration parameters </a>
+
+<li><a href="#how"> Using the postmulti(1) command </a>
+
+<li><a href="#credits"> Credits </a>
+
+</ul>
+
+<h2><a name="why"> Why multiple Postfix instances </a></h2>
+
+<p> Postfix is a general-purpose mail system that can be configured
+to serve a variety of needs. Examples of Postfix applications are: </p>
+
+<ul>
+
+<li><p> Local mail submission for shell users and system processes. </p>
+
+<li><p> Incoming (MX host) email from the Internet. </p>
+
+<li><p> Outbound mail relay for a corporate network. </p>
+
+<li><p> Authenticated submission for roaming users. </p>
+
+<li><p> Before/after content-filter mail. </p>
+
+</ul>
+
+<p> A single Postfix configuration can provide many or all of these
+services, but a complex interplay of settings may be required, for
+example with master.cf options overriding main.cf settings. In this
+document we take the view that multiple Postfix instances may be a
+simpler way to configure a multi-function Postfix system. With
+multiple Postfix instances, each instance has its own directories
+for configuration, queue and data files, but it shares all Postfix
+program and documentation files with other instances. </p>
+
+<p> Since there is no single right way to configure your system,
+we recommend that you choose what makes you most comfortable. If
+different Postfix services don't involve incompatible main.cf or
+master.cf settings, and if they can be combined together without
+complex tricks, then a single monolithic configuration may be the
+simplest approach. </p>
+
+<p> The purpose of multi-instance support in Postfix is not to force
+you to create multiple Postfix instances, but rather to give you a
+choice. Multiple instances give you the freedom to tune each Postfix
+instance to a single task that it does well and to combine instances
+into complete systems. </p>
+
+<p> With the introduction of the postmulti(1) utility and the reduction
+of the per-instance configuration footprint of a secondary Postfix
+instance to just a main.cf and master.cf file (other files are now in
+shared locations), we hope that multiple instances will be easier to
+use than ever before. </p>
+
+<h2><a name="split"> Null-client instances versus service instances </a></h2>
+
+<p> In the multi-instance approach to configuring Postfix, the first
+simplification is with the default local-submission Postfix instance.
+</p>
+
+<p> Most UNIX systems require support for email submission with the
+sendmail(1) command so that system processes such as cron jobs can
+send status reports, and so that system users can send email with
+command-line utilities. Such email can be handled with a <a
+href="STANDARD_CONFIGURATION_README.html#null_client">null-client</a>
+Postfix configuration that forwards all mail to a central mail hub.
+The null client will typically either not run an SMTP listener at
+all (master_service_disable = inet), or it will listen only on the
+loopback interface (inet_interfaces = loopback-only). </p>
+
+<p> When implementing specialized servers for inbound Internet
+email, outbound MTAs, internal mail hubs, and so on, we recommend
+using a null client for local submission and creating single-function
+secondary Postfix instances to serve the specialized needs. </p>
+
+<blockquote>
+
+<p> Note: usually, you need to use different "myhostname" settings
+when you run multiple instances on the same host. Otherwise, there
+will be false "mail loops back to myself" alarms when one instance
+tries to send mail into another instance. Typically, the null-client
+instance will use the system's hostname, and other instances will
+use their own dedicated "myhostname" settings. Different names are
+not needed when instances send mail to each other with a protocol
+other than SMTP, or with SMTP over a TCP port other than 25 as is
+usual with SMTP-based content filters. </p>
+
+</blockquote>
+
+<h2><a name="quick"> Multi-instance walk-through </a></h2>
+
+<p> Before discussing the fine details of multi-instance operation
+we first show the steps for creating a border mail server. This
+server has with a null-client Postfix instance for local submission,
+an input Postfix instance to receive mail from the Internet, plus
+an <a href="FILTER_README.html#advanced_filter">advanced</a> SMTP
+content-filter and an output Postfix instance to deliver filtered
+email to its internal destination. </p>
+
+<h3>Setting up the null-client Postfix instance </h3>
+
+<p> On a border mail hub, while mail from the Internet requires a
+great deal of scrutiny, locally submitted messages are typically
+limited to mail from cron jobs and other system services. In this
+regard the border MTA is not different from other Unix hosts in
+your environment. For this reason, it will submit locally-generated
+email to the internal mail hub. We start the construction of the
+border mail server with the <a href="#default_instance">default</a>
+instance, which will be a local-submission <a
+href="STANDARD_CONFIGURATION_README.html#null_client">null client</a>:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # We are mta1.example.com
+ #
+ myhostname = mta1.example.com
+ mydomain = example.com
+
+ # Flat user-account namespace in example.com:
+ #
+ # user@example.com not user@host.example.com
+ #
+ myorigin = $mydomain
+
+ # Postfix 2.6+, disable inet services, specifically disable smtpd(8)
+ #
+ master_service_disable = inet
+
+ # No local delivery:
+ #
+ mydestination =
+ local_transport = error:5.1.1 Mailbox unavailable
+ alias_database =
+ alias_maps =
+ local_recipient_maps =
+
+ # Send everything to the internal mailhub
+ #
+ relayhost = [mailhub.example.com]
+
+ # Indexed table macro:
+ # (use "hash", ... when <a href="CDB_README.html">cdb</a> is not available)
+ #
+ default_database_type = cdb
+ indexed = ${default_database_type}:${config_directory}/
+
+ # Expose origin host of mail from "root", ...
+ #
+ smtp_generic_maps = ${indexed}generic
+
+ # Send messages addressed to "root", ... to the MTA support team
+ #
+ virtual_alias_maps = ${indexed}virtual
+
+/etc/postfix/generic:
+ # The smarthost supports "+" addressing (recipient_delimiter = +).
+ # Mail from "root" exposes the origin host, without replies
+ # and bounces going back to the same host.
+ #
+ # On clustered MTAs this file is typically machine-built from
+ # a template file. The build process expands the template into
+ # "mtaadmin+root=mta1"
+ #
+ root mtaadmin+root=mta1
+
+/etc/postfix/virtual:
+ # Caretaker aliases:
+ #
+ root mtaadmin
+ postmaster root
+</pre>
+</blockquote>
+
+<p> You would typically also add a Makefile, to automatically run
+postmap(1) commands when source files change. This Makefile also
+creates a "generic" database when none exists. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/Makefile:
+ MTAADMIN=mtaadmin
+
+ all: virtual.cdb generic.cdb
+
+ generic: Makefile
+ @echo Creating $@
+ @rm -f $@.tmp
+ @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` &gt; $@.tmp
+ @mv $@.tmp generic
+
+ %.cdb: %
+ postmap cdb:$&lt;
+</pre>
+</blockquote>
+
+<p> Construct the "virtual" and "generic" databases (the latter is
+created by running "make"), then start and test the null-client:
+</p>
+
+<blockquote>
+<pre>
+# cd /etc/postfix; make
+# postfix start
+# sendmail -i -f root -t &lt;&lt;EOF
+From: root
+To: root
+Subject: test
+
+testing
+EOF
+</pre>
+</blockquote>
+
+<p> The test message should be delivered the members of the "mtaadmin"
+address group (or whatever address group you choose) with the
+following headers: </p>
+
+<blockquote>
+<pre>
+From: mtaadmin+root=mta1@example.com
+To: mtadmin+root=mta1@example.com
+Subject: test
+</pre>
+</blockquote>
+
+<h3>Setting up the "output" Postfix instance </h3>
+
+<p> With the null-client instance out of the way, we can create the
+MTA "output" instance that will deliver filtered mail to the inside
+network. We add the "output" instance first, because the output
+instance needs to be up and running before the input instance can
+be fully tested, and when the system boots, the "output" instance
+must start before the input instance. We will put the output and
+input instances into a single instance group named "mta". </p>
+
+<p> Just once, when adding the first secondary instance, enable
+multi-instance support in the default (null-client) instance: </p>
+
+<blockquote>
+<pre>
+# postmulti -e init
+</pre>
+</blockquote>
+
+<p> Then create the output instance: <p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-out -G mta -e create
+</pre>
+</blockquote>
+
+<p> The instance configuration directory defaults to /etc/postfix-out,
+more precisely, the "postfix-out" subdirectory of the parent directory
+of the default-instance configuration directory. The new instance will
+be created in a "disabled" state: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-out/main.cf
+ #
+ # ... "stock" main.cf settings ...
+ #
+ multi_instance_name = postfix-out
+ queue_directory = /var/spool/postfix-out
+ data_directory = /var/lib/postfix-out
+ #
+ multi_instance_enable = no
+ master_service_disable = inet
+ authorized_submit_users =
+</pre>
+</blockquote>
+
+<p> This instance has a "stock" master.cf file, and its queue and
+data directories, also named "postfix-out", will be located in the
+same parent directories as the corresponding directories of the
+default instance (e.g., /var/spool/postfix-out and /var/lib/postfix-out).
+</p>
+
+<p> While this instance is immediately safe to start, it is not yet
+usefully configured. It needs to be customized to fit the role of a
+post-filter re-injection SMTP service. Typical additions include: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-out/master.cf:
+ # Replace default "smtp inet" entry with one listening on port 10026.
+ 127.0.0.1:10026 inet n - n - - smtpd
+
+/etc/postfix-out/main.cf
+ # ...
+
+ # Comment out if you don't use IPv6 internally
+ # inet_protocols = ipv4
+ inet_interfaces = loopback-only
+ mynetworks_style = host
+ smtpd_authorized_xforward_hosts = $mynetworks
+
+ # Don't anvil(8) control the re-injection port.
+ #
+ smtpd_client_connection_count_limit = 0
+ smtpd_client_event_limit_exceptions = $mynetworks
+
+ # Best practice when inet_interfaces is set, as this is not a
+ # "secondary IP personality" configuration.
+ #
+ smtp_bind_address = 0.0.0.0
+
+ # All header rewriting happens upstream
+ #
+ local_header_rewrite_clients =
+
+ # No local delivery on border gateway
+ #
+ mydestination =
+ alias_maps =
+ alias_database =
+ local_recipient_maps =
+ local_transport = error:5.1.1 Mailbox unavailable
+
+ # May need a recipient_delimiter for per-user transport lookups:
+ #
+ recipient_delimiter = +
+
+ # Only one (unrestricted client)
+ # With multiple instances, rarely need "-o param=value" overrides
+ # in master.cf, each instance gets its own main.cf file.
+ #
+ # Postfix 2.10 and later: specify empty smtpd_relay_restrictions.
+ smtpd_relay_restrictions =
+ smtpd_recipient_restrictions = permit_mynetworks, reject
+
+ # Tolerate occasional high latency in the content filter.
+ #
+ smtpd_timeout = 1200s
+
+ # Best when empty, with all parent domain matches explicit.
+ #
+ parent_domain_matches_subdomains =
+
+ # Use the "relay" transport for inbound mail, and the default
+ # "smtp" transport for outbound mail (bounces, ...). The latter
+ # won't starve the former of delivery agent slots.
+ #
+ relay_domains = example.com, .example.com
+
+ # With xforward, match the input instance setting, if you
+ # want "yes", set both to "yes".
+ #
+ smtpd_client_port_logging = no
+
+ # Transport settings ...
+ # Message size limit
+ # Concurrency tuning for "relay" and "smtp" transport
+ # ...
+</pre>
+</blockquote>
+
+<p> With the "output" configuration in place, enable and start the
+instance: </p>
+
+<blockquote>
+<pre>
+1 # postmulti -i postfix-out -x postconf -e \
+2 "master_service_disable =" "authorized_submit_users = root"
+3 # postmulti -i postfix-out -e enable
+4 # postmulti -i postfix-out -p start
+</pre>
+</blockquote>
+
+<p> This uses the postmulti(1) command to invoke postconf(1) in the
+context (MAIL_CONFIG=/etc/postfix-out) of the output instance. </p>
+
+<ul>
+
+<li> <p> Lines 1-2: With "authorized_submit_users = root", the
+superuser can test the postfix-out instance with "postmulti -i
+postfix-out -x sendmail -bv recipient...", but otherwise local
+submission remains disabled. </p>
+
+<li> <p> Lines 1-2: With "master_service_disable =", the "inet"
+listeners are re-enabled. </p>
+
+<li> <p> Line 3: The output instance is enabled for multi-instance
+start/stop. </p>
+
+<li> <p> Line 4: The output instance is started. </p>
+
+</ul>
+
+<p> Test the output instance by submitting probe messages via "sendmail
+-bv" and "telnet". For production systems, in-depth configuration tests
+should be done on a lab system. The simple tests just suggested will only
+confirm successful deployment of a configuration that should already be
+known good. </p>
+
+<h3> Setting up the content-filter proxy </h3>
+
+<p> With the output instance ready, deploy your content-filter
+proxy. Most proxies will need their own /etc/rc* start/stop script.
+Some proxies, however, are started on demand by the Postfix spawn(8)
+service, in which case you need to add the relevant spawn(8) entry
+to the output instance master.cf file. </p>
+
+<p> Configure the proxy to listen on 127.0.0.1:10025 and to re-inject
+filtered email to 127.0.0.1:10026. Start the proxy service if
+necessary, then test the proxy via "telnet" or automated SMTP
+injectors. The proxy should support the following ESMTP features:
+DSN, 8BITMIME, and XFORWARD. In addition, the proxy should support
+multiple mail deliveries within an SMTP session. </p>
+
+<h3> Setting up the input Postfix instance </h3>
+
+<p> The input Postfix instance receives mail from the network and
+sends it through the content filter. Now we create the input instance,
+also part of the "mta" instance group: </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-in -G mta -e create
+</pre>
+</blockquote>
+
+<p> The new instance configuration directory defaults to /etc/postfix-in,
+more precisely, the "postfix-in" subdirectory of the parent directory
+of the default-instance configuration directory. The new instance will
+be created in a "disabled" state: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-in/main.cf
+ #
+ # ... "stock" main.cf settings ...
+ #
+ multi_instance_name = postfix-in
+ queue_directory = /var/spool/postfix-in
+ data_directory = /var/lib/postfix-in
+ #
+ multi_instance_enable = no
+ master_service_disable = inet
+ authorized_submit_users =
+</pre>
+</blockquote>
+
+<p> As before, make appropriate changes to main.cf and master.cf to
+make the instance production ready. Consider setting "soft_bounce = yes"
+during the first few hours of deployment, so you can iron-out any unexpected
+"kinks". </p>
+
+<p> Manual testing can start with:
+
+<blockquote>
+<pre>
+/etc/postfix-in/main.cf
+ # Accept only local traffic, but allow impersonation:
+ inet_interfaces = 127.0.0.1
+ smtpd_authorized_xclient_hosts = 127.0.0.1
+</pre>
+</blockquote>
+
+<p> This allows you to use the Postfix-specific <a
+href="XCLIENT_README.html">XCLIENT</a> SMTP command to safely
+simulate connections from remote systems before any remote systems
+are able to connect. If the test results look good, revert the above
+settings to the required production values. Typical settings in the
+pre-filter input instance include: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-in/main.cf
+ #
+ # ...
+ #
+
+ # No local delivery on border gateway
+ #
+ mydestination =
+ alias_maps =
+ alias_database =
+ local_recipient_maps =
+ local_transport = error:5.1.1 Mailbox unavailable
+
+ # Don't rewrite remote headers
+ #
+ local_header_rewrite_clients =
+
+ # All recipients of not yet filtered email go to the same filter together.
+ #
+ # With multiple instances, the content-filter is specified
+ # via transport settings not the "content_filter" transport
+ # switch override! Here the filter listens on local port 10025.
+ #
+ # If you need to route some users or recipient domains directly to the
+ # output instance bypassing the filter, just define a transport table
+ # with suitable entries.
+ #
+ default_transport = smtp:[127.0.0.1]:10025
+ relay_transport = $default_transport
+ virtual_transport = $default_transport
+ transport_maps =
+
+ # Pass original client log information through the filter.
+ #
+ smtp_send_xforward_command = yes
+
+ # Avoid splitting the envelope and scanning messages multiple times.
+ # Match the re-injection server's recipient limit.
+ #
+ smtp_destination_recipient_limit = 1000
+
+ # Tolerate occasional high latency in the content filter.
+ #
+ smtp_data_done_timeout = 1200s
+
+ # With xforward, match the output instance setting, if you
+ # want "yes", set both to "yes".
+ #
+ smtpd_client_port_logging = no
+
+ # ... Lots of settings for inbound MX host ...
+</pre>
+</blockquote>
+
+<p> With the "input" instance configured, enable and start it: </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-in -x postconf -e \
+ "master_service_disable =" "authorized_submit_users = root"
+# postmulti -i postfix-in -e enable
+# postmulti -i postfix-in -p start
+</pre>
+</blockquote>
+
+<p> That's it. You now have a 3-instance configuration. A null-client
+sending all locally submitted mail to the internal mail hub and a pair of
+"mta" instances that receive mail from the Internet, pass it through a
+content-filter, and then deliver it to the internal destination. </p>
+
+<p> Running "postfix start" or "postfix stop" will now start/stop all
+three Postfix instances. You can use "postfix -c /config/path start"
+to start just one instance, or use the instance name (or instance
+group name) via postmulti(1): </p>
+
+<blockquote>
+<pre>
+# postmulti -i - -p stop
+# postmulti -g mta -p status
+# postmulti -i postfix-out -p flush
+# postmulti -i postfix-in -p reload
+# ...
+</pre>
+</blockquote>
+
+<p> This example ends the multi-instance "walk through". The remainder
+of this document provides background information on Postfix
+multi-instance support features and options. </p>
+
+<h2><a name="parts"> Components of a Postfix system </a></h2>
+
+<p> A Postfix system consists of the following components: </p>
+
+<p> Shared among all instances: </p>
+
+<ul>
+
+<li><p> Command-line utilities for administrators and users installed in
+$command_directory, $sendmail_path, $mailq_path and $newaliases_path. </p>
+
+<li><p> Daemon executables, and run-time support files installed in
+$daemon_directory. </p>
+
+<li><p> Bundled documentation, installed in $html_directory,
+$manpage_directory and $readme_directory. </p>
+
+<li><p> Entries in /etc/passwd and /etc/group for the $mail_owner user and
+$setgid_group group. The $mail_owner user provides the mail system
+with a protected (non-root) execution context. The $setgid_group group
+is used exclusively to support the setgid postdrop(1) and postqueue(1)
+utilities (it <b>must not</b> be the primary group or secondary group
+of any users, including the $mail_owner user). </p>
+
+</ul>
+
+<p> Private to each instance: </p>
+
+<ul>
+
+<li><p> The main.cf, master.cf (and other optional) configuration
+files in $config_directory. </p>
+
+<li> <p> The maildrop, incoming, active, deferred and hold queues
+in $queue_directory (which contains additional directories needed
+by Postfix, and which optionally doubles as a chroot jail for Postfix
+daemon processes). </p>
+
+<li> <p> Various caches (TLS session, address verification, ...)
+in $data_directory. </p>
+
+</ul>
+
+<p> The Postfix configuration parameters mentioned above are
+collectively referred to as "installation parameters". Their default
+values are set when the Postfix software is built from source, and
+all but one may be optionally set to a non-default value via the
+main.cf file. The one parameter that (catch-22) cannot be set in
+main.cf is $config_directory, as this defines the location of the
+main.cf file itself. </p>
+
+<p> Though config_directory cannot be set in main.cf, postfix(1) and
+most of the other command-line Postfix utilities allow you to specify a
+non-default configuration directory via a command line option (typically
+<b>-c</b>) or via the MAIL_CONFIG environment variable. In this way,
+it is possible to have multiple configuration directories on the same
+machine, and to have multiple running master(8) daemons each with its
+own configuration files, queue directory and data directory. </p>
+
+<p> These multiple running copies of master(8) share the base Postfix
+software. They do not (and cannot) share their configuration
+directories, queue directories or data directories. </p>
+
+<p> Each combination of configuration directory, together with the queue
+directory and data directory (specified in the corresponding main.cf file)
+make up a Postfix <b>instance</b>. </p>
+
+<h2><a name="default"> The default Postfix instance </a></h2>
+
+<p> One Postfix instance is special: this is the instance whose
+configuration directory is the default one compiled into the Postfix
+utilities. The location of the default configuration directory is
+typically /etc/postfix, and can be queried via the "postconf -d
+config_directory" command. We call the instance with this configuration
+directory the "default instance". </p>
+
+<p> The default instance is responsible for local mail submission. The
+setgid postdrop(1) utility is used by the sendmail(1) local submission
+program to spool messages into the <b>maildrop</b> sub-directory of the
+queue directory of the default instance. </p>
+
+<p> Even in the rare case when "sendmail -C" is used to submit local mail
+into a non-default Postfix instance, for security reasons, postdrop(1)
+will consult the default main.cf file to check the validity of the
+requested non-default configuration directory. </p>
+
+<p> So, while in most other respects, all instances are equal, the
+default instance is "more equal than others". You may choose to create
+additional instances, but you must have at least the default instance,
+with its configuration directory in the default compiled-in location. </p>
+
+<h2><a name="group"> Instance groups </a></h2>
+
+<p> The postmulti(1) multi-instance manager supports the notion of an
+instance "group". Typically, the member instances of an instance group
+constitute a logical service, and are expected to all be running or all
+be stopped. </p>
+
+<p> In many cases a single Postfix instance will be a complete logical
+"service". You should define such instances as stand-alone instances
+that are not members of any instance "group". The null-client
+instance is an example of a non-group instance. </p>
+
+<p> When a logical service consists of multiple Postfix instances,
+often a pair of pre-filter and post-filter instances with a content
+filter proxy between them, the related instances should be members
+of a single instance group (however, the content filter usually has
+its own start/stop procedure that is separate from any Postfix
+instance). </p>
+
+<p> The default instance main.cf file's $multi_instance_directories
+configuration parameter lists the configuration directories of all
+secondary (non-default) instances. Together with the default instance,
+these secondary instances are managed by the multi-instance manager.
+Instances are started in the order listed, and stopped in the
+opposite order. For instances that are members of a service "group",
+you should arrange to start the service back-to-front, with the
+output stages started and ready to receive mail before the input
+stages are started. </p>
+
+<h2><a name="params"> Multi-instance configuration parameters </a></h2>
+
+<dl>
+
+<dt> multi_instance_wrapper </dt>
+
+<dd> <p> This default-instance configuration parameter must be set
+to a suitable multi-instance manager's "wrapper" program that
+controls the starting, stopping, etc. of a multi-instance Postfix
+system. To use the postmulti(1) manager described in this document,
+this parameter should be set with the "<a href="#init">postmulti
+-e init</a>" command. </p> </dd>
+
+<dt> multi_instance_directories </dt>
+
+<dd> <p> This default-instance configuration parameter specifies
+an optional list of the secondary instances controlled via the
+multi-instance manager. Instances are listed in their "start" order,
+with the default instance always started first (if enabled). If
+$multi_instance_directories is left empty, the postfix(1) command
+runs with multi-instance support turned off, and none of the
+multi_instance_ configuration parameters will have any effect. </p>
+
+<p> Do not assign a non-empty list of secondary instance configuration
+directories to multi_instance_directories until you have configured a
+suitable multi_instance_wrapper setting! This is best accomplished via
+the "<a href="#init">postmulti -e init</a>" command.
+</p> </dd>
+
+<dt> multi_instance_name </dt>
+
+<dd> <p> Each Postfix instance may be assigned a distinct name (with
+"postfix -e create/import/assign -I <i>name</i>..."). This name can
+be used with the postmulti(1) command-line utility to perform tasks
+on the instance by name (rather than the full pathname of its
+configuration directory). Choose a name that concisely captures the
+role of the instance (it must start with "postfix-"). It is an
+error for two instances to have the same $multi_instance_name. You
+can leave an instance "nameless" by leaving this parameter at the
+default empty setting. </p>
+
+<p> To avoid confusion in your logs, if you don't assign each
+secondary instance a non-empty (distinct) $multi_instance_name, you
+should make sure that the $syslog_name setting is different for
+each instance. The $syslog_name parameter defaults to $multi_instance_name
+when the latter is non-empty. If at all possible, the syslog_name
+should start with "postfix-", this helps log parsers to identify
+log entries from secondary Postfix instances. </p> </dd>
+
+<dt> multi_instance_group </dt>
+
+<dd> <p> Each Postfix instance may be assigned an "instance group"
+name (with "postfix -e create/import/assign -G <i>name</i>...").
+The default (empty) value of multi_instance_group parameter indicates
+a stand-alone instance that is not part of any group. The group
+name can be used with the postmulti(1) command-line utility to
+perform a task on the members of a group by name. Choose a single-word
+group name that concisely captures the role of the group. </p>
+</dd>
+
+<dt> multi_instance_enable </dt>
+
+<dd> <p> This parameter controls whether a Postfix instance will
+be started by a Postfix multi-instance manager. The default value
+is "no". The instance can be started explicitly with "postfix -c
+/path/to/config/directory"; this is useful for testing. </p>
+
+<p> When an instance is disabled, the postfix(1) "start" command
+is replaced by "check". </p>
+
+<p> Some postfix(1) commands (such as "stop", "flush", ...) require
+a running Postfix instance, and skip instances that are disabled.
+</p>
+
+<p> Other postfix(1) commands (such as "status", "set-permissions",
+"upgrade-configuration", ...) do not require a running Postfix
+system, and apply to all instances whether enabled or not. </p>
+</dd>
+
+</dl>
+
+<p> The postmulti(1) utility can be used to create (or destroy) instances.
+It can also be used to "import" or "deport" existing instances into or
+from the list of managed instances. When using postmulti(1) to manage
+instances, the above configuration parameters are managed for you
+automatically. See below. </p>
+
+<h2><a name="how"> Using the postmulti(1) command </a></h2>
+
+<ul>
+
+<li><a href="#init"> Initializing the multi-instance manager </a>
+
+<li><a href="#list"> Listing managed instances </a>
+
+<li><a href="#start"> Starting or stopping a multi-instance system </a>
+
+<li><a href="#adhoc"> Ad-hoc multi-instance operations </a>
+
+<li><a href="#create"> Creating a new Postfix instance </a>
+
+<li><a href="#destroy"> Destroying a Postfix instance </a>
+
+<li><a href="#import"> Importing an existing Postfix instance </a>
+
+<li><a href="#deport"> Deporting a managed Postfix instance </a>
+
+<li><a href="#assign"> Assigning a new name or group name </a>
+
+<li><a href="#enable"> Enabling/disabling managed instances </a>
+
+</ul>
+
+<h3><a name="init"> Initializing the multi-instance manager </a></h3>
+
+<p> Before postmulti(1) is used for the first time, you must install
+it as the multi_instance_wrapper for your Postfix system and enable
+multi-instance operation of the default Postfix instance. You can then
+proceed to add <a href="#create">new</a> or <a href="#import">existing</a>
+instances to the multi-instance configuration. This initial installation
+is accomplished as follows: </p>
+
+<blockquote>
+<pre>
+ # postmulti -e init
+</pre>
+</blockquote>
+
+<p> This updates the default instance main.cf file as follows: </p>
+
+<blockquote>
+<pre>
+ # Use postmulti(1) as a postfix-wrapper(5)
+ #
+ multi_instance_wrapper = ${command_directory}/postmulti -p --
+
+ # Configure the default instance to start when in multi-instance mode
+ #
+ multi_instance_enable = yes
+</pre>
+</blockquote>
+
+<p> If you prefer, you can make these changes by editing the default
+main.cf directly, or by using "postconf -e". </p>
+
+<h3><a name="list"> Listing managed instances </a></h3>
+
+<p> The list of managed instances consists of the default instance and
+the additional instances whose configuration directories are listed
+(in start order) under the multi_instance_directories parameter of the
+default main.cf configuration file. </p>
+
+<p> You can list selected instances, groups of instances or all
+instances by specifying only the instance matching options with the
+"-l" option. The "-a" option is assumed if no other instance
+selection options are specified (this behavior changes with the
+"-e" option). As a special case, even if it has an explicit name,
+the default instance can always be selected via "-i -". </p>
+
+<blockquote>
+<pre>
+# postmulti -l -a
+# postmulti -l -g a_group
+# postmulti -l -i an_instance
+</pre>
+</blockquote>
+
+<p> The output is one line per instance (in "postfix start" order):
+</p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th align="left">name</th> <th align="left">group</th> <th
+align="left">enabled</th> <th align="left">config_directory</th>
+</tr>
+
+<tr> <td>-</td> <td>-</td> <td>yes</td> <td>/etc/postfix
+
+<tr> <td>mta-out</td> <td>mta</td> <td>yes</td> <td>/etc/postfix/mta-out
+
+<tr> <td>mta-in</td> <td>mta</td> <td>yes</td> <td>/etc/postfix-mta-in
+
+<tr> <td>msa-out</td> <td>msa</td> <td>yes</td> <td>/etc/postfix-msa-out
+
+<tr> <td>msa-in</td> <td>msa</td> <td>yes</td> <td>/etc/postfix-msa-in
+
+<tr> <td>test</td> <td>-</td> <td>no</td> <td>/etc/postfix-test
+
+</table>
+
+</blockquote>
+
+<p> The first line showing the column headings is not part of the
+output. When either the instance name or the instance group is not
+set, it is shown as a "-". </p>
+
+<p> When selecting an existing instance via the "-i" option, you
+can always use the full pathname of its configuration directory
+instead of the instance (short) name. This is the only way to select
+a non-default nameless instance. The default instance can be selected
+via "-i -", whether it has a name or not. </p>
+
+<p> To list instances in reverse start order, include the "-R"
+option together with the instance selection options. </p>
+
+<h3><a name="start"> Starting or stopping a multi-instance system
+</a></h3>
+
+<p> To start, stop, reload, etc. the complete (already configured as
+above) multi-instance system just use postfix(1) as you would with a
+single-instance system. The Postfix multi-instance wrapper framework
+insulates Postfix init.d start and package upgrade scripts from the
+details of multi-instance management! </p>
+
+<p> The <b>-p</b> option of postmulti(1) turns on postfix(1) compatibility
+mode. With this option the remaining arguments are exactly those supported
+by postfix(1), but commands are applied to all instances or all enabled
+instances as appropriate. As described above, this switch is required
+when using postmulti(1) as the multi_instance_wrapper. </p>
+
+<p> If you want to specify a subset of instances by name, or group name,
+or run arbitrary commands (not just "postfix stop/start/etc. in the
+context (MAIL_CONFIG environment variable setting) of a particular
+instance or group of instances, then you can use the instance-aware
+postmulti(1) utility directly. </p>
+
+<h3><a name="adhoc"> Ad-hoc multi-instance operations </a></h3>
+
+<p> The postmulti(1) command can be used by the administrator to run arbitrary
+commands in the context of one or more Postfix instances. The most common
+use-case is stopping or starting a group of Postfix instances: </p>
+
+<blockquote>
+<pre>
+# postmulti -g mygroup -p start
+# postmulti -g mygroup -p flush
+# postmulti -g mygroup -p reload
+# postmulti -g mygroup -p status
+# postmulti -g mygroup -p stop
+# postmulti -g mygroup -p upgrade-configuration
+</pre>
+</blockquote>
+
+<p> The <b>-p</b> option is essentially a short-hand for a leading
+<b>postfix</b> command argument, but with appropriate additional options
+turned on depending on the first argument. In the case of "start",
+disabled instances are "checked" (postfix check) rather than simply
+skipped. </p>
+
+<p> The resulting command is executed for each candidate instance with
+the <b>MAIL_CONFIG</b> environment variable set to the configuration
+directory of the corresponding Postfix instance. </p>
+
+<p> The postmulti(1) utility is able to launch commands other than
+postfix(1), Use the <b>-x</b> option to ask postmulti to execute an
+ad-hoc command for all instances, a group of instances, or just one
+instance. With ad-hoc commands the multi_instance_enable parameter
+is ignored: the command is unconditionally executed for the instances
+selected via -a, -g or -i. In addition to MAIL_CONFIG, the following
+instance parameters are exported into the command environment: </p>
+
+<blockquote>
+<pre>
+command_directory=$command_directory
+daemon_directory=$daemon_directory
+config_directory=$config_directory
+queue_directory=$queue_directory
+data_directory=$data_directory
+multi_instance_name=$multi_instance_name
+multi_instance_group=$multi_instance_group
+multi_instance_enable=$multi_instance_enable
+</pre>
+</blockquote>
+
+<p> The config_directory setting is of course the same as MAIL_CONFIG,
+and is arguably redundant, but leaving it in is less surprising. If
+you want to skip disabled instances, just check multi_instance_enable
+environment variable and exit if it is set to "no". </p>
+
+<p> The ability to run ad-hoc commands opens up a wealth of additional
+possibilities: </p>
+
+<ul>
+
+<li><p> Specify an instance by name rather than configuration directory
+when using sendmail(1) to send a verification probe: </p>
+
+<blockquote>
+<pre>
+$ postmulti -i postfix-myinst -x sendmail -bv test@example.net
+</pre>
+</blockquote>
+
+<li><p> Display non-default main.cf settings of all Postfix instances.
+This uses an inline shell script to package together multiple shell
+commands to execute for each instance: </p>
+
+<blockquote>
+<pre>
+$ postmulti -x sh -c 'echo "-- $MAIL_CONFIG"; postconf -n'
+</pre>
+</blockquote>
+
+<li><p> Put all mail in enabled member instances of a group on hold: </p>
+
+<blockquote>
+<pre>
+# postmulti -g group_name -x \
+ sh -c 'test $multi_instance_enable = yes &amp;&amp; postsuper -h ALL'
+</pre>
+</blockquote>
+
+<li><p> Show top 10 domains in the deferred queue of all instances:
+</p>
+
+<blockquote>
+<pre>
+# postmulti -x sh -c 'echo "-- $MAIL_CONFIG"; qshape deferred | head -12'
+</pre>
+</blockquote>
+
+</ul>
+
+<h3><a name="create"> Creating a new Postfix instance </a></h3>
+
+<p> The postmulti(1) command can be used to create additional Postfix
+instances. New instances are created with local submission and all "inet"
+services disabled via the following non-default parameter settings in
+the main.cf file: </p>
+
+<blockquote>
+<pre>
+authorized_submit_users =
+master_service_disable = inet
+</pre>
+</blockquote>
+
+<p> The above settings ensure that new instances are safe to start
+immediately: they will not conflict with inet listeners in existing
+Postfix instances. They will also not accept any mail until they are
+fully configured, at which point you can do away with one or both of
+the above safety measures. </p>
+
+<p> The postmulti(1) command encourages a preferred way of organizing
+the configuration directories, queue directories and data directories
+of non-default instances. If the default instance settings are: </p>
+
+<blockquote>
+<pre>
+config_directory = /conf-path/postfix
+queue_directory = /queue-path/postfix
+data_directory = /data-path/postfix
+</pre>
+</blockquote>
+
+<p> A newly-created instance named <i>postfix-myinst</i> will by default
+have: </p>
+
+<blockquote>
+<pre>
+multi_instance_enable = no
+multi_instance_name = postfix-myinst
+config_directory = /conf-path/postfix-myinst
+queue_directory = /queue-path/postfix-myinst
+data_directory = /data-path/postfix-myinst
+</pre>
+</blockquote>
+
+<p> You can override any of these defaults when creating the instance,
+but unless you want to spread instance queue directories over multiple
+file-systems, use the default naming strategy. It keeps the multiple
+instances organized in a uniform, predictable fashion. </p>
+
+<p> When specifying the instance name later, you can refer to it
+either as "postfix-myinst", or via the full path of the configuration
+directory. </p>
+
+<p> To create a new instance just use the <b>-e create</b> option: </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-myinst -e create
+</pre>
+</blockquote>
+
+<p> If the new instance is to belong to a group of related instances that
+implement a single logical service, assign it to a group: </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-myinst -G mygroup -e create
+</pre>
+</blockquote>
+
+<p> If you want to override the conventional values of the instance
+installation parameters, specify their values on the command-line: </p>
+
+<blockquote>
+<pre>
+# postmulti [-I postfix-myinst] [-G mygroup] -e create \
+ "config_directory = /path/to/config_directory" \
+ "queue_directory = /path/to/queue_directory" \
+ "data_directory = /path/to/data_directory"
+</pre>
+</blockquote>
+
+<p> A note on the <b>-I</b> and <b>-G</b> options above. These are always
+used to assign a name or group name to an instance, while the <b>-i</b>
+and <b>-g</b> options always select existing instances. By default,
+the configuration directories of newly managed instances are appended
+to the instance list. You can use the "-i" or "-g" or "-a" options to
+insert the new instance before the specified instance or group, or at
+the beginning of the instance list (multi_instance_directories parameter
+of the default instance). </p>
+
+<p> If you do specify a name (use "-I" with a name that is not "-")
+for the new instance, you may omit any of the 3 instance installation
+parameters whose instance-name based value is acceptable. Otherwise, all
+three instance installation parameters are required. You should set the
+"syslog_name" explicitly in the main.cf file of a "nameless" instance,
+in order to avoid confusion in the mail logs when multiple instances
+are in use. </p>
+
+<h3><a name="destroy"> Destroying a Postfix instance </a></h3>
+
+<p> If you no longer need an instance, you can destroy it via: </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-myinst -p stop
+# postmulti -i postfix-myinst -e disable
+# postmulti -i postfix-myinst -e destroy
+</pre>
+</blockquote>
+
+<p> The instance must be stopped, disabled and have no queued messages.
+This is expected to fully delete a just created instance that has never
+been used. If the instance is not freshly created, files added after
+the instance was created will remain in the configuration, queue or
+data directories, in which case the corresponding directory may not
+be fully removed and a warning to that effect will be displayed. You
+can complete the destruction of the instance manually by removing any
+unwanted remnants of the instance-specific "private" directories. </p>
+
+<h3><a name="import"> Importing an existing Postfix instance </a></h3>
+
+<p> If you already have an existing secondary Postfix instance that is
+not yet managed via postmulti(1), you can "import" it into the list
+of managed instances. If your instance is already using the default
+configuration directory naming scheme, just specify the corresponding
+instance name (the multi_instance_name parameter in its configuration
+file will be adjusted to match this name if necessary): </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-myinst [-G mygroup] -e import
+</pre>
+</blockquote>
+
+<p> Otherwise, you must specify the location of its configuration
+directory: </p>
+
+<blockquote>
+<pre>
+# postmulti [-I postfix-myinst] [-G mygroup] -e import \
+ "config_directory = /path/of/config_directory"
+</pre>
+</blockquote>
+
+<p> When the instance is imported, you can assign a name or a group. As
+with <a href="#create">"create"</a>, you can control the placement of the
+new instance in the start order by using "-i", "-g" or "-a" to prepend
+before the selected instance or instances. </p>
+
+<p> An imported instance is usually not multi-instance "enabled",
+unless it was part of a multi-instance configuration at an earlier
+time. If it is fully configured and ready to run, don't forget
+to <a href="#enable">enable</a> it and if necessary start it. When
+other enabled instances are already running, new instances need to
+be started individually when they are first created or imported.
+</p>
+
+<p> To find out what instances are running, use: </p>
+
+<blockquote>
+<pre>
+# postfix status
+</pre>
+</blockquote>
+
+<h3><a name="deport"> Deporting a managed Postfix instance </a></h3>
+
+<p> You can "deport" an existing instance from the list of managed
+instances. This does not destroy the instance, rather the instance
+just becomes a stand-alone Postfix instance not registered with the
+multi-instance manager. postmulti(1) will refuse to "deport" an
+instance that is not stopped and disabled. </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-myinst -p stop
+# postmulti -i postfix-myinst -e disable
+# postmulti -i postfix-myinst -e deport
+</pre>
+</blockquote>
+
+<h3><a name="assign"> Assigning a new name or group name </a></h3>
+
+<p> You can assign a new name or new group to a managed instance.
+Use "-" as the new value to assign the instance to no group or make it
+nameless. To specify a nameless secondary instance use the configuration
+directory path instead of the old name: </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-old [-I postfix-new] [-G newgroup] -e assign
+</pre>
+</blockquote>
+
+<h3><a name="enable"> Enabling/disabling managed instances </a></h3>
+
+<p> You can enable or disable a managed instance. As documented in
+postfix-wrapper(5), disabled instances are skipped with actions
+that <a href="postconf.5.html#postmulti_start_commands">start</a>,
+<a href="postconf.5.html#postmulti_start_commands">stop</a> or <a
+href="postconf.5.html#postmulti_control_commands">control</a> running
+Postfix instances. </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-myinst -e enable
+# postmulti -i postfix-myinst -e disable
+</pre>
+</blockquote>
+
+<h2><a name="credits"> Credits </a></h2>
+
+<p> Wietse Venema created Postfix, designed and implemented the
+multi-instance wrapper framework and provided design feedback that made
+the postmulti(1) utility much more general and useful than originally
+envisioned. </p>
+
+<p> The postmulti(1) utility was developed by Victor Duchovni of Morgan
+Stanley, who also wrote the initial version of this document. </p>
+
+</body> </html>