mirror of
https://github.com/nginx/nginx.git
synced 2025-06-11 04:12:40 +08:00
Mail: parsing of the PROXY protocol from clients.
Activated with the "proxy_protocol" parameter of the "listen" directive. Obtained information is passed to the auth_http script in Proxy-Protocol-Addr, Proxy-Protocol-Port, Proxy-Protocol-Server-Addr, and Proxy-Protocol-Server-Port headers.
This commit is contained in:
parent
72dcd5141b
commit
1fce224f01
@ -405,6 +405,7 @@ ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
|
|||||||
#if (NGX_MAIL_SSL)
|
#if (NGX_MAIL_SSL)
|
||||||
addrs[i].conf.ssl = addr[i].opt.ssl;
|
addrs[i].conf.ssl = addr[i].opt.ssl;
|
||||||
#endif
|
#endif
|
||||||
|
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||||
addrs[i].conf.addr_text = addr[i].opt.addr_text;
|
addrs[i].conf.addr_text = addr[i].opt.addr_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +440,7 @@ ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
|
|||||||
#if (NGX_MAIL_SSL)
|
#if (NGX_MAIL_SSL)
|
||||||
addrs6[i].conf.ssl = addr[i].opt.ssl;
|
addrs6[i].conf.ssl = addr[i].opt.ssl;
|
||||||
#endif
|
#endif
|
||||||
|
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||||
addrs6[i].conf.addr_text = addr[i].opt.addr_text;
|
addrs6[i].conf.addr_text = addr[i].opt.addr_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ typedef struct {
|
|||||||
unsigned ipv6only:1;
|
unsigned ipv6only:1;
|
||||||
#endif
|
#endif
|
||||||
unsigned so_keepalive:2;
|
unsigned so_keepalive:2;
|
||||||
|
unsigned proxy_protocol:1;
|
||||||
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
||||||
int tcp_keepidle;
|
int tcp_keepidle;
|
||||||
int tcp_keepintvl;
|
int tcp_keepintvl;
|
||||||
@ -55,7 +56,8 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_mail_conf_ctx_t *ctx;
|
ngx_mail_conf_ctx_t *ctx;
|
||||||
ngx_str_t addr_text;
|
ngx_str_t addr_text;
|
||||||
ngx_uint_t ssl; /* unsigned ssl:1; */
|
unsigned ssl:1;
|
||||||
|
unsigned proxy_protocol:1;
|
||||||
} ngx_mail_addr_conf_t;
|
} ngx_mail_addr_conf_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1227,6 +1227,17 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
|||||||
+ ahcf->header.len
|
+ ahcf->header.len
|
||||||
+ sizeof(CRLF) - 1;
|
+ sizeof(CRLF) - 1;
|
||||||
|
|
||||||
|
if (c->proxy_protocol) {
|
||||||
|
len += sizeof("Proxy-Protocol-Addr: ") - 1
|
||||||
|
+ c->proxy_protocol->src_addr.len + sizeof(CRLF) - 1
|
||||||
|
+ sizeof("Proxy-Protocol-Port: ") - 1
|
||||||
|
+ sizeof("65535") - 1 + sizeof(CRLF) - 1
|
||||||
|
+ sizeof("Proxy-Protocol-Server-Addr: ") - 1
|
||||||
|
+ c->proxy_protocol->dst_addr.len + sizeof(CRLF) - 1
|
||||||
|
+ sizeof("Proxy-Protocol-Server-Port: ") - 1
|
||||||
|
+ sizeof("65535") - 1 + sizeof(CRLF) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||||
len += sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len
|
len += sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len
|
||||||
+ sizeof(CRLF) - 1
|
+ sizeof(CRLF) - 1
|
||||||
@ -1314,6 +1325,26 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
|||||||
*b->last++ = CR; *b->last++ = LF;
|
*b->last++ = CR; *b->last++ = LF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->proxy_protocol) {
|
||||||
|
b->last = ngx_cpymem(b->last, "Proxy-Protocol-Addr: ",
|
||||||
|
sizeof("Proxy-Protocol-Addr: ") - 1);
|
||||||
|
b->last = ngx_copy(b->last, c->proxy_protocol->src_addr.data,
|
||||||
|
c->proxy_protocol->src_addr.len);
|
||||||
|
*b->last++ = CR; *b->last++ = LF;
|
||||||
|
|
||||||
|
b->last = ngx_sprintf(b->last, "Proxy-Protocol-Port: %d" CRLF,
|
||||||
|
c->proxy_protocol->src_port);
|
||||||
|
|
||||||
|
b->last = ngx_cpymem(b->last, "Proxy-Protocol-Server-Addr: ",
|
||||||
|
sizeof("Proxy-Protocol-Server-Addr: ") - 1);
|
||||||
|
b->last = ngx_copy(b->last, c->proxy_protocol->dst_addr.data,
|
||||||
|
c->proxy_protocol->dst_addr.len);
|
||||||
|
*b->last++ = CR; *b->last++ = LF;
|
||||||
|
|
||||||
|
b->last = ngx_sprintf(b->last, "Proxy-Protocol-Server-Port: %d" CRLF,
|
||||||
|
c->proxy_protocol->dst_port);
|
||||||
|
}
|
||||||
|
|
||||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||||
|
|
||||||
/* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */
|
/* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */
|
||||||
|
@ -548,6 +548,11 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) {
|
||||||
|
ls->proxy_protocol = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
"the invalid \"%V\" parameter", &value[i]);
|
"the invalid \"%V\" parameter", &value[i]);
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <ngx_mail.h>
|
#include <ngx_mail.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev);
|
||||||
static void ngx_mail_init_session_handler(ngx_event_t *rev);
|
static void ngx_mail_init_session_handler(ngx_event_t *rev);
|
||||||
static void ngx_mail_init_session(ngx_connection_t *c);
|
static void ngx_mail_init_session(ngx_connection_t *c);
|
||||||
|
|
||||||
@ -168,6 +169,22 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
|||||||
rev = c->read;
|
rev = c->read;
|
||||||
rev->handler = ngx_mail_init_session_handler;
|
rev->handler = ngx_mail_init_session_handler;
|
||||||
|
|
||||||
|
if (addr_conf->proxy_protocol) {
|
||||||
|
c->log->action = "reading PROXY protocol";
|
||||||
|
|
||||||
|
rev->handler = ngx_mail_proxy_protocol_handler;
|
||||||
|
|
||||||
|
if (!rev->ready) {
|
||||||
|
ngx_add_timer(rev, cscf->timeout);
|
||||||
|
|
||||||
|
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||||
|
ngx_mail_close_connection(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_use_accept_mutex) {
|
if (ngx_use_accept_mutex) {
|
||||||
ngx_post_event(rev, &ngx_posted_events);
|
ngx_post_event(rev, &ngx_posted_events);
|
||||||
return;
|
return;
|
||||||
@ -177,6 +194,76 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ngx_mail_proxy_protocol_handler(ngx_event_t *rev)
|
||||||
|
{
|
||||||
|
u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
|
||||||
|
size_t size;
|
||||||
|
ssize_t n;
|
||||||
|
ngx_err_t err;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_mail_session_t *s;
|
||||||
|
ngx_mail_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
|
c = rev->data;
|
||||||
|
s = c->data;
|
||||||
|
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
|
"mail PROXY protocol handler");
|
||||||
|
|
||||||
|
if (rev->timedout) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
|
||||||
|
c->timedout = 1;
|
||||||
|
ngx_mail_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK);
|
||||||
|
|
||||||
|
err = ngx_socket_errno;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "recv(): %z", n);
|
||||||
|
|
||||||
|
if (n == -1) {
|
||||||
|
if (err == NGX_EAGAIN) {
|
||||||
|
rev->ready = 0;
|
||||||
|
|
||||||
|
if (!rev->timer_set) {
|
||||||
|
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||||
|
ngx_add_timer(rev, cscf->timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||||
|
ngx_mail_close_connection(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_connection_error(c, err, "recv() failed");
|
||||||
|
|
||||||
|
ngx_mail_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ngx_proxy_protocol_read(c, buf, buf + n);
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
ngx_mail_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = p - buf;
|
||||||
|
|
||||||
|
if (c->recv(c, buf, size) != (ssize_t) size) {
|
||||||
|
ngx_mail_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_mail_init_session_handler(rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_mail_init_session_handler(ngx_event_t *rev)
|
ngx_mail_init_session_handler(ngx_event_t *rev)
|
||||||
{
|
{
|
||||||
@ -242,9 +329,10 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
|
|||||||
|
|
||||||
s = c->data;
|
s = c->data;
|
||||||
|
|
||||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
if (!c->read->timer_set) {
|
||||||
|
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||||
ngx_add_timer(c->read, cscf->timeout);
|
ngx_add_timer(c->read, cscf->timeout);
|
||||||
|
}
|
||||||
|
|
||||||
c->ssl->handler = ngx_mail_ssl_handshake_handler;
|
c->ssl->handler = ngx_mail_ssl_handshake_handler;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user