X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b16c9f8bdcfd4cce490af9e493489e128f5c8f52..41c494e2465efadc2e82002a07430e8aec85bc9b:/doc/doc-docbook/spec.xfpt?ds=inline diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index af28f0cba..cbb7045a3 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -228,6 +228,14 @@ failure report bounce message + + de-tainting + tainting, de-tainting + + + detainting + tainting, de-tainting + dialup intermittently connected hosts @@ -3847,7 +3855,9 @@ id, and the remaining ones must be email addresses. However, if the message is active (in the middle of a delivery attempt), it is not altered. This option can be used only by an admin user. -.vitem "&%-MC%&&~<&'transport'&>&~<&'hostname'&>&~<&'sequence&~number'&>&&& +.vitem "&%-MC%&&~<&'transport'&>&~<&'hostname'&>&&& + &~<&'host&~IP'&>&&& + &~<&'sequence&~number'&>&&& &~<&'message&~id'&>" .oindex "&%-MC%&" .cindex "SMTP" "passed connection" @@ -3919,6 +3929,18 @@ This option is not intended for use by external callers. It is used internally by Exim in conjunction with the &%-MC%& option, and passes on the fact that the host to which Exim is connected supports TLS encryption. +.new +.vitem &%-MCr%&&~<&'SNI'&> &&& + &%-MCs%&&~<&'SNI'&> +.oindex "&%-MCs%&" +.oindex "&%-MCr%&" +These options are not intended for use by external callers. It is used internally +by Exim in conjunction with the &%-MCt%& option, and passes on the fact that +a TLS Server Name Indication was sent as part of the channel establishment. +The argument gives the SNI string. +The "r" variant indicates a DANE-verified connection. +.wen + .vitem &%-MCt%&&~<&'IP&~address'&>&~<&'port'&>&~<&'cipher'&> .oindex "&%-MCt%&" This option is not intended for use by external callers. It is used internally @@ -5905,13 +5927,13 @@ messages that are submitted by SMTP from local processes using the standard input and output (that is, not using TCP/IP). A number of MUAs operate in this manner. .code -deny message = Restricted characters in address - domains = +local_domains +deny domains = +local_domains local_parts = ^[.] : ^.*[@%!/|] + message = Restricted characters in address -deny message = Restricted characters in address - domains = !+local_domains +deny domains = !+local_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ + message = Restricted characters in address .endd These statements are concerned with local parts that contain any of the characters &"@"&, &"%"&, &"!"&, &"/"&, &"|"&, or dots in unusual places. @@ -6015,10 +6037,10 @@ require verify = recipient This statement requires the recipient address to be verified; if verification fails, the address is rejected. .code -# deny message = rejected because $sender_host_address \ +# deny dnslists = black.list.example +# message = rejected because $sender_host_address \ # is in a black list at $dnslist_domain\n\ # $dnslist_text -# dnslists = black.list.example # # warn dnslists = black.list.example # add_header = X-Warning: $sender_host_address is in \ @@ -6641,6 +6663,8 @@ file that is searched could contain lines like this: .endd When the lookup succeeds, the result of the expansion is a list of domains (and possibly other types of item that are allowed in domain lists). +.cindex "tainted data" "de-tainting" +The result of the expansion is not tainted. In the second example, the lookup is a single item in a domain list. It causes Exim to use a lookup to see if the domain that is being processed can be found @@ -6661,6 +6685,13 @@ If the value of &$sender_host_address$& is 192.168.5.6, expansion of the first &%domains%& setting above generates the second setting, which therefore causes a second lookup to occur. +.new +The lookup type may optionally be followed by a comma +and a comma-separated list of options. +Each option is a &"name=value"& pair. +Whether an option is meaningful depands on the lookup type. +.wen + The rest of this chapter describes the different lookup types that are available. Any of them can be used in any part of the configuration where a lookup is permitted. @@ -6678,6 +6709,13 @@ lookup to succeed. The lookup type determines how the file is searched. .new .cindex "tainted data" "single-key lookups" The file string may not be tainted + +.cindex "tainted data" "de-tainting" +All single-key lookups support the option &"ret=key"&. +If this is given and the lookup +(either underlying implementation or cached value) +returns data, the result is replaced with a non-tainted +version of the lookup key. .wen .next .cindex "query-style lookup" "definition of" @@ -8022,8 +8060,8 @@ For MySQL, PostgreSQL and Redis lookups (but not currently for Oracle and InterB it is possible to specify a list of servers with an individual query. This is done by appending a comma-separated option to the query type: .display -.endd &`,servers=`&&'server1:server2:server3:...'& +.endd .wen Each item in the list may take one of two forms: .olist @@ -8719,8 +8757,13 @@ The value for a match will be the list element string. .cindex "tainted data" "de-tainting" Note that this is commonly untainted (depending on the way the list was created). +Specifically, explicit text in the configuration file in not tainted. This is a useful way of obtaining an untainted equivalent to the domain, for later operations. + +However if the list (including one-element lists) +is created by expanding a variable containing tainted data, +it is tainted and so will the match value be. .endlist @@ -9439,7 +9482,22 @@ reasons, .cindex "tainted data" expansion .cindex expansion "tainted data" and expansion of data deriving from the sender (&"tainted data"&) -is not permitted. +.new +is not permitted (including acessing a file using a tainted name). +The main config option &%allow_insecure_tainted_data%& can be used as +mitigation during uprades to more secure configurations. +.wen + +.new +Common ways of obtaining untainted equivalents of variables with +tainted values +.cindex "tainted data" "de-tainting" +come down to using the tainted value as a lookup key in a trusted database. +This database could be the filesystem structure, +or the password file, +or accessed via a DBMS. +Specific methods are indexed under &"de-tainting"&. +.wen @@ -10154,6 +10212,18 @@ extracted is used. You can use &`fail`& instead of {<&'string3'&>} as in a string extract. +.new +.vitem &*${listquote{*&<&'separator'&>&*}{*&<&'string'&>&*}}*& +.cindex quoting "for list" +.cindex list quoting +This item doubles any occurrence of the separator character +in the given string. +An empty string is replaced with a single space. +This converts the string into a safe form for use as a list element, +in a list using the given separator. +.wen + + .vitem "&*${lookup{*&<&'key'&>&*}&~*&<&'search&~type'&>&*&~&&& {*&<&'file'&>&*}&~{*&<&'string1'&>&*}&~{*&<&'string2'&>&*}}*&" This is the first of one of two different types of lookup item, which are both @@ -10869,8 +10939,7 @@ a decimal representation of the answer (without &"K"&, &"M"& or &"G"&). For exam As a more realistic example, in an ACL you might have .code -deny message = Too many bad recipients - condition = \ +deny condition = \ ${if and { \ {>{$rcpt_count}{10}} \ { \ @@ -10879,6 +10948,7 @@ deny message = Too many bad recipients {${eval:$rcpt_count/2}} \ } \ }{yes}{no}} + message = Too many bad recipients .endd The condition is true if there have been more than 10 RCPT commands and fewer than half of them have resulted in a valid recipient. @@ -11906,15 +11976,12 @@ request, for a password, so the data consists of just two strings. There can be problems if any of the strings are permitted to contain colon characters. In the usual way, these have to be doubled to avoid being taken as -separators. If the data is being inserted from a variable, the &%sg%& expansion -item can be used to double any existing colons. For example, the configuration +separators. +The &%listquote%& expansion item can be used for this. +For example, the configuration of a LOGIN authenticator might contain this setting: .code -server_condition = ${if pam{$auth1:${sg{$auth2}{:}{::}}}} -.endd -For a PLAIN authenticator you could use: -.code -server_condition = ${if pam{$auth2:${sg{$auth3}{:}{::}}}} +server_condition = ${if pam{$auth1:${listquote{:}{$auth2}}}} .endd In some operating systems, PAM authentication can be done only from a process running as root. Since Exim is running as the Exim user when receiving @@ -12309,13 +12376,6 @@ contain the trailing slash. If &$config_file$& does not contain a slash, .vindex "&$config_file$&" The name of the main configuration file Exim is using. -.vitem &$dmarc_domain_policy$& &&& - &$dmarc_status$& &&& - &$dmarc_status_text$& &&& - &$dmarc_used_domains$& -Results of DMARC verification. -For details see section &<>&. - .vitem &$dkim_verify_status$& Results of DKIM verification. For details see section &<>&. @@ -12348,6 +12408,13 @@ When a message has been received this variable contains a colon-separated list of signer domains and identities for the message. For details see section &<>&. +.vitem &$dmarc_domain_policy$& &&& + &$dmarc_status$& &&& + &$dmarc_status_text$& &&& + &$dmarc_used_domains$& +Results of DMARC verification. +For details see section &<>&. + .vitem &$dnslist_domain$& &&& &$dnslist_matched$& &&& &$dnslist_text$& &&& @@ -12428,17 +12495,23 @@ Often &$domain_data$& is usable in this role. .vitem &$domain_data$& .vindex "&$domain_data$&" -When the &%domains%& option on a router matches a domain by -means of a lookup, the data read by the lookup is available during the running -of the router as &$domain_data$&. In addition, if the driver routes the +When the &%domains%& condition on a router +.new +or an ACL +matches a domain +against a list, the match value is copied to &$domain_data$&. +This is an enhancement over previous versions of Exim, when it only +applied to the data read by a lookup. +For details on match values see section &<>& et. al. +.wen + +If the router routes the address to a transport, the value is available in that transport. If the transport is handling multiple addresses, the value from the first address is used. -&$domain_data$& is also set when the &%domains%& condition in an ACL matches a -domain by means of a lookup. The data read by the lookup is available during -the rest of the ACL statement. In all other situations, this variable expands -to nothing. +&$domain_data$& set in an ACL is available during +the rest of the ACL statement. .vitem &$exim_gid$& .vindex "&$exim_gid$&" @@ -12519,7 +12592,7 @@ result of the lookup is made available in the &$host_data$& variable. This allows you, for example, to do things like this: .code deny hosts = net-lsearch;/some/file -message = $host_data + message = $host_data .endd .vitem &$host_lookup_deferred$& .cindex "host name" "lookup, failure of" @@ -12672,21 +12745,19 @@ to process local parts in a case-dependent manner in a router, you can set the .vitem &$local_part_data$& .vindex "&$local_part_data$&" -When the &%local_parts%& option on a router matches a local part by means of a -lookup, the data read by the lookup is available during the running of the -router as &$local_part_data$&. In addition, if the driver routes the address -to a transport, the value is available in that transport. If the transport is -handling multiple addresses, the value from the first address is used. +When the &%local_parts%& condition on a router or ACL +matches a local part list +.new +the match value is copied to &$local_part_data$&. +This is an enhancement over previous versions of Exim, when it only +applied to the data read by a lookup. +For details on match values see section &<>& et. al. +.wen .new The &%check_local_user%& router option also sets this variable. .wen -&$local_part_data$& is also set when the &%local_parts%& condition in an ACL -matches a local part by means of a lookup. The data read by the lookup is -available during the rest of the ACL statement. In all other situations, this -variable expands to nothing. - .vindex &$local_part_prefix$& &&& &$local_part_prefix_v$& &&& &$local_part_suffix$& &&& @@ -12871,9 +12942,9 @@ header and the body). Here is an example of the use of this variable in a DATA ACL: .code -deny message = Too many lines in message header - condition = \ +deny condition = \ ${if <{250}{${eval:$message_linecount - $body_linecount}}} + message = Too many lines in message header .endd In the MAIL and RCPT ACLs, the value is zero because at that stage the message has not yet been received. @@ -14362,6 +14433,8 @@ listed in more than one group. .section "Miscellaneous" "SECID96" .table2 +.row &%add_environment%& "environment variables" +.row &%allow_insecure_tainted_data%& "turn taint errors into warnings" .row &%bi_command%& "to run for &%-bi%& command line option" .row &%debug_store%& "do extra internal checks" .row &%disable_ipv6%& "do no IPv6 processing" @@ -14562,6 +14635,7 @@ listed in more than one group. .row &%percent_hack_domains%& "recognize %-hack for these domains" .row &%spamd_address%& "set interface to SpamAssassin" .row &%strict_acl_vars%& "object to unset ACL variables" +.row &%spf_smtp_comment_template%& "template for &$spf_smtp_comment$&" .endtable @@ -14648,6 +14722,9 @@ See also the &'Policy controls'& section above. .row &%dkim_verify_keytypes%& "DKIM key types accepted for signatures" .row &%dkim_verify_min_keysizes%& "DKIM key sizes accepted for signatures" .row &%dkim_verify_signers%& "DKIM domains for which DKIM ACL is run" +.row &%dmarc_forensic_sender%& "DMARC sender for report messages" +.row &%dmarc_history_file%& "DMARC results log" +.row &%dmarc_tld_file%& "DMARC toplevel domains file" .row &%host_lookup%& "host name looked up for these hosts" .row &%host_lookup_order%& "order of DNS and local name lookups" .row &%recipient_unqualified_hosts%& "may send unqualified recipients" @@ -14965,6 +15042,18 @@ domains (defined in the named domain list &%local_domains%& in the default configuration). This &"magic string"& matches the domain literal form of all the local host's IP addresses. +.new +.option allow_insecure_tainted_data main boolean false +.cindex "de-tainting" +.oindex "allow_insecure_tainted_data" +The handling of tainted data may break older (pre 4.94) configurations. +Setting this option to "true" turns taint errors (which result in a temporary +message rejection) into warnings. This option is meant as mitigation only +and deprecated already today. Future releases of Exim may ignore it. +The &%taint%& log selector can be used to suppress even the warnings. +.wen + + .option allow_mx_to_ip main boolean false .cindex "MX record" "pointing to IP address" @@ -15452,6 +15541,14 @@ the ACL once for each signature in the message. See section &<>&. +.option dmarc_forensic_sender main string&!! unset +.option dmarc_history_file main string unset +.option dmarc_tld_file main string unset +.cindex DMARC "main section options" +These options control DMARC processing. +See section &<>& for details. + + .option dns_again_means_nonexist main "domain list&!!" unset .cindex "DNS" "&""try again""& response; overriding" DNS lookups give a &"try again"& response for the DNS errors @@ -15631,6 +15728,10 @@ and RET and ORCPT options on MAIL FROM commands. A NOTIFY=SUCCESS option requests success-DSN messages. A NOTIFY= option with no argument requests that no delay or failure DSNs are sent. +.new +&*Note*&: Supplying success-DSN messages has been criticised +on privacy grounds; it can leak details of internal forwarding. +.wen .option dsn_from main "string&!!" "see below" .cindex "&'From:'& header line" "in bounces" @@ -16796,7 +16897,7 @@ not count as protocol errors (see &%smtp_max_synprot_errors%&). .option pipelining_connect_advertise_hosts main "host list&!!" * .cindex "pipelining" "early connection" .cindex "pipelining" PIPE_CONNECT -.cindex "ESMTP extensions" X_PIPE_CONNECT +.cindex "ESMTP extensions" PIPE_CONNECT If Exim is built with the SUPPORT_PIPE_CONNECT build option this option controls which hosts the facility is advertised to and from which pipeline early-connection (before MAIL) SMTP @@ -16805,7 +16906,9 @@ When used, the pipelining saves on roundtrip times. See also the &%hosts_pipe_connect%& smtp transport option. -Currently the option name &"X_PIPE_CONNECT"& is used. +.new +The SMTP service extension keyword advertised is &"PIPE_CONNECT"&. +.wen .option prdr_enable main boolean false @@ -17730,6 +17833,48 @@ See section &<>& for more details. This option is available when Exim is compiled with SPF support. See section &<>& for more details. +.new +.option spf_smtp_comment_template main string&!! "Please%_see%_http://www.open-spf.org/Why" +This option is available when Exim is compiled with SPF support. It +allows the customisation of the SMTP comment that the SPF library +generates. You are strongly encouraged to link to your own explanative +site. The template must not contain spaces. If you need spaces in the +output, use the proper placeholder. If libspf2 can not parse the +template, it uses a built-in default broken link. The following placeholders +(along with Exim variables (but see below)) are allowed in the template: +.ilist +&*%_*&: A space. +.next +&*%{L}*&: Envelope sender's local part. +.next +&*%{S}*&: Envelope sender. +.next +&*%{O}*&: Envelope sender's domain. +.next +&*%{D}*&: Current(?) domain. +.next +&*%{I}*&: SMTP client Ip. +.next +&*%{C}*&: SMTP client pretty IP. +.next +&*%{T}*&: Epoch time (UTC). +.next +&*%{P}*&: SMTP client domain name. +.next +&*%{V}*&: IP version. +.next +&*%{H}*&: EHLO/HELO domain. +.next +&*%{R}*&: Receiving domain. +.endlist +The capitalized placeholders do proper URL encoding, if you use them +lowercased, no encoding takes place. This list was compiled from the +libspf2 sources. + +A note on using Exim variables: As +currently the SPF library is initialized before the SMTP EHLO phase, +the variables useful for expansion are quite limited. +.wen .option split_spool_directory main boolean false @@ -25300,11 +25445,14 @@ BDAT will not be used in conjunction with a transport filter. .option hosts_try_dane smtp "host list&!!" * .cindex DANE "transport options" .cindex DANE "attempting for certain servers" -If built with DANE support, Exim will require that a DNSSEC-validated -TLSA record is present for any host matching the list, -and that a DANE-verified TLS connection is made. See -the &%dnssec_request_domains%& router and transport options. -There will be no fallback to in-clear communication. +.new +If built with DANE support, Exim will look up a +TLSA record for any host matching the list, +If one is found and that lookup was DNSSEC-validated, +then Exim requires that a DANE-verified TLS connection is made for that host; +there will be no fallback to in-clear communication. +.wen +See the &%dnssec_request_domains%& router and transport options. See section &<>&. .option hosts_try_fastopen smtp "host list&!!" * @@ -25577,7 +25725,11 @@ ciphers is a preference order. .option tls_sni smtp string&!! unset .cindex "TLS" "Server Name Indication" .vindex "&$tls_sni$&" -If this option is set then it sets the $tls_out_sni variable and causes any +If this option is set +.new +and the connection is not DANE-validated +.wen +then it sets the $tls_out_sni variable and causes any TLS session to pass this value as the Server Name Indication extension to the remote side, which can be used by the remote side to select an appropriate certificate and private key for the session. @@ -27531,7 +27683,14 @@ fixed_plain: client_send = ^username^mysecret .endd The lack of colons means that the entire text is sent with the AUTH -command, with the circumflex characters converted to NULs. A similar example +command, with the circumflex characters converted to NULs. +.new +Note that due to the ambiguity of parsing three consectutive circumflex characters +there is no way to provide a password having a leading circumflex. +.wen + + +A similar example that uses the LOGIN mechanism is: .code fixed_login: @@ -28597,6 +28756,12 @@ Some other recently added features may only be available in one or the other. This should be documented with the feature. If the documentation does not explicitly state that the feature is infeasible in the other TLS implementation, then patches are welcome. +.new +.next +The output from "exim -bV" will show which (if any) support was included +in the build. +Also, the macro "_HAVE_OPENSSL" or "_HAVE_GNUTLS" will be defined. +.wen .endlist @@ -29135,8 +29300,14 @@ certificate verification to the listed servers. Verification either must or need not succeed respectively. The &%tls_verify_cert_hostnames%& option lists hosts for which additional -checks are made: that the host name (the one in the DNS A record) -is valid for the certificate. +name checks are made on the server certificate. +.new +The match against this list is, as per other Exim usage, the +IP for the host. That is most closely associated with the +name on the DNS A (or AAAA) record for the host. +However, the name that needs to be in the certificate +is the one at the head of any CNAME chain leading to the A record. +.wen The option defaults to always checking. The &(smtp)& transport has two OCSP-related options: @@ -29217,6 +29388,11 @@ nothing more to it. Choosing a sensible value not derived insecurely is the only point of caution. The &$tls_out_sni$& variable will be set to this string for the lifetime of the client connection (including during authentication). +.new +If DAVE validated the connection attempt then the value of the &%tls_sni%& option +is forced to the domain part of the recipient address. +.wen + Except during SMTP client sessions, if &$tls_in_sni$& is set then it is a string received from a client. It can be logged with the &%log_selector%& item &`+tls_sni`&. @@ -29420,7 +29596,7 @@ by (a) is thought to be smaller than that of the set of root CAs. It also allows the server to declare (implicitly) that connections to it should use TLS. An MITM could simply fail to pass on a server's STARTTLS. -DANE scales better than having to maintain (and side-channel communicate) copies of server certificates +DANE scales better than having to maintain (and communicate via side-channel) copies of server certificates for every possible target server. It also scales (slightly) better than having to maintain on an SMTP client a copy of the standard CAs bundle. It also means not having to pay a CA for certificates. @@ -29565,6 +29741,7 @@ If DANE is requested and useable (see above) the following transport options are tls_verify_certificates tls_crl tls_verify_cert_hostnames + tls_sni .endd If DANE is not usable, whether requested or not, and CA-anchored @@ -30221,8 +30398,8 @@ The &%message%& modifier operates exactly as it does for &%accept%&. &%drop%&: This verb behaves like &%deny%&, except that an SMTP connection is forcibly closed after the 5&'xx'& error message has been sent. For example: .code -drop message = I don't take more than 20 RCPTs - condition = ${if > {$rcpt_count}{20}} +drop condition = ${if > {$rcpt_count}{20}} + message = I don't take more than 20 RCPTs .endd There is no difference between &%deny%& and &%drop%& for the connect-time ACL. The connection is always dropped after sending a 550 response. @@ -31458,7 +31635,7 @@ of the lookup is made available in the &$host_data$& variable. This allows you, for example, to set up a statement like this: .code deny hosts = net-lsearch;/some/file -message = $host_data + message = $host_data .endd which gives a custom error message for each denied host. @@ -31602,8 +31779,8 @@ section &<>& (callouts are described in section condition to restrict it to bounce messages only: .code deny senders = : - message = A valid sender header is required for bounces !verify = header_sender + message = A valid sender header is required for bounces .endd .vitem &*verify&~=&~header_syntax*& @@ -31785,8 +31962,8 @@ Testing the list of domains stops as soon as a match is found. If you want to warn for one list and block for another, you can use two different statements: .code deny dnslists = blackholes.mail-abuse.org -warn message = X-Warn: sending host is on dialups list - dnslists = dialups.mail-abuse.org +warn dnslists = dialups.mail-abuse.org + message = X-Warn: sending host is on dialups list .endd .cindex caching "of dns lookup" .cindex DNS TTL @@ -31827,8 +32004,8 @@ addresses (see, e.g., the &'domain based zones'& link at with these lists. You can change the name that is looked up in a DNS list by listing it after the domain name, introduced by a slash. For example, .code -deny message = Sender's domain is listed at $dnslist_domain - dnslists = dsn.rfc-ignorant.org/$sender_address_domain +deny dnslists = dsn.rfc-ignorant.org/$sender_address_domain + message = Sender's domain is listed at $dnslist_domain .endd This particular example is useful only in ACLs that are obeyed after the RCPT or DATA commands, when a sender address is available. If (for @@ -31892,13 +32069,13 @@ dnslists = black.list.tld/a.domain::b.domain However, when the data for the list is obtained from a lookup, the second form is usually much more convenient. Consider this example: .code -deny message = The mail servers for the domain \ +deny dnslists = sbl.spamhaus.org/<|${lookup dnsdb {>|a=<|\ + ${lookup dnsdb {>|mxh=\ + $sender_address_domain} }} } + message = The mail servers for the domain \ $sender_address_domain \ are listed at $dnslist_domain ($dnslist_value); \ see $dnslist_text. - dnslists = sbl.spamhaus.org/<|${lookup dnsdb {>|a=<|\ - ${lookup dnsdb {>|mxh=\ - $sender_address_domain} }} } .endd Note the use of &`>|`& in the dnsdb lookup to specify the separator for multiple DNS records. The inner dnsdb lookup produces a list of MX hosts @@ -31971,7 +32148,7 @@ very meaningful. See section &<>& for a way of obtaining more information. You can use the DNS list variables in &%message%& or &%log_message%& modifiers -&-- although these appear before the condition in the ACL, they are not +&-- even if these appear before the condition in the ACL, they are not expanded until after it has failed. For example: .code deny hosts = !+local_networks @@ -32157,12 +32334,12 @@ restrictions, to get the TXT record. As a byproduct of this, there is also a check that the IP being tested is indeed on the first list. The first domain is the one that is put in &$dnslist_domain$&. For example: .code -deny message = \ - rejected because $sender_host_address is blacklisted \ - at $dnslist_domain\n$dnslist_text - dnslists = \ +deny dnslists = \ sbl.spamhaus.org,sbl-xbl.spamhaus.org=127.0.0.2 : \ dul.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.10 + message = \ + rejected because $sender_host_address is blacklisted \ + at $dnslist_domain\n$dnslist_text .endd For the first blacklist item, this starts by doing a lookup in &'sbl-xbl.spamhaus.org'& and testing for a 127.0.0.2 return. If there is a @@ -32352,12 +32529,12 @@ new rate. .code acl_check_connect: deny ratelimit = 100 / 5m / readonly - log_message = RATE CHECK: $sender_rate/$sender_rate_period \ + log_message = RATE CHECK: $sender_rate/$sender_rate_period \ (max $sender_rate_limit) # ... acl_check_mail: warn ratelimit = 100 / 5m / strict - log_message = RATE UPDATE: $sender_rate/$sender_rate_period \ + log_message = RATE UPDATE: $sender_rate/$sender_rate_period \ (max $sender_rate_limit) .endd @@ -32467,16 +32644,16 @@ deny authenticated = * ratelimit = 100 / 1d / strict / $authenticated_id # System-wide rate limit -defer message = Sorry, too busy. Try again later. - ratelimit = 10 / 1s / $primary_hostname +defer ratelimit = 10 / 1s / $primary_hostname + message = Sorry, too busy. Try again later. # Restrict incoming rate from each host, with a default # set using a macro and special cases looked up in a table. -defer message = Sender rate exceeds $sender_rate_limit \ - messages per $sender_rate_period - ratelimit = ${lookup {$sender_host_address} \ +defer ratelimit = ${lookup {$sender_host_address} \ cdb {DB/ratelimits.cdb} \ {$value} {RATELIMIT} } + message = Sender rate exceeds $sender_rate_limit \ + messages per $sender_rate_period .endd &*Warning*&: If you have a busy server with a lot of &%ratelimit%& tests, especially with the &%per_rcpt%& option, you may suffer from a performance @@ -33065,16 +33242,16 @@ list called &%batv_senders%&. Then, in the ACL for RCPT commands, you could use this: .code # Bounces: drop unsigned addresses for BATV senders -deny message = This address does not send an unsigned reverse path - senders = : +deny senders = : recipients = +batv_senders + message = This address does not send an unsigned reverse path # Bounces: In case of prvs-signed address, check signature. -deny message = Invalid reverse path signature. - senders = : +deny senders = : condition = ${prvscheck {$local_part@$domain}\ {PRVSCHECK_SQL}{1}} !condition = $prvscheck_result + message = Invalid reverse path signature. .endd The first statement rejects recipients for bounce messages that are addressed to plain BATV sender addresses, because it is known that BATV senders do not @@ -33611,13 +33788,13 @@ imposed by your anti-virus scanner. Here is a very simple scanning example: .code -deny message = This message contains malware ($malware_name) - malware = * +deny malware = * + message = This message contains malware ($malware_name) .endd The next example accepts messages when there is a problem with the scanner: .code -deny message = This message contains malware ($malware_name) - malware = */defer_ok +deny malware = */defer_ok + message = This message contains malware ($malware_name) .endd The next example shows how to use an ACL variable to scan with both sophie and aveserver. It assumes you have set: @@ -33626,13 +33803,13 @@ av_scanner = $acl_m0 .endd in the main Exim configuration. .code -deny message = This message contains malware ($malware_name) - set acl_m0 = sophie +deny set acl_m0 = sophie malware = * + message = This message contains malware ($malware_name) -deny message = This message contains malware ($malware_name) - set acl_m0 = aveserver +deny set acl_m0 = aveserver malware = * + message = This message contains malware ($malware_name) .endd @@ -33761,8 +33938,8 @@ is set to record the actual address used. .section "Calling SpamAssassin from an Exim ACL" "SECID206" Here is a simple example of the use of the &%spam%& condition in a DATA ACL: .code -deny message = This message was classified as SPAM - spam = joe +deny spam = joe + message = This message was classified as SPAM .endd The right-hand side of the &%spam%& condition specifies a name. This is relevant if you have set up multiple SpamAssassin profiles. If you do not want @@ -33794,9 +33971,9 @@ large ones may cause significant performance degradation. As most spam messages are quite small, it is recommended that you do not scan the big ones. For example: .code -deny message = This message was classified as SPAM - condition = ${if < {$message_size}{10K}} +deny condition = ${if < {$message_size}{10K}} spam = nobody + message = This message was classified as SPAM .endd The &%spam%& condition returns true if the threshold specified in the user's @@ -33854,8 +34031,8 @@ failed. If you want to treat DEFER as FAIL (to pass on to the next ACL statement block), append &`/defer_ok`& to the right-hand side of the spam condition, like this: .code -deny message = This message was classified as SPAM - spam = joe/defer_ok +deny spam = joe/defer_ok + message = This message was classified as SPAM .endd This causes messages to be accepted even if there is a problem with &%spamd%&. @@ -33873,9 +34050,9 @@ warn spam = nobody add_header = Subject: *SPAM* $h_Subject: # reject spam at high scores (> 12) -deny message = This message scored $spam_score spam points. - spam = nobody:true +deny spam = nobody:true condition = ${if >{$spam_score_int}{120}{1}{0}} + message = This message scored $spam_score spam points. .endd @@ -34079,10 +34256,10 @@ As an example, the following will ban &"HTML mail"& (including that sent with alternative plain text), while allowing HTML files to be attached. HTML coverletter mail attached to non-HTML coverletter mail will also be allowed: .code -deny message = HTML mail is not accepted here -!condition = $mime_is_rfc822 -condition = $mime_is_coverletter -condition = ${if eq{$mime_content_type}{text/html}{1}{0}} +deny !condition = $mime_is_rfc822 + condition = $mime_is_coverletter + condition = ${if eq{$mime_content_type}{text/html}{1}{0}} + message = HTML mail is not accepted here .endd .vitem &$mime_is_multipart$& @@ -34135,8 +34312,8 @@ expanded before being used, you must also escape dollar signs and backslashes with more backslashes, or use the &`\N`& facility to disable expansion. Here is a simple example that contains two regular expressions: .code -deny message = contains blacklisted regex ($regex_match_string) - regex = [Mm]ortgage : URGENT BUSINESS PROPOSAL +deny regex = [Mm]ortgage : URGENT BUSINESS PROPOSAL + message = contains blacklisted regex ($regex_match_string) .endd The conditions returns true if any one of the regular expressions matches. The &$regex_match_string$& expansion variable is then set up and contains the @@ -38019,6 +38196,7 @@ selection marked by asterisks: &` smtp_protocol_error `& SMTP protocol errors &` smtp_syntax_error `& SMTP syntax errors &` subject `& contents of &'Subject:'& on <= lines +&`*taint `& taint errors or warnings &`*tls_certificate_verified `& certificate verification status &`*tls_cipher `& TLS cipher suite on <= and => lines &` tls_peerdn `& TLS peer DN on <= and => lines @@ -38412,6 +38590,11 @@ using a CA trust anchor, &`CA=dane`& if using a DNS trust anchor, and &`CV=no`& if not. .next +.cindex "log" "Taint warnings" +&%taint%&: Log warnings about tainted data. This selector can't be +turned of if &%allow_insecure_tainted_data%& is false (which is the +default). +.next .cindex "log" "TLS cipher" .cindex "TLS" "logging cipher" &%tls_cipher%&: When a message is sent or received over an encrypted @@ -38481,9 +38664,9 @@ the next chapter. The utilities described here are: "check address acceptance from given IP" .irow &<>& &'exim_dbmbuild'& "build a DBM file" .irow &<>& &'exinext'& "extract retry information" -.irow &<>& &'exim_dumpdb'& "dump a hints database" -.irow &<>& &'exim_tidydb'& "clean up a hints database" -.irow &<>& &'exim_fixdb'& "patch a hints database" +.irow &<>& &'exim_dumpdb'& "dump a hints database" +.irow &<>& &'exim_tidydb'& "clean up a hints database" +.irow &<>& &'exim_fixdb'& "patch a hints database" .irow &<>& &'exim_lock'& "lock a mailbox file" .endtable @@ -38985,7 +39168,7 @@ in a transport) -.section "exim_dumpdb" "SECID261" +.section "exim_dumpdb" "SECTdumpdb" .cindex "&'exim_dumpdb'&" The entire contents of a database are written to the standard output by the &'exim_dumpdb'& program, which has no options or arguments other than the @@ -39022,7 +39205,7 @@ cross-references. -.section "exim_tidydb" "SECID262" +.section "exim_tidydb" "SECTtidydb" .cindex "&'exim_tidydb'&" The &'exim_tidydb'& utility program is used to tidy up the contents of a hints database. If run with no options, it removes all records that are more than 30 @@ -39071,7 +39254,7 @@ databases is likely to keep on increasing. -.section "exim_fixdb" "SECID263" +.section "exim_fixdb" "SECTfixdb" .cindex "&'exim_fixdb'&" The &'exim_fixdb'& program is a utility for interactively modifying databases. Its main use is for testing Exim, but it might also be occasionally useful for @@ -40867,10 +41050,10 @@ verb to a group of domains or identities. For example: .code # Warn when Mail purportedly from GMail has no gmail signature -warn log_message = GMail sender without gmail.com DKIM signature - sender_domains = gmail.com +warn sender_domains = gmail.com dkim_signers = gmail.com dkim_status = none + log_message = GMail sender without gmail.com DKIM signature .endd Note that the above does not check for a total lack of DKIM signing; @@ -40882,10 +41065,10 @@ results against the actual result of verification. This is typically used to restrict an ACL verb to a list of verification outcomes, for example: .code -deny message = Mail from Paypal with invalid/missing signature - sender_domains = paypal.com:paypal.de +deny sender_domains = paypal.com:paypal.de dkim_signers = paypal.com:paypal.de dkim_status = none:invalid:fail + message = Mail from Paypal with invalid/missing signature .endd The possible status keywords are: 'none','invalid','fail' and 'pass'. Please @@ -40969,13 +41152,16 @@ deny spf = fail message = $sender_host_address is not allowed to send mail from \ ${if def:sender_address_domain \ {$sender_address_domain}{$sender_helo_name}}. \ - Please see http://www.open-spf.org/Why?scope=\ - ${if def:sender_address_domain {mfrom}{helo}};\ + Please see http://www.open-spf.org/Why;\ identity=${if def:sender_address_domain \ {$sender_address}{$sender_helo_name}};\ ip=$sender_host_address .endd +Note: The above mentioned URL may not be as helpful as expected. You are +encouraged to replace the link with a link to a site with more +explanations. + When the spf condition has run, it sets up several expansion variables: @@ -41010,8 +41196,13 @@ variables: .vitem &$spf_smtp_comment$& .vindex &$spf_smtp_comment$& +.vindex &%spf_smtp_comment_template%& This contains a string that can be used in a SMTP response to the calling party. Useful for "fail". +.new + The string is generated by the SPF library from the template configured in the main config + option &%spf_smtp_comment_template%&. +.wen .endlist @@ -41384,8 +41575,8 @@ A possible solution is: # Or do some kind of IP lookup in a flat file or database # LIMIT = ${lookup{$sender_host_address}iplsearch{/etc/exim/proxy_limits}} - defer message = Too many connections from this IP right now - ratelimit = LIMIT / 5s / per_conn / strict + defer ratelimit = LIMIT / 5s / per_conn / strict + message = Too many connections from this IP right now .endd