[PATCH]add proxy_protocol_port variable for rfc6302
junpei yoshino
junpei.yoshino at gmail.com
Mon Apr 18 15:47:36 UTC 2016
Hello,
Is there any problem or comment?
Best Regards,
Junpei Yoshino
On Tue, Apr 5, 2016 at 9:50 AM, junpei yoshino <junpei.yoshino at gmail.com> wrote:
> Hello!
>
> Thank you for your comment.
>
> I rewrote patch in way 3.
>
> Best Regards,
> Junpei Yoshino
>
> # HG changeset patch
> # User Junpei Yoshino <junpei.yoshino at gmail.com>
> # Date 1459816952 -32400
> # Tue Apr 05 09:42:32 2016 +0900
> # Node ID cdaf19070ed1687a4f942936a0e7339355b98bfa
> # Parent 8426275a13fdfac6dfe6955b7b3e999430eb373d
> Http: add proxy_protocol_port variable for rfc6302 & support in realip module
>
>
> real_port_header is not needed if "real_ip_header proxy_protocol" configured.
> replace remote_port with request header if you set real_port_header.
>
> diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_connection.h
> --- a/src/core/ngx_connection.h Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/core/ngx_connection.h Tue Apr 05 09:42:32 2016 +0900
> @@ -147,8 +147,10 @@
> struct sockaddr *sockaddr;
> socklen_t socklen;
> ngx_str_t addr_text;
> + ngx_uint_t port;
>
> ngx_str_t proxy_protocol_addr;
> + ngx_int_t proxy_protocol_port;
>
> #if (NGX_SSL)
> ngx_ssl_connection_t *ssl;
> diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_inet.c
> --- a/src/core/ngx_inet.c Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/core/ngx_inet.c Tue Apr 05 09:42:32 2016 +0900
> @@ -256,6 +256,38 @@
> }
>
>
> +ngx_uint_t
> +ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen)
> +{
> + struct sockaddr_in *sin;
> +#if (NGX_HAVE_INET6)
> + struct sockaddr_in6 *sin6;
> +#endif
> +
> + switch (sa->sa_family) {
> +
> + case AF_INET:
> + sin = (struct sockaddr_in *) sa;
> + return ntohs(sin->sin_port);
> + break;
> +
> +#if (NGX_HAVE_INET6)
> +
> + case AF_INET6:
> +
> + sin6 = (struct sockaddr_in6 *) sa;
> +
> + return ntohs(sin6->sin6_port);
> +
> + break;
> +#endif
> +
> + default:
> + return 0;
> + }
> +}
> +
> +
> size_t
> ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
> {
> diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_inet.h
> --- a/src/core/ngx_inet.h Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/core/ngx_inet.h Tue Apr 05 09:42:32 2016 +0900
> @@ -109,6 +109,7 @@
> #endif
> size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text,
> size_t len, ngx_uint_t port);
> +ngx_uint_t ngx_sock_get_port(struct sockaddr *sa, socklen_t socklen);
> size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
> ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
> ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
> diff -r 8426275a13fd -r cdaf19070ed1 src/core/ngx_proxy_protocol.c
> --- a/src/core/ngx_proxy_protocol.c Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/core/ngx_proxy_protocol.c Tue Apr 05 09:42:32 2016 +0900
> @@ -13,7 +13,7 @@
> ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
> {
> size_t len;
> - u_char ch, *p, *addr;
> + u_char ch, *p, *addr, *port;
>
> p = buf;
> len = last - buf;
> @@ -71,8 +71,40 @@
> ngx_memcpy(c->proxy_protocol_addr.data, addr, len);
> c->proxy_protocol_addr.len = len;
>
> - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
> - "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr);
> + for ( ;; ) {
> + if (p == last) {
> + goto invalid;
> + }
> +
> + ch = *p++;
> +
> + if (ch == ' ') {
> + break;
> + }
> + }
> + port = p;
> + for ( ;; ) {
> + if (p == last) {
> + goto invalid;
> + }
> +
> + ch = *p++;
> +
> + if (ch == ' ') {
> + break;
> + }
> +
> + if (ch < '0' || ch > '9')
> + {
> + goto invalid;
> + }
> + }
> + len = p - port - 1;
> + c->proxy_protocol_port = ngx_atoi(port,len);
> +
> + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
> + "PROXY protocol address: \"%V\", PROXY protocol
> port: \"%d\"",
> + &c->proxy_protocol_addr, c->proxy_protocol_port);
>
> skip:
>
> diff -r 8426275a13fd -r cdaf19070ed1 src/event/ngx_event_accept.c
> --- a/src/event/ngx_event_accept.c Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/event/ngx_event_accept.c Tue Apr 05 09:42:32 2016 +0900
> @@ -278,6 +278,7 @@
> ngx_close_accepted_connection(c);
> return;
> }
> + c->port = ngx_sock_get_port(c->sockaddr, c->socklen);
> }
>
> #if (NGX_DEBUG)
> diff -r 8426275a13fd -r cdaf19070ed1 src/http/modules/ngx_http_realip_module.c
> --- a/src/http/modules/ngx_http_realip_module.c Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/http/modules/ngx_http_realip_module.c Tue Apr 05 09:42:32 2016 +0900
> @@ -15,6 +15,8 @@
> #define NGX_HTTP_REALIP_HEADER 2
> #define NGX_HTTP_REALIP_PROXY 3
>
> +#define NGX_HTTP_REALPORT_PROXY 1
> +#define NGX_HTTP_REALPORT_HEADER 2
>
> typedef struct {
> ngx_array_t *from; /* array of ngx_cidr_t */
> @@ -22,6 +24,9 @@
> ngx_uint_t hash;
> ngx_str_t header;
> ngx_flag_t recursive;
> + ngx_uint_t porttype;
> + ngx_uint_t porthash;
> + ngx_str_t portheader;
> } ngx_http_realip_loc_conf_t;
>
>
> @@ -30,16 +35,18 @@
> struct sockaddr *sockaddr;
> socklen_t socklen;
> ngx_str_t addr_text;
> + ngx_uint_t port;
> } ngx_http_realip_ctx_t;
>
>
> static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r);
> static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r,
> - ngx_addr_t *addr);
> + ngx_addr_t *addr, ngx_uint_t port);
> static void ngx_http_realip_cleanup(void *data);
> static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
> void *conf);
> static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
> +static char *ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd,
> void *conf);
> static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf);
> static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf,
> void *parent, void *child);
> @@ -49,6 +56,8 @@
>
> static ngx_int_t ngx_http_realip_remote_addr_variable(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> +static ngx_int_t ngx_http_realip_remote_port_variable(ngx_http_request_t *r,
> + ngx_http_variable_value_t *v, uintptr_t data);
>
>
> static ngx_command_t ngx_http_realip_commands[] = {
> @@ -67,6 +76,13 @@
> 0,
> NULL },
>
> + { ngx_string("real_port_header"),
> + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
> + ngx_http_real_port,
> + NGX_HTTP_LOC_CONF_OFFSET,
> + 0,
> + NULL },
> +
> { ngx_string("real_ip_recursive"),
> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
> ngx_conf_set_flag_slot,
> @@ -115,6 +131,9 @@
> { ngx_string("realip_remote_addr"), NULL,
> ngx_http_realip_remote_addr_variable, 0, 0, 0 },
>
> + { ngx_string("realip_remote_port"), NULL,
> + ngx_http_realip_remote_port_variable, 0, 0, 0 },
> +
> { ngx_null_string, NULL, NULL, 0, 0, 0 }
> };
>
> @@ -127,6 +146,7 @@
> ngx_str_t *value;
> ngx_uint_t i, hash;
> ngx_addr_t addr;
> + ngx_uint_t port;
> ngx_array_t *xfwd;
> ngx_list_part_t *part;
> ngx_table_elt_t *header;
> @@ -146,6 +166,8 @@
> return NGX_DECLINED;
> }
>
> + port = r->connection->port;
> +
> switch (rlcf->type) {
>
> case NGX_HTTP_REALIP_XREALIP:
> @@ -172,8 +194,8 @@
> break;
>
> case NGX_HTTP_REALIP_PROXY:
> -
> value = &r->connection->proxy_protocol_addr;
> + port = r->connection->proxy_protocol_port;
>
> if (value->len == 0) {
> return NGX_DECLINED;
> @@ -211,14 +233,52 @@
> value = &header[i].value;
> xfwd = NULL;
>
> - goto found;
> + goto portphase;
> }
> }
>
> return NGX_DECLINED;
> }
>
> -found:
> +portphase:
> +
> +
> + switch (rlcf->porttype) {
> +
> + case NGX_CONF_UNSET_UINT:
> + break;
> +
> + default: /* NGX_HTTP_REALPORT_HEADER */
> +
> + part = &r->headers_in.headers.part;
> + header = part->elts;
> +
> + hash = rlcf->porthash;
> + len = rlcf->portheader.len;
> + p = rlcf->portheader.data;
> +
> + for (i = 0; /* void */ ; i++) {
> +
> + if (i >= part->nelts) {
> + if (part->next == NULL) {
> + break;
> + }
> +
> + part = part->next;
> + header = part->elts;
> + i = 0;
> + }
> +
> + if (hash == header[i].hash
> + && len == header[i].key.len
> + && ngx_strncmp(p, header[i].lowcase_key, len) == 0)
> + {
> + port=ngx_atoi(header[i].value.data, header[i].value.len);
> +
> + break;
> + }
> + }
> + }
>
> c = r->connection;
>
> @@ -230,7 +290,7 @@
> rlcf->recursive)
> != NGX_DECLINED)
> {
> - return ngx_http_realip_set_addr(r, &addr);
> + return ngx_http_realip_set_addr(r, &addr, port);
> }
>
> return NGX_DECLINED;
> @@ -238,7 +298,7 @@
>
>
> static ngx_int_t
> -ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr)
> +ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr,
> ngx_uint_t port)
> {
> size_t len;
> u_char *p;
> @@ -276,11 +336,13 @@
> ctx->sockaddr = c->sockaddr;
> ctx->socklen = c->socklen;
> ctx->addr_text = c->addr_text;
> + ctx->port = c->port;
>
> c->sockaddr = addr->sockaddr;
> c->socklen = addr->socklen;
> c->addr_text.len = len;
> c->addr_text.data = p;
> + c->port = port;
>
> return NGX_DECLINED;
> }
> @@ -298,6 +360,7 @@
> c->sockaddr = ctx->sockaddr;
> c->socklen = ctx->socklen;
> c->addr_text = ctx->addr_text;
> + c->port = ctx->port;
> }
>
>
> @@ -383,6 +446,28 @@
> }
>
>
> +static char *
> +ngx_http_real_port(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
> +{
> + ngx_http_realip_loc_conf_t *rlcf = conf;
> +
> + ngx_str_t *value;
> +
> + value = cf->args->elts;
> +
> + if (ngx_strcmp(value[1].data, "proxy_protocol") == 0) {
> + rlcf->porttype = NGX_HTTP_REALPORT_PROXY;
> + return NGX_CONF_OK;
> + }
> +
> + rlcf->porttype = NGX_HTTP_REALPORT_HEADER;
> + rlcf->porthash = ngx_hash_strlow(value[1].data, value[1].data,
> value[1].len);
> + rlcf->portheader = value[1];
> +
> + return NGX_CONF_OK;
> +}
> +
> +
> static void *
> ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
> {
> @@ -399,9 +484,12 @@
> * conf->from = NULL;
> * conf->hash = 0;
> * conf->header = { 0, NULL };
> + * conf->porthash = 0
> + * conf->portheader = { 0, NULL };
> */
>
> conf->type = NGX_CONF_UNSET_UINT;
> + conf->porttype = NGX_CONF_UNSET_UINT;
> conf->recursive = NGX_CONF_UNSET;
>
> return conf;
> @@ -510,3 +598,50 @@
>
> return NGX_OK;
> }
> +
> +
> +static ngx_int_t
> +ngx_http_realip_remote_port_variable(ngx_http_request_t *r,
> + ngx_http_variable_value_t *v, uintptr_t data)
> +{
> + ngx_uint_t port;
> + ngx_pool_cleanup_t *cln;
> + ngx_http_realip_ctx_t *ctx;
> +
> + ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
> +
> + if (ctx == NULL && (r->internal || r->filter_finalize)) {
> +
> + /*
> + * if module context was reset, the original port
> + * can still be found in the cleanup handler
> + */
> +
> + for (cln = r->pool->cleanup; cln; cln = cln->next) {
> + if (cln->handler == ngx_http_realip_cleanup) {
> + ctx = cln->data;
> + break;
> + }
> + }
> + }
> + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
> + "piyo %ui %ui",ctx->port,r->connection->port);
> +
> +
> + port = ctx ? ctx->port : r->connection->port;
> +
> + v->len = 0;
> + v->valid = 1;
> + v->no_cacheable = 0;
> + v->not_found = 0;
> + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
> +
> + if (v->data == NULL) {
> + return NGX_ERROR;
> + }
> + if (port > 0 && port < 65536) {
> + v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
> + }
> +
> + return NGX_OK;
> +}
> diff -r 8426275a13fd -r cdaf19070ed1 src/http/ngx_http_variables.c
> --- a/src/http/ngx_http_variables.c Fri Apr 01 16:38:31 2016 +0300
> +++ b/src/http/ngx_http_variables.c Tue Apr 05 09:42:32 2016 +0900
> @@ -58,6 +58,8 @@
> ngx_http_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
> + ngx_http_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,
> @@ -192,6 +194,9 @@
> { ngx_string("proxy_protocol_addr"), NULL,
> ngx_http_variable_proxy_protocol_addr, 0, 0, 0 },
>
> + { ngx_string("proxy_protocol_port"), NULL,
> + ngx_http_variable_proxy_protocol_port, 0, 0, 0 },
> +
> { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr,
> 0, 0, 0 },
>
> { ngx_string("server_port"), NULL, ngx_http_variable_server_port,
> 0, 0, 0 },
> @@ -1190,12 +1195,7 @@
> ngx_http_variable_remote_port(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data)
> {
> - ngx_uint_t port;
> - struct sockaddr_in *sin;
> -#if (NGX_HAVE_INET6)
> - struct sockaddr_in6 *sin6;
> -#endif
> -
> + ngx_uint_t port;
> v->len = 0;
> v->valid = 1;
> v->no_cacheable = 0;
> @@ -1205,27 +1205,8 @@
> if (v->data == NULL) {
> return NGX_ERROR;
> }
> -
> - switch (r->connection->sockaddr->sa_family) {
> -
> -#if (NGX_HAVE_INET6)
> - case AF_INET6:
> - sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
> - port = ntohs(sin6->sin6_port);
> - break;
> -#endif
> -
> -#if (NGX_HAVE_UNIX_DOMAIN)
> - case AF_UNIX:
> - port = 0;
> - break;
> -#endif
> -
> - default: /* AF_INET */
> - sin = (struct sockaddr_in *) r->connection->sockaddr;
> - port = ntohs(sin->sin_port);
> - break;
> - }
> +
> + port = r->connection->port;
>
> if (port > 0 && port < 65536) {
> v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
> @@ -1250,6 +1231,29 @@
>
>
> static ngx_int_t
> +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
> + ngx_http_variable_value_t *v, uintptr_t data)
> +{
> + ngx_int_t port = r->connection->proxy_protocol_port;
> +
> + v->len = 0;
> + v->valid = 1;
> + v->no_cacheable = 0;
> + v->not_found = 0;
> + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
> +
> + if (v->data == NULL) {
> + return NGX_ERROR;
> + }
> + if (port > 0 && port < 65536) {
> + v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
> + }
> +
> + return NGX_OK;
> +}
> +
> +
> +static ngx_int_t
> ngx_http_variable_server_addr(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data)
> {
>
>
> On Tue, Apr 5, 2016 at 2:56 AM, Maxim Dounin <mdounin at mdounin.ru> wrote:
>> Hello!
>>
>> On Tue, Apr 05, 2016 at 02:12:21AM +0900, junpei yoshino wrote:
>>
>>> which is better way ?
>>> 1.
>>> "real_ip_from Forwarded" replace remote_addr and remote_port.
>>> And proxy_protocol also replace remote_addr and remote_port, too.
>>
>> While support for Forwarded is a good thing to have, it looks like
>> a separate and big work, so I wouldn't recommend trying to do this
>> now.
>>
>>> 2.
>>> "real_port_from Forwarded" replace port only.
>>> ip and port is independent.
>>> Also proxy protocol must configure real_ip_from and real_port_from.
>>
>> This approach looks wrong. If we know client port it should be
>> used. But see above about Forwarded.
>>
>>> 3.
>>> At first, not care Forwarded header.
>>> delete code related x-forwarded-port.
>>> support only custom http header including port number.
>>
>> This option looks most appropriate for now.
>>
>> (Assuming this also includes "proxy_protocol also replace
>> remote_addr and remote_port" as in 1.)
>>
>> --
>> Maxim Dounin
>> http://nginx.org/
>>
>> _______________________________________________
>> nginx-devel mailing list
>> nginx-devel at nginx.org
>> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
>
>
> --
> junpei.yoshino at gmail.com
--
junpei.yoshino at gmail.com
More information about the nginx-devel
mailing list