Attached is a patch that configurably enables smtp to send a v1 PROXY
protocol string before HELO.

We have a specific use case where want postfix to be able to specify the
sending IP to use to our network edges, and PROXY protocol seemed ideal for
this.  We can just override the "source" ip to use in the protocol
string, and the edge proxy/firewall can SNAT using the provided IP.  I
realize this is kind of an esoteric use case for PROXY protocol, but
figured I'd submit the patch for some eyes even if its not considered
for merging upstream.  I would appreciate any input on if I'm doing 
something very wrong or stupid.

Thanks, Matthew


diff -rupN postfix-3.3-20170218/src/global/mail_params.h 
postfix-3.3-20170218-via/src/global/mail_params.h
--- postfix-3.3-20170218/src/global/mail_params.h       2017-02-18 
20:58:20.000000000 -0500
+++ postfix-3.3-20170218-via/src/global/mail_params.h   2017-05-05 
10:55:52.123154188 -0400
@@ -1594,6 +1594,37 @@ extern bool var_smtp_tls_force_tlsa;
 #define DEF_SMTP_TLS_INSECURE_MX_POLICY "dane"
 extern char *var_smtp_tls_insecure_mx_policy;

+ /* PROXY protocol support, for outbound smtp */
+#define VAR_SMTP_PROXY_ENABLED "smtp_proxy_protocol_enabled"
+#define DEF_SMTP_PROXY_ENABLED 0
+#define VAR_LMTP_PROXY_ENABLED "lmtp_proxy_protocol_enabled"
+#define DEF_LMTP_PROXY_ENABLED 0
+extern bool var_smtp_proxy_enabled;
+
+#define VAR_SMTP_PROXY_SRC_IP "smtp_proxy_protocol_src_ip"
+#define DEF_SMTP_PROXY_SRC_IP ""
+#define VAR_LMTP_PROXY_SRC_IP "lmtp_proxy_protocol_src_ip"
+#define DEF_LMTP_PROXY_SRC_IP ""
+extern char *var_smtp_proxy_src_ip;
+
+#define VAR_SMTP_PROXY_SRC_PORT "smtp_proxy_protocol_src_port"
+#define DEF_SMTP_PROXY_SRC_PORT 0
+#define VAR_LMTP_PROXY_SRC_PORT "lmtp_proxy_protocol_src_port"
+#define DEF_LMTP_PROXY_SRC_PORT 0
+extern int var_smtp_proxy_src_port;
+
+#define VAR_SMTP_PROXY_DEST_IP "smtp_proxy_protocol_dest_ip"
+#define DEF_SMTP_PROXY_DEST_IP ""
+#define VAR_LMTP_PROXY_DEST_IP "lmtp_proxy_protocol_dest_ip"
+#define DEF_LMTP_PROXY_DEST_IP ""
+extern char *var_smtp_proxy_dest_ip;
+
+#define VAR_SMTP_PROXY_DEST_PORT "smtp_proxy_protocol_dest_port"
+#define DEF_SMTP_PROXY_DEST_PORT 0
+#define VAR_LMTP_PROXY_DEST_PORT "lmtp_proxy_protocol_dest_port"
+#define DEF_LMTP_PROXY_DEST_PORT 0
+extern int var_smtp_proxy_dest_port;
+
  /*
   * SASL authentication support, SMTP server side.
   */
diff -rupN postfix-3.3-20170218/src/smtp/lmtp_params.c 
postfix-3.3-20170218-via/src/smtp/lmtp_params.c
--- postfix-3.3-20170218/src/smtp/lmtp_params.c 2016-10-08 09:44:25.000000000 
-0400
+++ postfix-3.3-20170218-via/src/smtp/lmtp_params.c     2017-05-05 
09:44:27.416097856 -0400
@@ -32,6 +32,10 @@
 #endif
        VAR_LMTP_SASL_MECHS, DEF_LMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
        VAR_LMTP_SASL_TYPE, DEF_LMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
+#ifdef USE_PROXY_PROTO
+       VAR_LMTP_PROXY_DEST_IP, DEF_LMTP_PROXY_DEST_IP, 
&var_smtp_proxy_dest_ip, 0, 0,
+       VAR_LMTP_PROXY_SRC_IP, DEF_LMTP_PROXY_SRC_IP, &var_smtp_proxy_src_ip, 
0, 0,
+#endif
        VAR_LMTP_BIND_ADDR, DEF_LMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
        VAR_LMTP_BIND_ADDR6, DEF_LMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
        VAR_LMTP_VRFY_TGT, DEF_LMTP_VRFY_TGT, &var_smtp_vrfy_tgt, 1, 0,
@@ -92,6 +96,10 @@
        VAR_LMTP_MXADDR_LIMIT, DEF_LMTP_MXADDR_LIMIT, &var_smtp_mxaddr_limit, 
0, 0,
        VAR_LMTP_MXSESS_LIMIT, DEF_LMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 
0, 0,
        VAR_LMTP_REUSE_COUNT, DEF_LMTP_REUSE_COUNT, &var_smtp_reuse_count, 0, 0,
+#ifdef USE_PROXY_PROTO
+       VAR_LMTP_PROXY_DEST_PORT, DEF_LMTP_PROXY_DEST_PORT, 
&var_smtp_proxy_dest_port, 0, 0,
+       VAR_LMTP_PROXY_SRC_PORT, DEF_LMTP_PROXY_SRC_PORT, 
&var_smtp_proxy_src_port, 0, 0,
+#endif
 #ifdef USE_TLS
        VAR_LMTP_TLS_SCERT_VD, DEF_LMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 
0, 0,
 #endif
@@ -101,6 +109,9 @@
        VAR_LMTP_SKIP_5XX, DEF_LMTP_SKIP_5XX, &var_smtp_skip_5xx_greeting,
        VAR_LMTP_SKIP_QUIT_RESP, DEF_LMTP_SKIP_QUIT_RESP, &var_skip_quit_resp,
        VAR_LMTP_SASL_ENABLE, DEF_LMTP_SASL_ENABLE, &var_smtp_sasl_enable,
+#ifdef USE_PROXY_PROTO
+       VAR_LMTP_PROXY_ENABLED, DEF_LMTP_PROXY_ENABLED, &var_smtp_proxy_enabled,
+#endif
        VAR_LMTP_RAND_ADDR, DEF_LMTP_RAND_ADDR, &var_smtp_rand_addr,
        VAR_LMTP_QUOTE_821_ENV, DEF_LMTP_QUOTE_821_ENV, &var_smtp_quote_821_env,
        VAR_LMTP_DEFER_MXADDR, DEF_LMTP_DEFER_MXADDR, &var_smtp_defer_mxaddr,
diff -rupN postfix-3.3-20170218/src/smtp/smtp.c 
postfix-3.3-20170218-via/src/smtp/smtp.c
--- postfix-3.3-20170218/src/smtp/smtp.c        2016-12-04 14:50:52.000000000 
-0500
+++ postfix-3.3-20170218-via/src/smtp/smtp.c    2017-05-04 16:51:48.799440505 
-0400
@@ -847,6 +847,11 @@ char   *var_smtp_sasl_passwd;
 bool    var_smtp_sasl_enable;
 char   *var_smtp_sasl_mechs;
 char   *var_smtp_sasl_type;
+bool    var_smtp_proxy_enabled;
+char   *var_smtp_proxy_src_ip;
+char   *var_smtp_proxy_dest_ip;
+int    var_smtp_proxy_src_port;
+int    var_smtp_proxy_dest_port;
 char   *var_smtp_bind_addr;
 char   *var_smtp_bind_addr6;
 char   *var_smtp_vrfy_tgt;
diff -rupN postfix-3.3-20170218/src/smtp/smtp_connect.c 
postfix-3.3-20170218-via/src/smtp/smtp_connect.c
--- postfix-3.3-20170218/src/smtp/smtp_connect.c        2016-10-08 
09:36:04.000000000 -0400
+++ postfix-3.3-20170218-via/src/smtp/smtp_connect.c    2017-05-05 
11:47:29.189846705 -0400
@@ -322,6 +322,51 @@ static SMTP_SESSION *smtp_connect_sock(i
     /*
      * Bundle up what we have into a nice SMTP_SESSION object.
      */
+#ifdef USE_PROXY_PROTO
+    if (var_smtp_proxy_enabled) {
+        const char *srcip;
+        unsigned srcport;
+        char ntopbuf[INET6_ADDRSTRLEN];
+
+        const char *proto = sa->sa_family == AF_INET6 ? "TCP6" :
+                            sa->sa_family == AF_INET ? "TCP4" :
+                            "UNKNOWN";
+        if (strcmp(var_smtp_proxy_src_ip, "")) {
+            srcip = var_smtp_proxy_src_ip;
+        } else {
+            if (sa->sa_family == AF_INET) {
+                inet_ntop(sa->sa_family, &((struct sockaddr_in *)sa)->sin_addr,
+                          ntopbuf, INET6_ADDRSTRLEN);
+            } else if (sa->sa_family == AF_INET6) {
+                inet_ntop(sa->sa_family, &((struct sockaddr_in6 
*)sa)->sin6_addr,
+                          ntopbuf, INET6_ADDRSTRLEN);
+            } else {
+                strcpy(ntopbuf, "UNKNOWN");
+            }
+            srcip = ntopbuf;
+        }
+
+        if (var_smtp_proxy_src_port) {
+            srcport = var_smtp_proxy_src_port;
+        } else {
+            if (sa->sa_family == AF_INET) {
+                srcport = ntohs(((struct sockaddr_in*)sa)->sin_port);
+            } else if (sa->sa_family == AF_INET6) {
+                srcport = ntohs(((struct sockaddr_in6*)sa)->sin6_port);
+            } else srcport = 0xFFFF;
+        }
+
+        const char *destip = strcmp(var_smtp_proxy_dest_ip, "") ?
+                                    var_smtp_proxy_dest_ip : addr;
+        unsigned destport = var_smtp_proxy_dest_port ?
+                            var_smtp_proxy_dest_port : ntohs(port);
+
+        vstream_fprintf(stream, "PROXY %s %s %s %d %d\r\n",
+                        proto, srcip, destip, srcport, destport);
+        vstream_fflush(stream);
+    }
+#endif
+
     return (smtp_session_alloc(stream, iter, start_time, sess_flags));
 }

diff -rupN postfix-3.3-20170218/src/smtp/smtp_params.c 
postfix-3.3-20170218-via/src/smtp/smtp_params.c
--- postfix-3.3-20170218/src/smtp/smtp_params.c 2016-10-08 09:36:04.000000000 
-0400
+++ postfix-3.3-20170218-via/src/smtp/smtp_params.c     2017-05-05 
09:43:35.333020070 -0400
@@ -33,6 +33,10 @@
 #endif
        VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
        VAR_SMTP_SASL_TYPE, DEF_SMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
+#ifdef USE_PROXY_PROTO
+       VAR_SMTP_PROXY_DEST_IP, DEF_SMTP_PROXY_DEST_IP, 
&var_smtp_proxy_dest_ip, 0, 0,
+       VAR_SMTP_PROXY_SRC_IP, DEF_SMTP_PROXY_SRC_IP, &var_smtp_proxy_src_ip, 
0, 0,
+#endif
        VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
        VAR_SMTP_BIND_ADDR6, DEF_SMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
        VAR_SMTP_VRFY_TGT, DEF_SMTP_VRFY_TGT, &var_smtp_vrfy_tgt, 1, 0,
@@ -93,6 +97,10 @@
        VAR_SMTP_MXADDR_LIMIT, DEF_SMTP_MXADDR_LIMIT, &var_smtp_mxaddr_limit, 
0, 0,
        VAR_SMTP_MXSESS_LIMIT, DEF_SMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 
0, 0,
        VAR_SMTP_REUSE_COUNT, DEF_SMTP_REUSE_COUNT, &var_smtp_reuse_count, 0, 0,
+#ifdef USE_PROXY_PROTO
+       VAR_SMTP_PROXY_DEST_PORT, DEF_SMTP_PROXY_DEST_PORT, 
&var_smtp_proxy_dest_port, 0, 0,
+       VAR_SMTP_PROXY_SRC_PORT, DEF_SMTP_PROXY_SRC_PORT, 
&var_smtp_proxy_src_port, 0, 0,
+#endif
 #ifdef USE_TLS
        VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 
0, 0,
 #endif
@@ -105,6 +113,9 @@
        VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
        VAR_SMTP_NEVER_EHLO, DEF_SMTP_NEVER_EHLO, &var_smtp_never_ehlo,
        VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
+#ifdef USE_PROXY_PROTO
+       VAR_SMTP_PROXY_ENABLED, DEF_SMTP_PROXY_ENABLED, &var_smtp_proxy_enabled,
+#endif
        VAR_SMTP_RAND_ADDR, DEF_SMTP_RAND_ADDR, &var_smtp_rand_addr,
        VAR_SMTP_QUOTE_821_ENV, DEF_SMTP_QUOTE_821_ENV, &var_smtp_quote_821_env,
        VAR_SMTP_DEFER_MXADDR, DEF_SMTP_DEFER_MXADDR, &var_smtp_defer_mxaddr,


Reply via email to