This commit is contained in:
mdewitt11 2026-02-03 12:43:06 -06:00 committed by GitHub
commit 91e9028a73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 118 additions and 24 deletions

View file

@ -4,7 +4,6 @@
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
@ -12,6 +11,7 @@
#define NGX_PROXY_PROTOCOL_AF_INET 1
#define NGX_PROXY_PROTOCOL_AF_INET6 2
#define NGX_PROXY_PROTOCOL_V2_SIG "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
#define ngx_proxy_protocol_parse_uint16(p) \
( ((uint16_t) (p)[0] << 8) \
@ -321,6 +321,80 @@ ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last)
return ngx_slprintf(buf, last, " %ui %ui" CRLF, port, lport);
}
u_char *
ngx_proxy_protocol_v2_write(ngx_connection_t *c, u_char *buf, u_char *last) {
u_char *buf_ptr = buf;
ngx_uint_t port, lport;
if (last - buf < NGX_PROXY_PROTOCOL_V2_MAX_HEADER) {
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "the buffer is too small for proxy protocol v2");
return NULL;
}
buf_ptr = ngx_cpymem(buf_ptr, NGX_PROXY_PROTOCOL_V2_SIG, 12);
*buf_ptr++ = 0x21;
port = ngx_inet_get_port(c->sockaddr);
lport = ngx_inet_get_port(c->local_sockaddr);
switch (c->sockaddr->sa_family) {
case AF_INET: {
*buf_ptr++ = 0x11;
*buf_ptr++ = 0x00;
*buf_ptr++ = 0x0C;
struct sockaddr_in *sin;
sin = (struct sockaddr_in *) c->sockaddr;
struct sockaddr_in *lsin;
lsin = (struct sockaddr_in *) c->local_sockaddr;
buf_ptr = ngx_cpymem(buf_ptr, &sin->sin_addr.s_addr, 4);
buf_ptr = ngx_cpymem(buf_ptr, &lsin->sin_addr.s_addr, 4);
*buf_ptr++ = (u_char) (port >> 8);
*buf_ptr++ = (u_char) port;
*buf_ptr++ = (u_char) (lport >> 8);
*buf_ptr++ = (u_char) lport;
break;
}
#if (NGX_HAVE_INET6)
case AF_INET6: {
*buf_ptr++ = 0x00;
*buf_ptr++ = 0x24;
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *) c->sockaddr;
struct sockaddr_in6 *lsin6;
lsin6 = (struct sockaddr_in6 *) c->local_sockaddr;
buf_ptr = ngx_cpymem(buf_ptr, &sin6->sin6_addr, 16);
buf_ptr = ngx_cpymem(buf_ptr, &lsin6->sin6_addr, 16);
*buf_ptr++ = (u_char)(port >> 8);
*buf_ptr++ = (u_char) port;
*buf_ptr++ = (u_char)(lport >> 8);
*buf_ptr++ = (u_char) lport;
break;
}
#endif
default: {
*buf_ptr++ = 0x00;
*buf_ptr++ = 0x00;
*buf_ptr++ = 0x00;
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "unsupported address family");
return NULL;
}
}
return buf_ptr;
}
static u_char *
ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last)

View file

@ -4,34 +4,30 @@
* Copyright (C) Nginx, Inc.
*/
#ifndef _NGX_PROXY_PROTOCOL_H_INCLUDED_
#define _NGX_PROXY_PROTOCOL_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
#define NGX_PROXY_PROTOCOL_V1_MAX_HEADER 107
#define NGX_PROXY_PROTOCOL_MAX_HEADER 4096
#define NGX_PROXY_PROTOCOL_V1_MAX_HEADER 107
#define NGX_PROXY_PROTOCOL_V2_MAX_HEADER 64
#define NGX_PROXY_PROTOCOL_MAX_HEADER 4096
struct ngx_proxy_protocol_s {
ngx_str_t src_addr;
ngx_str_t dst_addr;
in_port_t src_port;
in_port_t dst_port;
ngx_str_t tlvs;
ngx_str_t src_addr;
ngx_str_t dst_addr;
in_port_t src_port;
in_port_t dst_port;
ngx_str_t tlvs;
};
u_char *ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf,
u_char *last);
u_char *ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last);
u_char *ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf,
u_char *last);
u_char *last);
u_char *ngx_proxy_protocol_v2_write(ngx_connection_t *c, u_char *buf,
u_char *last);
ngx_int_t ngx_proxy_protocol_get_tlv(ngx_connection_t *c, ngx_str_t *name,
ngx_str_t *value);
ngx_str_t *value);
#endif /* _NGX_PROXY_PROTOCOL_H_INCLUDED_ */

View file

@ -31,6 +31,7 @@ typedef struct {
ngx_uint_t next_upstream_tries;
ngx_flag_t next_upstream;
ngx_flag_t proxy_protocol;
ngx_flag_t protocol_version;
ngx_flag_t half_close;
ngx_stream_upstream_local_t *local;
ngx_flag_t socket_keepalive;
@ -253,6 +254,13 @@ static ngx_command_t ngx_stream_proxy_commands[] = {
offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
NULL },
{ ngx_string("proxy_protocol_version"),
NGX_STREAM_MAIN_CONF | NGX_STREAM_SRV_CONF | NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_STREAM_SRV_CONF_OFFSET,
offsetof(ngx_stream_proxy_srv_conf_t, protocol_version),
NULL},
{ ngx_string("proxy_half_close"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@ -927,7 +935,11 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
return;
}
p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
if (pscf->proxy_protocol == 2){
p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V2_MAX_HEADER);
} else{
p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
}
if (p == NULL) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
@ -935,8 +947,13 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
cl->buf->pos = p;
p = ngx_proxy_protocol_write(c, p,
p + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
if (pscf->protocol_version == 2) {
p = ngx_proxy_protocol_v2_write(c, p,
p + NGX_PROXY_PROTOCOL_V2_MAX_HEADER);
} else {
p = ngx_proxy_protocol_write(c, p,
p + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
}
if (p == NULL) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
@ -969,7 +986,6 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
ngx_stream_proxy_process(s, 0, 1);
}
#if (NGX_STREAM_SSL)
static ngx_int_t
@ -986,9 +1002,16 @@ ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
"stream proxy send PROXY protocol header");
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
p = ngx_proxy_protocol_write(c, buf,
buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
if (pscf->protocol_version == 2) {
p = ngx_proxy_protocol_v2_write(c, buf,
buf + NGX_PROXY_PROTOCOL_V2_MAX_HEADER);
} else {
p = ngx_proxy_protocol_write(c, buf,
buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
if (p == NULL) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
@ -2216,6 +2239,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->next_upstream = NGX_CONF_UNSET;
conf->proxy_protocol = NGX_CONF_UNSET;
conf->protocol_version = NGX_CONF_UNSET_UINT;
conf->local = NGX_CONF_UNSET_PTR;
conf->socket_keepalive = NGX_CONF_UNSET;
conf->half_close = NGX_CONF_UNSET;