From 4c7f095f4f32a2259017fa5acab6b1278af9e702 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 4 Oct 2020 12:22:01 +0200 Subject: [PATCH] Add proxy_protocol_timeout main config option. --- doc/doc-docbook/spec.xfpt | 12 +++++++++++- doc/doc-txt/NewStuff | 3 +++ src/src/globals.c | 1 + src/src/globals.h | 1 + src/src/macros.h | 9 +-------- src/src/readconf.c | 3 +++ src/src/smtp_in.c | 2 +- test/confs/4030 | 2 ++ test/scripts/4030-proxy-protocol/4030 | 14 +++++++++++--- test/scripts/4030-proxy-protocol/4031 | 6 ++++++ test/stderr/4030 | 10 ++++++++++ test/stderr/4031 | 16 +++++++++++++--- test/stdout/4030 | 20 ++++++++++++++++++++ test/stdout/4031 | 10 ++++++++++ 14 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 test/stderr/4030 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index d0c3e7846..31c8c5653 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -14680,6 +14680,7 @@ listed in more than one group. .row &%local_scan_timeout%& "timeout for &[local_scan()]&" .row &%message_size_limit%& "for all messages" .row &%percent_hack_domains%& "recognize %-hack for these domains" +.row &%proxy_protocol_timeout%& "timeout for proxy protocol negotiation" .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$&" @@ -17017,6 +17018,14 @@ admin user unless &%prod_requires_admin%& is set false. See also &%queue_list_requires_admin%& and &%commandline_checks_require_admin%&. +.new +.option proxy_protocol_timeout main time 3s +.cindex proxy "proxy protocol" +This option sets the timeout for proxy protocol negotiation. +For details see section &<>&. +.wen + + .option qualify_domain main string "see below" .cindex "domain" "for qualifying addresses" .cindex "address" "qualification" @@ -41929,7 +41938,8 @@ automatically determines which version is in use. The Proxy Protocol header is the first data received on a TCP connection and is inserted before any TLS-on-connect handshake from the client; Exim negotiates TLS between Exim-as-server and the remote client, not between -Exim and the proxy server. +Exim and the proxy server. The Proxy Protocol header must be received +within &%proxy_protocol_timeout%&, which defaults to 3s. The following expansion variables are usable (&"internal"& and &"external"& here refer to the interfaces diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index acbbc15fd..cd1699dc6 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -43,6 +43,9 @@ Version 4.95 than the provious behaviour of always loading at startup time for every connection. This helps particularly for the CA bundle. +12. Proxy Protocol Timeout is configurable via "proxy_protocol_timeout" + main config option. + Version 4.94 ------------ diff --git a/src/src/globals.c b/src/src/globals.c index 240c2eb80..d029f7540 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1204,6 +1204,7 @@ uschar *proxy_external_address = NULL; int proxy_external_port = 0; uschar *proxy_local_address = NULL; int proxy_local_port = 0; +int proxy_protocol_timeout = 3; #endif uschar *prvscheck_address = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 8fbb14136..41705fb4b 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -788,6 +788,7 @@ extern uschar *proxy_external_address; /* IP of remote interface of proxy */ extern int proxy_external_port; /* Port on remote interface of proxy */ extern uschar *proxy_local_address; /* IP of local interface of proxy */ extern int proxy_local_port; /* Port on local interface of proxy */ +extern int proxy_protocol_timeout; /* Timeout for proxy negotiation */ extern BOOL proxy_session; /* TRUE if receiving mail from valid proxy */ #endif diff --git a/src/src/macros.h b/src/src/macros.h index c3f1c5d43..62b6290eb 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -196,13 +196,6 @@ record. */ #define WAIT_NAME_MAX 50 -/* Wait this long before determining that a Proxy Protocol configured -host isn't speaking the protocol, and so is disallowed. Can be moved to -runtime configuration if per site settings become needed. */ -#ifdef SUPPORT_PROXY -#define PROXY_NEGOTIATION_TIMEOUT_SEC 3 -#endif - /* Fixed option values for all PCRE functions */ #define PCRE_COPT 0 /* compile */ @@ -887,7 +880,7 @@ enum { /* Options for smtp_write_command */ -enum { +enum { SCMD_FLUSH = 0, /* write to kernel */ SCMD_MORE, /* write to kernel, but likely more soon */ SCMD_BUFFER /* stash in application cmd output buffer */ diff --git a/src/src/readconf.c b/src/src/readconf.c index dabe86348..0b78a88b9 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -259,6 +259,9 @@ static optionlist optionlist_config[] = { { "print_topbitchars", opt_bool, {&print_topbitchars} }, { "process_log_path", opt_stringptr, {&process_log_path} }, { "prod_requires_admin", opt_bool, {&prod_requires_admin} }, +#ifdef SUPPORT_PROXY + { "proxy_protocol_timeout", opt_time, {&proxy_protocol_timeout} }, +#endif { "qualify_domain", opt_stringptr, {&qualify_domain_sender} }, { "qualify_recipient", opt_stringptr, {&qualify_domain_recipient} }, { "queue_domains", opt_stringptr, {&queue_domains} }, diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 69eae3cb4..da6d23602 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -1219,7 +1219,7 @@ socklen_t vslen = sizeof(struct timeval); BOOL yield = FALSE; os_non_restarting_signal(SIGALRM, command_timeout_handler); -ALARM(PROXY_NEGOTIATION_TIMEOUT_SEC); +ALARM(proxy_protocol_timeout); do { diff --git a/test/confs/4030 b/test/confs/4030 index e64859769..86bf6b31c 100644 --- a/test/confs/4030 +++ b/test/confs/4030 @@ -5,6 +5,8 @@ primary_hostname = myhost.test.ex hosts_proxy = HOSTIPV4 +# default timeout is 3s, speed up the timeout test here +proxy_protocol_timeout = 1s queue_only # ----- Main settings ----- diff --git a/test/scripts/4030-proxy-protocol/4030 b/test/scripts/4030-proxy-protocol/4030 index 1eece1112..868a2581c 100644 --- a/test/scripts/4030-proxy-protocol/4030 +++ b/test/scripts/4030-proxy-protocol/4030 @@ -5,7 +5,7 @@ munge loopback exim -bd -DSERVER=server -oX PORT_D **** # -# non-prox plain receive +### non-prox plain receive client 127.0.0.1 PORT_D ??? 220 HELO clientname @@ -25,7 +25,7 @@ QUIT ??? 221 **** # -# protocol v1 plain receive +### protocol v1 plain receive client HOSTIPV4 PORT_D PROXY TCP4 127.0.0.2 127.42.42.42 64000 25 ??? 220 @@ -48,7 +48,7 @@ QUIT # # # -# protocol v2 plain receive +### protocol v2 plain receive client HOSTIPV4 PORT_D >>> \x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21\x11\x00\x0c\x7f\x00\x00\x02\x7f\x2a\x2a\x2a\xc2\x95\x04\x01 ??? 220 @@ -71,5 +71,13 @@ QUIT # # # +### proxy timeout +client HOSTIPV4 PORT_D +??? 220 +PROXY TCP4 127.0.0.2 127.42.42.42 64000 25 +??? 503 +QUIT +??? 221 +**** killdaemon no_msglog_check diff --git a/test/scripts/4030-proxy-protocol/4031 b/test/scripts/4030-proxy-protocol/4031 index f3d2456ec..55e8ba806 100644 --- a/test/scripts/4030-proxy-protocol/4031 +++ b/test/scripts/4030-proxy-protocol/4031 @@ -38,3 +38,9 @@ body v2 . QUIT **** +### proxy timeout +exim -bh HOSTIPV4 +:sleep:3 +PROXY TCP4 127.0.0.2 127.42.42.42 64000 25 +QUIT +**** diff --git a/test/stderr/4030 b/test/stderr/4030 new file mode 100644 index 000000000..00cf8eabc --- /dev/null +++ b/test/stderr/4030 @@ -0,0 +1,10 @@ +### non-prox plain receive +### protocol v1 plain receive +### protocol v2 plain receive +### proxy timeout + +******** SERVER ******** +### non-prox plain receive +### protocol v1 plain receive +### protocol v2 plain receive +### proxy timeout diff --git a/test/stderr/4031 b/test/stderr/4031 index c5336cb25..b0d6a4aaf 100644 --- a/test/stderr/4031 +++ b/test/stderr/4031 @@ -9,7 +9,7 @@ >>> host in helo_accept_junk_hosts? no (option unset) >>> clientname in helo_lookup_domains? no (end of list) >>> using ACL "r_acl" ->>> processing "accept" (TESTSUITE/test-config 20) +>>> processing "accept" (TESTSUITE/test-config 22) >>> check logwrite = proxy session: $proxy_session >>> = proxy session: no LOG: proxy session: no @@ -42,7 +42,7 @@ LOG: 10HmaX-0005vi-00 <= a@test.ex H=(clientname) [127.0.0.2] P=smtp S=sss LOG: no host name found for IP address 127.0.0.2 >>> clientname in helo_lookup_domains? no (end of list) >>> using ACL "r_acl" ->>> processing "accept" (TESTSUITE/test-config 20) +>>> processing "accept" (TESTSUITE/test-config 22) >>> check logwrite = proxy session: $proxy_session >>> = proxy session: yes LOG: proxy session: yes @@ -75,7 +75,7 @@ LOG: 10HmaY-0005vi-00 <= a@test.ex H=(clientname) [127.0.0.2]:1113 P=smtp PRX=ip LOG: no host name found for IP address 127.0.0.2 >>> clientname in helo_lookup_domains? no (end of list) >>> using ACL "r_acl" ->>> processing "accept" (TESTSUITE/test-config 20) +>>> processing "accept" (TESTSUITE/test-config 22) >>> check logwrite = proxy session: $proxy_session >>> = proxy session: yes LOG: proxy session: yes @@ -95,8 +95,18 @@ LOG: remote [127.0.0.2]:1115 >>> end of ACL "r_acl": ACCEPT >>> host in ignore_fromline_hosts? no (option unset) LOG: 10HmaZ-0005vi-00 <= a@test.ex H=(clientname) [127.0.0.2]:1115 P=smtp PRX=ip4.ip4.ip4.ip4 S=sss +### proxy timeout +>>> host in hosts_connection_nolog? no (option unset) +>>> host in host_lookup? no (option unset) +>>> host in host_reject_connection? no (option unset) +>>> host in sender_unqualified_hosts? no (option unset) +>>> host in recipient_unqualified_hosts? no (option unset) +>>> host in helo_verify_hosts? no (option unset) +>>> host in helo_try_verify_hosts? no (option unset) +>>> host in helo_accept_junk_hosts? no (option unset) ******** SERVER ******** ### non-prox plain receive ### protocol v1 receive ### protocol v2 receive +### proxy timeout diff --git a/test/stdout/4030 b/test/stdout/4030 index c37aaa963..d6dcda718 100644 --- a/test/stdout/4030 +++ b/test/stdout/4030 @@ -1,3 +1,4 @@ +### non-prox plain receive Connecting to 127.0.0.1 port 1225 ... connected ??? 220 <<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 @@ -23,6 +24,7 @@ Connecting to 127.0.0.1 port 1225 ... connected ??? 221 <<< 221 myhost.test.ex closing connection End of script +### protocol v1 plain receive Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected >>> PROXY TCP4 127.0.0.2 127.42.42.42 64000 25 ??? 220 @@ -49,6 +51,7 @@ Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected ??? 221 <<< 221 myhost.test.ex closing connection End of script +### protocol v2 plain receive Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected >>> \x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21\x11\x00\x0c\x7f\x00\x00\x02\x7f\x2a\x2a\x2a\xc2\x95\x04\x01 ??? 220 @@ -75,3 +78,20 @@ Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected ??? 221 <<< 221 myhost.test.ex closing connection End of script +### proxy timeout +Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> PROXY TCP4 127.0.0.2 127.42.42.42 64000 25 +??? 503 +<<< 503 Command refused, required Proxy negotiation failed +>>> QUIT +??? 221 +<<< 221 myhost.test.ex closing connection +End of script + +******** SERVER ******** +### non-prox plain receive +### protocol v1 plain receive +### protocol v2 plain receive +### proxy timeout diff --git a/test/stdout/4031 b/test/stdout/4031 index a0cddc62d..d53009cc1 100644 --- a/test/stdout/4031 +++ b/test/stdout/4031 @@ -45,9 +45,19 @@ **** SMTP testing: that is not a real message id! +221 myhost.test.ex closing connection +### proxy timeout + +**** SMTP testing session as if from host ip4.ip4.ip4.ip4 +**** but without any ident (RFC 1413) callback. +**** This is not for real! + +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +503 Command refused, required Proxy negotiation failed 221 myhost.test.ex closing connection ******** SERVER ******** ### non-prox plain receive ### protocol v1 receive ### protocol v2 receive +### proxy timeout -- 2.30.2