Hello! Thank you for your comment.
I rewrote patch in way 3. Best Regards, Junpei Yoshino # HG changeset patch # User Junpei Yoshino <junpei.yosh...@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 <mdou...@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@nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- junpei.yosh...@gmail.com _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel