X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=doc%2Fdoc-txt%2Fexperimental-spec.txt;h=3389632a2eeac6b82a990a33a36924c6b213693c;hp=bdab748414d83954f6200cf179360ad27bc442f2;hb=27a79307f48631bbefe9abb6f399da0e8e4b46d1;hpb=50dc740948ba43eaeb6d33757bc83beff33f2a64 diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index bdab74841..3389632a2 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -6,7 +6,7 @@ about experimental features, all of which are unstable and liable to incompatible change. -Brightmail AntiSpam (BMI) suppport +Brightmail AntiSpam (BMI) support -------------------------------------------------------------- Brightmail AntiSpam is a commercial package. Please see @@ -42,7 +42,7 @@ These four steps are explained in more details below. 1) Adding support for BMI at compile time To compile with BMI support, you need to link Exim against - the Brighmail client SDK, consisting of a library + the Brightmail client SDK, consisting of a library (libbmiclient_single.so) and a header file (bmi_api.h). You'll also need to explicitly set a flag in the Makefile to include BMI support in the Exim binary. Both can be achieved @@ -292,172 +292,18 @@ These four steps are explained in more details below. -Sender Policy Framework (SPF) support --------------------------------------------------------------- - -To learn more about SPF, visit http://www.openspf.org. This -document does not explain the SPF fundamentals, you should -read and understand the implications of deploying SPF on your -system before doing so. - -SPF support is added via the libspf2 library. Visit - - http://www.libspf2.org/ - -to obtain a copy, then compile and install it. By default, -this will put headers in /usr/local/include and the static -library in /usr/local/lib. - -To compile Exim with SPF support, set these additional flags in -Local/Makefile: - -EXPERIMENTAL_SPF=yes -CFLAGS=-DSPF -I/usr/local/include -EXTRALIBS_EXIM=-L/usr/local/lib -lspf2 - -This assumes that the libspf2 files are installed in -their default locations. - -You can now run SPF checks in incoming SMTP by using the "spf" -ACL condition in either the MAIL, RCPT or DATA ACLs. When -using it in the RCPT ACL, you can make the checks dependent on -the RCPT address (or domain), so you can check SPF records -only for certain target domains. This gives you the -possibility to opt-out certain customers that do not want -their mail to be subject to SPF checking. - -The spf condition takes a list of strings on its right-hand -side. These strings describe the outcome of the SPF check for -which the spf condition should succeed. Valid strings are: - - o pass The SPF check passed, the sending host - is positively verified by SPF. - o fail The SPF check failed, the sending host - is NOT allowed to send mail for the domain - in the envelope-from address. - o softfail The SPF check failed, but the queried - domain can't absolutely confirm that this - is a forgery. - o none The queried domain does not publish SPF - records. - o neutral The SPF check returned a "neutral" state. - This means the queried domain has published - a SPF record, but wants to allow outside - servers to send mail under its domain as well. - This should be treated like "none". - o permerror This indicates a syntax error in the SPF - record of the queried domain. You may deny - messages when this occurs. (Changed in 4.83) - o temperror This indicates a temporary error during all - processing, including Exim's SPF processing. - You may defer messages when this occurs. - (Changed in 4.83) - o err_temp Same as permerror, deprecated in 4.83, will be - removed in a future release. - o err_perm Same as temperror, deprecated in 4.83, will be - removed in a future release. - -You can prefix each string with an exclamation mark to invert -its meaning, for example "!fail" will match all results but -"fail". The string list is evaluated left-to-right, in a -short-circuit fashion. When a string matches the outcome of -the SPF check, the condition succeeds. If none of the listed -strings matches the outcome of the SPF check, the condition -fails. - -Here is an example to fail forgery attempts from domains that -publish SPF records: - -/* ----------------- -deny 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.openspf.org/Why?scope=${if def:sender_address_domain {mfrom}{helo}};identity=${if def:sender_address_domain {$sender_address}{$sender_helo_name}};ip=$sender_host_address - spf = fail ---------------------- */ - -You can also give special treatment to specific domains: - -/* ----------------- -deny message = AOL sender, but not from AOL-approved relay. - sender_domains = aol.com - spf = fail:neutral ---------------------- */ - -Explanation: AOL publishes SPF records, but is liberal and -still allows non-approved relays to send mail from aol.com. -This will result in a "neutral" state, while mail from genuine -AOL servers will result in "pass". The example above takes -this into account and treats "neutral" like "fail", but only -for aol.com. Please note that this violates the SPF draft. - -When the spf condition has run, it sets up several expansion -variables. - - $spf_header_comment - This contains a human-readable string describing the outcome - of the SPF check. You can add it to a custom header or use - it for logging purposes. - - $spf_received - This contains a complete Received-SPF: header that can be - added to the message. Please note that according to the SPF - draft, this header must be added at the top of the header - list. Please see section 10 on how you can do this. - - Note: in case of "Best-guess" (see below), the convention is - to put this string in a header called X-SPF-Guess: instead. - - $spf_result - This contains the outcome of the SPF check in string form, - one of pass, fail, softfail, none, neutral, permerror or - temperror. - - $spf_smtp_comment - This contains a string that can be used in a SMTP response - to the calling party. Useful for "fail". - -In addition to SPF, you can also perform checks for so-called -"Best-guess". Strictly speaking, "Best-guess" is not standard -SPF, but it is supported by the same framework that enables SPF -capability. Refer to http://www.openspf.org/FAQ/Best_guess_record -for a description of what it means. - -To access this feature, simply use the spf_guess condition in place -of the spf one. For example: - -/* ----------------- -deny message = $sender_host_address doesn't look trustworthy to me - spf_guess = fail ---------------------- */ - -In case you decide to reject messages based on this check, you -should note that although it uses the same framework, "Best-guess" -is NOT SPF, and therefore you should not mention SPF at all in your -reject message. - -When the spf_guess condition has run, it sets up the same expansion -variables as when spf condition is run, described above. - -Additionally, since Best-guess is not standardized, you may redefine -what "Best-guess" means to you by redefining spf_guess variable in -global config. For example, the following: - -/* ----------------- -spf_guess = v=spf1 a/16 mx/16 ptr ?all ---------------------- */ - -would relax host matching rules to a broader network range. - - SRS (Sender Rewriting Scheme) Support -------------------------------------------------------------- Exiscan currently includes SRS support via Miles Wilton's libsrs_alt library. The current version of the supported -library is 0.5. +library is 0.5, there are reports of 1.0 working. In order to use SRS, you must get a copy of libsrs_alt from -http://srs.mirtol.com/ +https://opsec.eu/src/srs/ + +(not the original source, which has disappeared.) Unpack the tarball, then refer to MTAs/README.EXIM to proceed. You need to set @@ -467,8 +313,10 @@ EXPERIMENTAL_SRS=yes in your Local/Makefile. + DCC Support -------------------------------------------------------------- +Distributed Checksum Clearinghouse; http://www.rhyolite.com/dcc/ *) Building exim @@ -538,7 +386,9 @@ Then set something like mout-xforward.gmx.net 82.165.159.12 mout.gmx.net 212.227.15.16 -Use a reasonable IP. eg. one the sending cluster acutally uses. +Use a reasonable IP. eg. one the sending cluster actually uses. + + DMARC Support -------------------------------------------------------------- @@ -559,7 +409,7 @@ that headers will be in /usr/local/include, and that the libraries are in /usr/local/lib. 1. To compile Exim with DMARC support, you must first enable SPF. -Please read the above section on enabling the EXPERIMENTAL_SPF +Please read the Local/Makefile comments on enabling the SUPPORT_SPF feature. You must also have DKIM support, so you cannot set the DISABLE_DKIM feature. Once both of those conditions have been met you can enable DMARC in Local/Makefile: @@ -580,12 +430,14 @@ package controlled locations (/usr/include and /usr/lib). 2. Use the following global settings to configure DMARC: -Required: +Optional: dmarc_tld_file Defines the location of a text file of valid top level domains the opendmarc library uses during domain parsing. Maintained by Mozilla, the most current version can be downloaded from a link at http://publicsuffix.org/list/. + If unset, "/etc/exim/opendmarc.tlds" (hardcoded) + is used. Optional: dmarc_history_file Defines the location of a file to log results @@ -623,10 +475,10 @@ exim will send these forensic emails. It's also advised that you configure a dmarc_forensic_sender because the default sender address construction might be inadequate. - control = dmarc_forensic_enable + control = dmarc_enable_forensic (AGAIN: You can choose not to send these forensic reports by simply -not putting the dmarc_forensic_enable control line at any point in +not putting the dmarc_enable_forensic control line at any point in your exim config. If you don't tell it to send them, it will not send them.) @@ -755,486 +607,203 @@ b. Configure, somewhere before the DATA ACL, the control option to deny dmarc_status = reject !authenticated = * - message = Message from $domain_used_domain failed sender's DMARC policy, REJECT + message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT -Event Actions --------------------------------------------------------------- +DSN extra information +--------------------- +If compiled with EXPERIMENTAL_DSN_INFO extra information will be added +to DSN fail messages ("bounces"), when available. The intent is to aid +tracing of specific failing messages, when presented with a "bounce" +complaint and needing to search logs. -(Renamed from TPDA, Transport post-delivery actions) -An arbitrary per-transport string can be expanded upon various transport events. -Additionally a main-section configuration option can be expanded on some -per-message events. -This feature may be used, for example, to write exim internal log information -(not available otherwise) into a database. +The remote MTA IP address, with port number if nonstandard. +Example: + Remote-MTA: X-ip; [127.0.0.1]:587 +Rationale: + Several addresses may correspond to the (already available) + dns name for the remote MTA. -In order to use the feature, you must compile with +The remote MTA connect-time greeting. +Example: + X-Remote-MTA-smtp-greeting: X-str; 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +Rationale: + This string sometimes presents the remote MTA's idea of its + own name, and sometimes identifies the MTA software. -EXPERIMENTAL_EVENT=yes +The remote MTA response to HELO or EHLO. +Example: + X-Remote-MTA-helo-response: X-str; 250-the.local.host.name Hello localhost [127.0.0.1] +Limitations: + Only the first line of a multiline response is recorded. +Rationale: + This string sometimes presents the remote MTA's view of + the peer IP connecting to it. -in your Local/Makefile +The reporting MTA detailed diagnostic. +Example: + X-Exim-Diagnostic: X-str; SMTP error from remote mail server after RCPT TO:: 550 hard error +Rationale: + This string sometimes give extra information over the + existing (already available) Diagnostic-Code field. -and define one or both of -- the event_action option in the transport -- the event_action main option -to be expanded when the event fires. -A new variable, $event_name, is set to the event type when the -expansion is done. The current list of events is: +Note that non-RFC-documented field names and data types are used. - msg:complete after main per message - msg:delivery after transport per recipient - msg:host:defer after transport per attempt - msg:fail:delivery after main per recipient - msg:fail:internal after main per recipient - tcp:connect before transport per connection - tcp:close after transport per connection - tls:cert before both per certificate in verification chain - smtp:connect after transport per connection -The expansion is called for all event types, and should use the $event_name -value to decide when to act. The variable data is a colon-separated -list, describing an event tree. +LMDB Lookup support +------------------- +LMDB is an ultra-fast, ultra-compact, crash-proof key-value embedded data store. +It is modeled loosely on the BerkeleyDB API. You should read about the feature +set as well as operation modes at https://symas.com/products/lightning-memory-mapped-database/ -There is an auxilary variable, $event_data, for which the -content is event_dependent: +LMDB single key lookup support is provided by linking to the LMDB C library. +The current implementation does not support writing to the LMDB database. - msg:delivery smtp confirmation mssage - msg:host:defer error string - tls:cert verification chain depth - smtp:connect smtp banner +Visit https://github.com/LMDB/lmdb to download the library or find it in your +operating systems package repository. -The msg:host:defer event populates one extra variable, $event_defer_errno. +If building from source, this description assumes that headers will be in +/usr/local/include, and that the libraries are in /usr/local/lib. -The following variables are likely to be useful depending on the event type: +1. In order to build exim with LMDB lookup support add or uncomment - router_name, transport_name - local_part, domain - host, host_address, host_port - tls_out_peercert - lookup_dnssec_authenticated, tls_out_dane - sending_ip_address, sending_port - message_exim_id, verify_mode +EXPERIMENTAL_LMDB=yes +to your Local/Makefile. (Re-)build/install exim. exim -d should show +Experimental_LMDB in the line "Support for:". -An example might look like: +EXPERIMENTAL_LMDB=yes +LDFLAGS += -llmdb +# CFLAGS += -I/usr/local/include +# LDFLAGS += -L/usr/local/lib -event_action = ${if eq {msg:delivery}{$event_name} \ -{${lookup pgsql {SELECT * FROM record_Delivery( \ - '${quote_pgsql:$sender_address_domain}',\ - '${quote_pgsql:${lc:$sender_address_local_part}}', \ - '${quote_pgsql:$domain}', \ - '${quote_pgsql:${lc:$local_part}}', \ - '${quote_pgsql:$host_address}', \ - '${quote_pgsql:${lc:$host}}', \ - '${quote_pgsql:$message_exim_id}')}} \ -} {}} +The first line sets the feature to include the correct code, and +the second line says to link the LMDB libraries into the +exim binary. The commented out lines should be uncommented if you +built LMDB from source and installed in the default location. +Adjust the paths if you installed them elsewhere, but you do not +need to uncomment them if an rpm (or you) installed them in the +package controlled locations (/usr/include and /usr/lib). -The string is expanded when each of the supported events occur -and any side-effects of the expansion will happen. -Note that for complex operations an ACL expansion can be used. +2. Create your LMDB files, you can use the mdb_load utility which is +part of the LMDB distribution our your favourite language bindings. +3. Add the single key lookups to your exim.conf file, example lookups +are below. -The expansion of the event_action option should normally -return an empty string. Should it return anything else the -following will be forced: +${lookup{$sender_address_domain}lmdb{/var/lib/baruwa/data/db/relaydomains.mdb}{$value}} +${lookup{$sender_address_domain}lmdb{/var/lib/baruwa/data/db/relaydomains.mdb}{$value}fail} +${lookup{$sender_address_domain}lmdb{/var/lib/baruwa/data/db/relaydomains.mdb}} - msg:delivery (ignored) - msg:host:defer (ignored) - msg:fail:delivery (ignored) - tcp:connect do not connect - tcp:close (ignored) - tls:cert refuse verification - smtp:connect close connection -No other use is made of the result string. +Queuefile transport +------------------- +Queuefile is a pseudo transport which does not perform final delivery. +It simply copies the exim spool files out of the spool directory into +an external directory retaining the exim spool format. +The spool files can then be processed by external processes and then +requeued into exim spool directories for final delivery. -Known issues: -- the tls:cert event is only called for the cert chain elements - received over the wire, with GnuTLS. OpenSSL gives the entire - chain including thse loaded locally. +The motivation/inspiration for the transport is to allow external +processes to access email queued by exim and have access to all the +information which would not be available if the messages were delivered +to the process in the standard email formats. +The mailscanner package is one of the processes that can take advantage +of this transport to filter email. -Redis Lookup --------------------------------------------------------------- +The transport can be used in the same way as the other existing transports, +i.e by configuring a router to route mail to a transport configured with +the queuefile driver. -Redis is open source advanced key-value data store. This document -does not explain the fundamentals, you should read and understand how -it works by visiting the website at http://www.redis.io/. +The transport only takes one option: -Redis lookup support is added via the hiredis library. Visit: +* directory - This is used to specify the directory messages should be +copied to - https://github.com/redis/hiredis +The generic transport options (body_only, current_directory, disable_logging, +debug_print, delivery_date_add, envelope_to_add, event_action, group, +headers_add, headers_only, headers_remove, headers_rewrite, home_directory, +initgroups, max_parallel, message_size_limit, rcpt_include_affixes, +retry_use_local_part, return_path, return_path_add, shadow_condition, +shadow_transport, transport_filter, transport_filter_timeout, user) are +ignored. -to obtain a copy, or find it in your operating systems package repository. -If building from source, this description assumes that headers will be in -/usr/local/include, and that the libraries are in /usr/local/lib. +Sample configuration: -1. In order to build exim with Redis lookup support add +(Router) -EXPERIMENTAL_REDIS=yes +scan: + driver = accept + transport = scan -to your Local/Makefile. (Re-)build/install exim. exim -d should show -Experimental_Redis in the line "Support for:". +(Transport) -EXPERIMENTAL_REDIS=yes -LDFLAGS += -lhiredis -# CFLAGS += -I/usr/local/include -# LDFLAGS += -L/usr/local/lib +scan: + driver = queuefile + directory = /var/spool/baruwa-scanner/input -The first line sets the feature to include the correct code, and -the second line says to link the hiredis libraries into the -exim binary. The commented out lines should be uncommented if you -built hiredis from source and installed in the default location. -Adjust the paths if you installed them elsewhere, but you do not -need to uncomment them if an rpm (or you) installed them in the -package controlled locations (/usr/include and /usr/lib). +In order to build exim with Queuefile transport support add or uncomment -2. Use the following global settings to configure Redis lookup support: +EXPERIMENTAL_QUEUEFILE=yes -Required: -redis_servers This option provides a list of Redis servers - and associated connection data, to be used in - conjunction with redis lookups. The option is - only available if Exim is configured with Redis - support. - -For example: +to your Local/Makefile. (Re-)build/install exim. exim -d should show +Experimental_QUEUEFILE in the line "Support for:". -redis_servers = 127.0.0.1/10/ - using database 10 with no password -redis_servers = 127.0.0.1//password - to make use of the default database of 0 with a password -redis_servers = 127.0.0.1// - for default database of 0 with no password -3. Once you have the Redis servers defined you can then make use of the -experimental Redis lookup by specifying ${lookup redis{}} in a lookup query. +ARC support +----------- +Specification: https://tools.ietf.org/html/draft-ietf-dmarc-arc-protocol-11 +Note that this is not an RFC yet, so may change. -4. Example usage: +ARC is intended to support the utility of SPF and DKIM in the presence of +intermediaries in the transmission path - forwarders and mailinglists - +by establishing a cryptographically-signed chain in headers. -(Host List) -hostlist relay_from_ips = <\n ${lookup redis{SMEMBERS relay_from_ips}} +Normally one would only bother doing ARC-signing when functioning as +an intermediary. One might do verify for local destinations. -Where relay_from_ips is a Redis set which contains entries such as "192.168.0.0/24" "10.0.0.0/8" and so on. -The result set is returned as -192.168.0.0/24 -10.0.0.0/8 -.. -. +ARC uses the notion of a "ADministrative Management Domain" (ADMD). +Described in RFC 5598 (section 2.3), this is essentially the set of +mail-handling systems that the mail transits. A label should be chosen to +identify the ADMD. Messages should be ARC-verified on entry to the ADMD, +and ARC-signed on exit from it. -(Domain list) -domainlist virtual_domains = ${lookup redis {HGET $domain domain}} -Where $domain is a hash which includes the key 'domain' and the value '$domain'. +Verification +-- +An ACL condition is provided to perform the "verifier actions" detailed +in section 6 of the above specification. It may be called from the DATA ACL +and succeeds if the result matches any of a given list. +It also records the highest ARC instance number (the chain size) +and verification result for later use in creating an Authentication-Results: +standard header. -(Adding or updating an existing key) -set acl_c_spammer = ${if eq{${lookup redis{SPAMMER_SET}}}{OK}} + verify = arc/ none:fail:pass -Where SPAMMER_SET is a macro and it is defined as + add_header = :at_start:${authresults {}} -"SET SPAMMER " + Note that it would be wise to strip incoming messages of A-R headers + that claim to be from our own . -(Getting a value from Redis) +There are two new variables: $arc_state and $arc_state_reason. -set acl_c_spam_host = ${lookup redis{GET...}} +Receive log lines for an ARC pass will be tagged "ARC". -Proxy Protocol Support --------------------------------------------------------------- +Signing +-- +arc_sign = : : +An option on the smtp transport, which constructs and prepends to the message +an ARC set of headers. The textually-first Authentication-Results: header +is used as a basis (you must have added one on entry to the ADMD). +Expanded; if unset, empty or forced-failure then no signing is done. -Exim now has Experimental "Proxy Protocol" support. It was built on -specifications from: -http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt -Above URL revised May 2014 to change version 2 spec: -http://git.1wt.eu/web?p=haproxy.git;a=commitdiff;h=afb768340c9d7e50d8e - -The purpose of this function is so that an application load balancer, -such as HAProxy, can sit in front of several Exim servers and Exim -will log the IP that is connecting to the proxy server instead of -the IP of the proxy server when it connects to Exim. It resets the -$sender_address_host and $sender_address_port to the IP:port of the -connection to the proxy. It also re-queries the DNS information for -this new IP address so that the original sender's hostname and IP -get logged in the Exim logfile. There is no logging if a host passes or -fails Proxy Protocol negotiation, but it can easily be determined and -recorded in an ACL (example is below). - -1. To compile Exim with Proxy Protocol support, put this in -Local/Makefile: - -EXPERIMENTAL_PROXY=yes - -2. Global configuration settings: - -proxy_required_hosts = HOSTLIST - -The proxy_required_hosts option will require any IP in that hostlist -to use Proxy Protocol. The specification of Proxy Protocol is very -strict, and if proxy negotiation fails, Exim will not allow any SMTP -command other than QUIT. (See end of this section for an example.) -The option is expanded when used, so it can be a hostlist as well as -string of IP addresses. Since it is expanded, specifying an alternate -separator is supported for ease of use with IPv6 addresses. - -To log the IP of the proxy in the incoming logline, add: - log_selector = +proxy - -A default incoming logline (wrapped for appearance) will look like this: - - 2013-11-04 09:25:06 1VdNti-0001OY-1V <= me@example.net - H=mail.example.net [1.2.3.4] P=esmtp S=433 - -With the log selector enabled, an email that was proxied through a -Proxy Protocol server at 192.168.1.2 will look like this: - - 2013-11-04 09:25:06 1VdNti-0001OY-1V <= me@example.net - H=mail.example.net [1.2.3.4] P=esmtp PRX=192.168.1.2 S=433 - -3. In the ACL's the following expansion variables are available. - -proxy_host_address The (internal) src IP of the proxy server - making the connection to the Exim server. -proxy_host_port The (internal) src port the proxy server is - using to connect to the Exim server. -proxy_target_address The dest (public) IP of the remote host to - the proxy server. -proxy_target_port The dest port the remote host is using to - connect to the proxy server. -proxy_session Boolean, yes/no, the connected host is required - to use Proxy Protocol. - -There is no expansion for a failed proxy session, however you can detect -it by checking if $proxy_session is true but $proxy_host is empty. As -an example, in my connect ACL, I have: - - warn condition = ${if and{ {bool{$proxy_session}} \ - {eq{$proxy_host_address}{}} } } - log_message = Failed required proxy protocol negotiation \ - from $sender_host_name [$sender_host_address] - - warn condition = ${if and{ {bool{$proxy_session}} \ - {!eq{$proxy_host_address}{}} } } - # But don't log health probes from the proxy itself - condition = ${if eq{$proxy_host_address}{$sender_host_address} \ - {false}{true}} - log_message = Successfully proxied from $sender_host_name \ - [$sender_host_address] through proxy protocol \ - host $proxy_host_address - - # Possibly more clear - warn logwrite = Remote Source Address: $sender_host_address:$sender_host_port - logwrite = Proxy Target Address: $proxy_target_address:$proxy_target_port - logwrite = Proxy Internal Address: $proxy_host_address:$proxy_host_port - logwrite = Internal Server Address: $received_ip_address:$received_port - - -4. Recommended ACL additions: - - Since the real connections are all coming from your proxy, and the - per host connection tracking is done before Proxy Protocol is - evaluated, smtp_accept_max_per_host must be set high enough to - handle all of the parallel volume you expect per inbound proxy. - - With the smtp_accept_max_per_host set so high, you lose the ability - to protect your server from massive numbers of inbound connections - from one IP. In order to prevent your server from being DOS'd, you - need to add a per connection ratelimit to your connect ACL. I - suggest something like this: - - # Set max number of connections per host - LIMIT = 5 - # 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 - - -5. Runtime issues to be aware of: - - The proxy has 3 seconds (hard-coded in the source code) to send the - required Proxy Protocol header after it connects. If it does not, - the response to any commands will be: - "503 Command refused, required Proxy negotiation failed" - - If the incoming connection is configured in Exim to be a Proxy - Protocol host, but the proxy is not sending the header, the banner - does not get sent until the timeout occurs. If the sending host - sent any input (before the banner), this causes a standard Exim - synchronization error (i.e. trying to pipeline before PIPELINING - was advertised). - - This is not advised, but is mentioned for completeness if you have - a specific internal configuration that you want this: If the Exim - server only has an internal IP address and no other machines in your - organization will connect to it to try to send email, you may - simply set the hostlist to "*", however, this will prevent local - mail programs from working because that would require mail from - localhost to use Proxy Protocol. Again, not advised! - -6. Example of a refused connection because the Proxy Protocol header was -not sent from a host configured to use Proxy Protocol. In the example, -the 3 second timeout occurred (when a Proxy Protocol banner should have -been sent), the banner was displayed to the user, but all commands are -rejected except for QUIT: - -# nc mail.example.net 25 -220-mail.example.net, ESMTP Exim 4.82+proxy, Mon, 04 Nov 2013 10:45:59 -220 -0800 RFC's enforced -EHLO localhost -503 Command refused, required Proxy negotiation failed -QUIT -221 mail.example.net closing connection - - - - -DANE ------------------------------------------------------------- -DNS-based Authentication of Named Entities, as applied -to SMTP over TLS, provides assurance to a client that -it is actually talking to the server it wants to rather -than some attacker operating a Man In The Middle (MITM) -operation. The latter can terminate the TLS connection -you make, and make another one to the server (so both -you and the server still think you have an encrypted -connection) and, if one of the "well known" set of -Certificate Authorities has been suborned - something -which *has* been seen already (2014), a verifiable -certificate (if you're using normal root CAs, eg. the -Mozilla set, as your trust anchors). - -What DANE does is replace the CAs with the DNS as the -trust anchor. The assurance is limited to a) the possibility -that the DNS has been suborned, b) mistakes made by the -admins of the target server. The attack surface presented -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 -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. - -DANE requires a server operator to do three things: -1) run DNSSEC. This provides assurance to clients -that DNS lookups they do for the server have not -been tampered with. The domain MX record applying -to this server, its A record, its TLSA record and -any associated CNAME records must all be covered by -DNSSEC. -2) add TLSA DNS records. These say what the server -certificate for a TLS connection should be. -3) offer a server certificate, or certificate chain, -in TLS connections which is traceable to the one -defined by (one of?) the TSLA records - -There are no changes to Exim specific to server-side -operation of DANE. - -The TLSA record for the server may have "certificate -usage" of DANE-TA(2) or DANE-EE(3). The latter specifies -the End Entity directly, i.e. the certificate involved -is that of the server (and should be the sole one transmitted -during the TLS handshake); this is appropriate for a -single system, using a self-signed certificate. - DANE-TA usage is effectively declaring a specific CA -to be used; this might be a private CA or a public, -well-known one. A private CA at simplest is just -a self-signed certificate which is used to sign -cerver certificates, but running one securely does -require careful arrangement. If a private CA is used -then either all clients must be primed with it, or -(probably simpler) the server TLS handshake must transmit -the entire certificate chain from CA to server-certificate. -If a public CA is used then all clients must be primed with it -(losing one advantage of DANE) - but the attack surface is -reduced from all public CAs to that single CA. -DANE-TA is commonly used for several services and/or -servers, each having a TLSA query-domain CNAME record, -all of which point to a single TLSA record. - -The TLSA record should have a Selector field of SPKI(1) -and a Matching Type field of SHA2-512(2). - -At the time of writing, https://www.huque.com/bin/gen_tlsa -is useful for quickly generating TLSA records; and commands like - - openssl x509 -in -pubkey -noout /dev/null \ - | openssl sha512 \ - | awk '{print $2}' - -are workable for 4th-field hashes. - -For use with the DANE-TA model, server certificates -must have a correct name (SubjectName or SubjectAltName). - -The use of OCSP-stapling should be considered, allowing -for fast revocation of certificates (which would otherwise -be limited by the DNS TTL on the TLSA records). However, -this is likely to only be usable with DANE-TA. NOTE: the -default of requesting OCSP for all hosts is modified iff -DANE is in use, to: - - hosts_request_ocsp = ${if or { {= {0}{$tls_out_tlsa_usage}} \ - {= {4}{$tls_out_tlsa_usage}} } \ - {*}{}} - -The (new) variable $tls_out_tlsa_usage is a bitfield with -numbered bits set for TLSA record usage codes. -The zero above means DANE was not in use, -the four means that only DANE-TA usage TLSA records were -found. If the definition of hosts_request_ocsp includes the -string "tls_out_tlsa_usage", they are re-expanded in time to -control the OCSP request. - -This modification of hosts_request_ocsp is only done if -it has the default value of "*". Admins who change it, and -those who use hosts_require_ocsp, should consider the interaction -with DANE in their OCSP settings. - - -For client-side DANE there are two new smtp transport options, -hosts_try_dane and hosts_require_dane. They do the obvious thing. -[ should they be domain-based rather than host-based? ] - -DANE will only be usable if the target host has DNSSEC-secured -MX, A and TLSA records. - -A TLSA lookup will be done if either of the above options match -and the host-lookup succeded using dnssec. -If a TLSA lookup is done and succeeds, a DANE-verified TLS connection -will be required for the host. - -(TODO: specify when fallback happens vs. when the host is not used) - -If DANE is requested and useable (see above) the following transport -options are ignored: - hosts_require_tls - tls_verify_hosts - tls_try_verify_hosts - tls_verify_certificates - tls_crl - tls_verify_cert_hostnames - -If DANE is not usable, whether requested or not, and CA-anchored -verification evaluation is wanted, the above variables should be set -appropriately. - -Currently dnssec_request_domains must be active (need to think about that) -and dnssec_require_domains is ignored. - -If verification was successful using DANE then the "CV" item -in the delivery log line will show as "CV=dane". - -There is a new variable $tls_out_dane which will have "yes" if -verification succeeded using DANE and "no" otherwise (only useful -in combination with EXPERIMENTAL_EVENT), and a new variable -$tls_out_tlsa_usage (detailed above). --------------------------------------------------------------