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,