# Copyright (C) 2008-2017 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # # GNU Mailman is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along with # GNU Mailman. If not, see . # This is the GNU Mailman configuration schema. It defines the default # configuration options for the core system and plugins. It uses ini-style # formats under the lazr.config regime to define all system configuration # options. See for details. [mailman] # This address is the "site owner" address. Certain messages which must be # delivered to a human, but which can't be delivered to a list owner (e.g. a # bounce from a list owner), will be sent to this address. It should point to # a human. site_owner: changeme@example.com # This is the local-part of an email address used in the From field whenever a # message comes from some entity to which there is no natural reply recipient. # Mailman will append '@' and the host name of the list involved. This # address must not bounce and it must not point to a Mailman process. noreply_address: noreply # The default language for this server. default_language: en # Membership tests for posting purposes are usually performed by looking at a # set of headers, passing the test if any of their values match a member of # the list. Headers are checked in the order given in this variable. The # value From_ means to use the envelope sender. Field names are case # insensitive. This is a space separate list of headers. sender_headers: from from_ reply-to sender # Mail command processor will ignore mail command lines after designated max. email_commands_max_lines: 10 # Default length of time a pending request is live before it is evicted from # the pending database. pending_request_life: 3d # How long should files be saved before they are evicted from the cache? cache_life: 7d # A callable to run with no arguments early in the initialization process. # This runs before database initialization. pre_hook: # A callable to run with no arguments late in the initialization process. # This runs after adapters are initialized. post_hook: # Which paths.* file system layout to use. layout: here # Can MIME filtered messages be preserved by list owners? filtered_messages_are_preservable: no # How should text/html parts be converted to text/plain when the mailing list # is set to convert HTML to plaintext? This names a command to be called, # where the substitution variable $filename is filled in by Mailman, and # contains the path to the temporary file that the command should read from. # The command should print the converted text to stdout. html_to_plain_text_command: /usr/bin/lynx -dump $filename # Specify what characters are allowed in list names. Characters outside of # the class [-_.+=!$*{}~0-9a-z] matched case insensitively are never allowed, # but this specifies a subset as the only allowable characters. This must be # a valid character class regexp or the effect on list creation is # unpredictable. listname_chars: [-_.0-9a-z] [shell] # `mailman shell` (also `withlist`) gives you an interactive prompt that you # can use to interact with an initialized and configured Mailman system. Use # --help for more information. This section allows you to configure certain # aspects of this interactive shell. # Customize the interpreter prompt. prompt: >>> # Banner to show on startup. banner: Welcome to the GNU Mailman shell # Use IPython as the shell, which must be found on the system. Valid values # are `no`, `yes`, and `debug` where the latter is equivalent to `yes` except # that any import errors will be displayed to stderr. use_ipython: no # Set this to allow for command line history if readline is available. This # can be as simple as $var_dir/history.py to put the file in the var directory. history_file: [paths.master] # Important directories for Mailman operation. These are defined here so that # different layouts can be supported. For example, a developer layout would # be different from a FHS layout. Most paths are based off the var_dir, and # often just setting that will do the right thing for all the other paths. # You might also have to set spool_dir though. # # Substitutions are allowed, but must be of the form $var where 'var' names a # configuration variable in the paths.* section. Substitutions are expanded # recursively until no more $-variables are present. Beware of infinite # expansion loops! # # This is the root of the directory structure that Mailman will use to store # its run-time data. var_dir: /var/tmp/mailman # This is where the Mailman queue files directories will be created. queue_dir: $var_dir/queue # This is the directory containing the Mailman 'runner' and 'master' commands # if set to the string '$argv', it will be taken as the directory containing # the 'mailman' command. bin_dir: $argv # All list-specific data. list_data_dir: $var_dir/lists # Directory where log files go. log_dir: $var_dir/logs # Directory for system-wide locks. lock_dir: $var_dir/locks # Directory for system-wide data. data_dir: $var_dir/data # Cache files. cache_dir: $var_dir/cache # Directory for configuration files and such. etc_dir: $var_dir/etc # Directory containing Mailman plugins. ext_dir: $var_dir/ext # Directory where the default IMessageStore puts its messages. messages_dir: $var_dir/messages # Directory for archive backends to store their messages in. Archivers should # create a subdirectory in here to store their files. archive_dir: $var_dir/archives # Root directory for site-specific template override files. template_dir: $var_dir/templates # There are also a number of paths to specific file locations that can be # defined. For these, the directory containing the file must already exist, # or be one of the directories created by Mailman as per above. # # This is where PID file for the master runner is stored. pid_file: $var_dir/master.pid # Lock file. lock_file: $lock_dir/master.lck [devmode] # Setting enabled to true enables certain safeguards and other behavior # changes that make developing Mailman easier. For example, it forces the # SMTP RCPT TO recipients to be a test address so that no messages are # accidentally sent to real addresses. enabled: no # Set this to an address to force the SMTP RCPT TO recipents when devmode is # enabled. This way messages can't be accidentally sent to real addresses. recipient: # This gets set by the testing layers so that the runner subprocesses produce # predictable dates and times. testing: no # Time-outs for starting up various test subprocesses, such as the LMTP and # REST servers. This is only used for the test suite, so if you're seeing # test failures, try increasing the wait time. wait: 60s [passwords] # Where can we find the passlib configuration file? The path can be either a # file system path or a Python import path. If the value starts with python: # then it is a Python import path, otherwise it is a file system path. File # system paths must be absolute since no guarantees are made about the current # working directory. Python paths should not include the trailing .cfg, which # the file must end with. configuration: python:mailman.config.passlib # When Mailman generates them, this is the default length of passwords. password_length: 8 [runner.master] # Define which runners, and how many of them, to start. # The full import path to the class for this runner. class: mailman.core.runner.Runner # The queue directory path that this runner scans. This is ignored for # runners that don't manage a queue directory. path: $QUEUE_DIR/$name # The number of parallel runners. This must be a power of 2. This is ignored # for runners that don't manage a queue directory. instances: 1 # Whether to start this runner or not. start: yes # The maximum number of restarts for this runner. When the runner exits # because of an error or other unexpected problem, it is automatically # restarted, until the maximum number of restarts has been reached. max_restarts: 10 # The sleep interval for the runner. It wakes up once every interval to # process the files in its slice of the queue directory. Some runners may # ignore this. sleep_time: 1s [database] # The class implementing the IDatabase. class: mailman.database.sqlite.SQLiteDatabase # Use this to set the Storm database engine URL. You generally have one # primary database connection for all of Mailman. List data and most rosters # will store their data in this database, although external rosters may access # other databases in their own way. This string supports standard # 'configuration' substitutions. url: sqlite:///$DATA_DIR/mailman.db debug: no [logging.template] # This defines various log settings. The options available are: # # - level -- Overrides the default level; this may be any of the # standard Python logging levels, case insensitive. # - format -- Overrides the default format string # - datefmt -- Overrides the default date format string # - path -- Overrides the default logger path. This may be a relative # path name, in which case it is relative to Mailman's LOG_DIR, # or it may be an absolute path name. You cannot change the # handler class that will be used. # - propagate -- Boolean specifying whether to propagate log message from this # logger to the root "mailman" logger. You cannot override # settings for the root logger. # # In this section, you can define defaults for all loggers, which will be # prefixed by 'mailman.'. Use subsections to override settings for specific # loggers. The names of the available loggers are: # # - archiver -- All archiver output # - bounce -- All bounce processing logs go here # - config -- Configuration issues # - database -- Database logging (SQLAlchemy and Alembic) # - debug -- Only used for development # - error -- All exceptions go to this log # - fromusenet -- Information related to the Usenet to Mailman gateway # - http -- Internal wsgi-based web interface # - locks -- Lock state changes # - mischief -- Various types of hostile activity # - runner -- Runner process start/stops # - smtp -- Successful SMTP activity # - smtp-failure -- Unsuccessful SMTP activity # - subscribe -- Information about leaves/joins # - vette -- Message vetting information format: %(asctime)s (%(process)d) %(message)s datefmt: %b %d %H:%M:%S %Y propagate: no level: info path: mailman.log [logging.root] [logging.archiver] [logging.bounce] path: bounce.log [logging.config] [logging.database] level: warn [logging.debug] path: debug.log level: info [logging.error] [logging.fromusenet] [logging.http] [logging.locks] [logging.mischief] [logging.runner] [logging.smtp] path: smtp.log # The smtp logger defines additional options for handling the logging of each # attempted delivery. These format strings specify what information is logged # for every message, every successful delivery, every refused delivery and # every recipient failure. To disable a status message, set the value to 'no' # (without the quotes). # # These template strings accept the following set of substitution # placeholders, if available. # # msgid -- the Message-ID of the message in question # listname -- the fully-qualified list name # sender -- the sender if available # recip -- the recipient address if available, or the number of # recipients being delivered to # size -- the approximate size of the message in bytes # seconds -- the number of seconds the operation took # refused -- the number of refused recipients # smtpcode -- the SMTP success or failure code # smtpmsg -- the SMTP success or failure message every: $msgid smtp to $listname for $recip recips, completed in $time seconds success: $msgid post to $listname from $sender, $size bytes refused: $msgid post to $listname from $sender, $size bytes, $refused failures failure: $msgid delivery to $recip failed with code $smtpcode, $smtpmsg [logging.subscribe] [logging.vette] [webservice] # The hostname at which admin web service resources are exposed. hostname: localhost # The port at which the admin web service resources are exposed. port: 8001 # Whether or not requests to the web service are secured through SSL. use_https: no # Whether or not to show tracebacks in an HTTP response for a request that # raised an exception. show_tracebacks: yes # The API version number for the current (highest) API. api_version: 3.1 # The administrative username. admin_user: restadmin # The administrative password. admin_pass: restpass [language.master] # Template for language definitions. The section name must be [language.xx] # where xx is the 2-character ISO code for the language. # The English name for the language. description: English (USA) # And the default character set for the language. charset: us-ascii # Whether the language is enabled or not. enabled: yes # Language charsets as imported from Mailman 2.1 defaults # Ref: http://www.lingoes.net/en/translator/langcode.htm [language.ar] description: Arabic charset: utf-8 enabled: yes [language.ast] description: Asturian charset: iso-8859-1 enabled: yes [language.ca] description: Catalan charset: utf-8 enabled: yes [language.cs] description: Czech charset: iso-8859-2 enabled: yes [language.da] description: Danish charset: iso-8859-1 enabled: yes [language.de] description: German charset: iso-8859-1 enabled: yes [language.el] description: Greek charset: iso-8859-7 enabled: yes [language.es] description: Spanish charset: iso-8859-1 enabled: yes [language.et] description: Estonian charset: iso-8859-15 enabled: yes [language.eu] # Basque description: Euskara charset: iso-8859-15 enabled: yes [language.fi] description: Finnish charset: iso-8859-1 enabled: yes [language.fr] description: French charset: iso-8859-1 enabled: yes [language.gl] description: Galician charset: utf-8 enabled: yes [language.he] description: Hebrew charset: utf-8 enabled: yes [language.hr] description: Croatian charset: iso-8859-2 enabled: yes [language.hu] description: Hungarian charset: iso-8859-2 enabled: yes [language.ia] description: Interlingua charset: iso-8859-15 enabled: yes [language.it] description: Italian charset: iso-8859-1 enabled: yes [language.ja] description: Japanese charset: euc-jp enabled: yes [language.ko] description: Korean charset: euc-kr enabled: yes [language.lt] description: Lithuanian charset: iso-8859-13 enabled: yes [language.nl] description: Dutch charset: iso-8859-1 enabled: yes [language.no] description: Norwegian charset: iso-8859-1 enabled: yes [language.pl] description: Polish charset: iso-8859-2 enabled: yes [language.pt] description: Protuguese charset: iso-8859-1 enabled: yes [language.pt_BR] description: Protuguese (Brazil) charset: iso-8859-1 enabled: yes [language.ro] description: Romanian charset: iso-8859-2 enabled: yes [language.ru] description: Russian charset: koi8-r enabled: yes [language.sk] description: Slovak charset: utf-8 enabled: yes [language.sl] description: Slovenian charset: iso-8859-2 enabled: yes [language.sr] description: Serbian charset: utf-8 enabled: yes [language.sv] description: Swedish charset: iso-8859-1 enabled: yes [language.tr] description: Turkish charset: iso-8859-9 enabled: yes [language.uk] description: Ukrainian charset: utf-8 enabled: yes [language.vi] description: Vietnamese charset: utf-8 enabled: yes [language.zh_CN] description: Chinese charset: utf-8 enabled: yes [language.zh_TW] description: Chinese (Taiwan) charset: utf-8 enabled: yes [antispam] # This section defines basic antispam detection settings. # This value contains lines which specify RFC 822 headers in the email to # check for spamminess. Each line contains a `key: value` pair, where the key # is the header to check and the value is a Python regular expression to match # against the header's value. Multiple checks should be entered as multiline # value with leading spaces: # # header_checks: # X-Spam: (yes|maybe) # Authentication-Results: mail.example.com; dmarc=(fail|quarantine) # # The header value and regular expression are always matched # case-insensitively. header_checks: # The chain to jump to if any of the header patterns matches. This must be # the name of an existing chain such as 'discard', 'reject', 'hold', or # 'accept', otherwise 'hold' will be used. jump_chain: hold [mta] # The class defining the interface to the incoming mail transport agent. incoming: mailman.mta.postfix.LMTP # The callable implementing delivery to the outgoing mail transport agent. # This must accept three arguments, the mailing list, the message, and the # message metadata dictionary. outgoing: mailman.mta.deliver.deliver # How to connect to the outgoing MTA. If smtp_user and smtp_pass is given, # then Mailman will attempt to log into the MTA when making a new connection. smtp_host: localhost smtp_port: 25 smtp_user: smtp_pass: # Where the LMTP server listens for connections. Use 127.0.0.1 instead of # localhost for Postfix integration, because Postfix only consults DNS # (e.g. not /etc/hosts). lmtp_host: 127.0.0.1 lmtp_port: 8024 # Ceiling on the number of recipients that can be specified in a single SMTP # transaction. Set to 0 to submit the entire recipient list in one # transaction. max_recipients: 500 # Ceiling on the number of SMTP sessions to perform on a single socket # connection. Some MTAs have limits. Set this to 0 to do as many as we like # (i.e. your MTA has no limits). Set this to some number great than 0 and # Mailman will close the SMTP connection and re-open it after this number of # consecutive sessions. max_sessions_per_connection: 0 # Maximum number of simultaneous subthreads that will be used for SMTP # delivery. After the recipients list is chunked according to max_recipients, # each chunk is handed off to the SMTP server by a separate such thread. If # your Python interpreter was not built for threads, this feature is disabled. # You can explicitly disable it in all cases by setting max_delivery_threads # to 0. max_delivery_threads: 0 # How long should messages which have delivery failures continue to be # retried? After this period of time, a message that has failed recipients # will be dequeued and those recipients will never receive the message. delivery_retry_period: 5d # These variables control the format and frequency of VERP-like delivery for # better bounce detection. VERP is Variable Envelope Return Path, defined # here: # # http://cr.yp.to/proto/verp.txt # # This involves encoding the address of the recipient as Mailman knows it into # the envelope sender address (i.e. RFC 5321 MAIL FROM). Thus, no matter what # kind of forwarding the recipient has in place, should it eventually bounce, # we will receive an unambiguous notice of the bouncing address. # # However, we're technically only "VERP-like" because we're doing the envelope # sender encoding in Mailman, not in the MTA. We do require cooperation from # the MTA, so you must be sure your MTA can be configured for extended address # semantics. # # The first variable describes how to encode VERP envelopes. It must contain # these three string interpolations, which get filled in by Mailman: # # $bounces -- the list's -bounces robot address will be set here # $local -- the recipient address's local mailbox part will be set here # $domain -- the recipient address's domain name will be set here # # This example uses the default below. # # FQDN list address is: mylist@dom.ain # Recipient is: aperson@a.nother.dom # # The envelope sender will be mylist-bounces+aperson=a.nother.dom@dom.ain # # Note that your MTA /must/ be configured to deliver such an addressed message # to mylist-bounces! verp_delimiter: + verp_format: ${bounces}+${local}=${domain} # For nicer confirmation emails, use a VERP-like format which encodes the # confirmation cookie in the reply address. This lets us put a more user # friendly Subject: on the message, but requires cooperation from the MTA. # Format is like verp_format, but with the following substitutions: # # $address -- the list-confirm address # $cookie -- the confirmation cookie verp_confirm_format: $address+$cookie # This regular expression unambiguously decodes VERP addresses, which will be # placed in the To: (or other, depending on the MTA) header of the bounce # message by the bouncing MTA. Getting this right is critical -- and tricky. # Learn your Python regular expressions. It must define exactly three named # groups, `bounces`, `local` and `domain`, with the same definition as above. # It will be compiled case-insensitively. verp_regexp: ^(?P[^+]+?)\+(?P[^=]+)=(?P[^@]+)@.*$ # This is analogous to verp_regexp, but for splitting apart the # verp_confirm_format. MUAs have been observed that mung # # From: local_part@host # # into # # To: "local_part" # # when replying, so we skip everything up to '<' if any. verp_confirm_regexp: ^(.*<)?(?P[^+]+?)\+(?P[^@]+)@.*$ # Set this to 'yes' to enable VERP-like (more user friendly) confirmations. verp_confirmations: no # Another good opportunity is when regular delivery is personalized. Here # again, we're already incurring the performance hit for addressing each # individual recipient. Set this to 'yes' to enable VERPs on all personalized # regular deliveries (personalized digests aren't supported yet). verp_personalized_deliveries: no # And finally, we can VERP normal, non-personalized deliveries. However, # because it can be a significant performance hit, we allow you to decide how # often to VERP regular deliveries. This is the interval, in number of # messages, to do a VERP recipient address. The same variable controls both # regular and digest deliveries. Set to 0 to disable occasional VERPs, set to # 1 to VERP every delivery, or to some number > 1 for only occasional VERPs. verp_delivery_interval: 0 # VERP format and regexp for probe messages. verp_probe_format: $bounces+$token@$domain verp_probe_regexp: ^(?P[^+]+?)\+(?P[^@]+)@.*$ # Set this 'yes' to activate VERP probe for disabling by bounce. verp_probes: no # This is the maximum number of automatic responses sent to an address because # of -request messages or posting hold messages. This limit prevents response # loops between Mailman and misconfigured remote email robots. Mailman # already inhibits automatic replies to any message labeled with a header # "Precendence: bulk|list|junk". This is a fallback safety valve so it should # be set fairly high. Set to 0 for no limit (probably useful only for # debugging). max_autoresponses_per_day: 10 # Some list posts and mail to the -owner address may contain DomainKey or # DomainKeys Identified Mail (DKIM) signature headers . # Various list transformations to the message such as adding a list header or # footer or scrubbing attachments or even reply-to munging can break these # signatures. It is generally felt that these signatures have value, even if # broken and even if the outgoing message is resigned. However, some sites # may wish to remove these headers by setting this to 'yes'. remove_dkim_headers: no # Where can we find the mail server specific configuration file? The path can # be either a file system path or a Python import path. If the value starts # with python: then it is a Python import path, otherwise it is a file system # path. File system paths must be absolute since no guarantees are made about # the current working directory. Python paths should not include the trailing # .cfg, which the file must end with. configuration: python:mailman.config.postfix [bounces] # How often should the bounce runner process queued detected bounces? register_bounces_every: 15m [archiver.master] # To add new archivers, define a new section based on this one, overriding the # following values. # The class implementing the IArchiver interface. class: # Set this to 'yes' to enable the archiver. enable: no # Additional configuration for the archiver. The path can be either a file # system path or a Python import path. If the value starts with python: then # it is a Python import path, otherwise it is a file system path. File system # paths must be absolute since no guarantees are made about the current # working directory. Python paths should not include the trailing .cfg, which # the file must end with. configuration: changeme # When sending the message to the archiver, you have the option of # "clobbering" the Date: header, specifically to make it more sane. Some # archivers can't handle dates that are wildly off from reality. This does # not change the Date: header for any other delivery vector except this # specific archive. # # When the original Date header is clobbered, it will always be stored in # X-Original-Date. The new Date header will always be set to the date at # which the messages was received by the Mailman server, in UTC. # # Your options here are: # * never -- Leaves the original Date header alone. # * always -- Always override the Date header. # * maybe -- Override the Date only if it is outside the clobber_skew period. clobber_date: maybe clobber_skew: 1d [archiver.mhonarc] # This is the stock MHonArc archiver. class: mailman.archiving.mhonarc.MHonArc configuration: python:mailman.config.mhonarc [archiver.mail_archive] # This is the stock mail-archive.com archiver. class: mailman.archiving.mailarchive.MailArchive configuration: python:mailman.config.mail_archive [archiver.prototype] # This is a prototypical sample archiver. class: mailman.archiving.prototype.Prototype [styles] # Python import paths inside which components are searched for which implement # the IStyle interface. Use one path per line. paths: mailman.styles # The default style to apply if nothing else was requested. The value is the # name of an existing style. If no such style exists, no style will be # applied. default: legacy-default [digests] # Headers which should be kept in both RFC 1153 (plain) and MIME digests. RFC # 1153 also specifies these headers in this exact order, so order matters. # These are space separated and case insensitive. mime_digest_keep_headers: Date From To Cc Subject Message-ID Keywords In-Reply-To References Content-Type MIME-Version Content-Transfer-Encoding Precedence Reply-To Message List-Post plain_digest_keep_headers: Message Date From Subject To Cc Message-ID Keywords Content-Type [nntp] # Set these variables if you need to authenticate to your NNTP server for # Usenet posting or reading. Leave these blank if no authentication is # necessary. user: password: # Host and port of the NNTP server to connect to. Leave these blank to use # the default localhost:119. host: port: # This controls how headers must be cleansed in order to be accepted by your # NNTP server. Some servers like INN reject messages containing prohibited # headers, or duplicate headers. The NNTP server may reject the message for # other reasons, but there's little that can be programmatically done about # that. # # These headers (case ignored) are removed from the original message. This is # a whitespace separate list of headers. remove_headers: nntp-posting-host nntp-posting-date x-trace x-complaints-to xref date-received posted posting-version relay-version received # These headers are left alone, unless there are duplicates in the original # message. Any second and subsequent headers are rewritten to the second # named header (case preserved). This is a list of header pairs, one pair per # line. rewrite_duplicate_headers: To X-Original-To CC X-Original-CC Content-Transfer-Encoding X-Original-Content-Transfer-Encoding MIME-Version X-MIME-Version [dmarc] # RFC 7489 - Domain-based Message Authentication, Reporting, and Conformance. # https://en.wikipedia.org/wiki/DMARC # Parameters for DMARC DNS lookups. If you are seeing 'DNSException: Unable # to query DMARC policy ...' entries in your error log, you may need to adjust # these. # # The time to wait for a response from a name server before timeout. resolver_timeout: 3s # The total time to spend trying to get an answer to the DNS question. resolver_lifetime: 5s # A URL from which to retrieve the data for the algorithm that computes # Organizational Domains for DMARC policy lookup purposes. This can be # anything handled by the Python urllib.request.urlopen function. See # https://publicsuffix.org/list/ for info. org_domain_data_url: https://publicsuffix.org/list/public_suffix_list.dat # How long should the local suffix list be used before it's considered out of # date. After this amount of time a new list will be downloaded, but if it # can't be accessed, old data will still be used. cache_lifetime: 7d