[PATCH] proxy protocol proxified client port
Aleksandar Lazic
al-nginx at none.at
Tue Apr 5 08:19:15 UTC 2016
Hi,
Am 05-04-2016 09:55, schrieb Tony Fouchard:
> Hi guys,
>
> I need to log the user remote port at nginx level when requests are
> passed through proxy protocol (legal requirement), but looking at
> implementation I saw that all of the work stopped after reading source
> IP.
>
> In my setup, I have bgp sessions mounted on haproxy instances, but the
> haproxy acts at level 4 and only route traffic to different nginx farms
> depending of TLS extension value provided by client : it permits to
> serve for example both spdy and h2 over alpn.
>
> I have tried to implement what I needed and update the test case.
Could this be the same request?
PATCH]add proxy_protocol_port variable for rfc6302
http://thread.gmane.org/gmane.comp.web.nginx.devel/4273/focus=4390
Cheers aleks
> Regards.
>
> # HG changeset patch
> # User Tony Fouchard <tony.fouchard at blablacar.com>
> # Date 1459438244 -7200
> # Thu Mar 31 17:30:44 2016 +0200
> # Node ID 708e5e9873798be8786aa0234c9712ef94b5a1e2
> # Parent 5debefd670bcbc1d4344913bd4754452892f4cb2
> Retrieve the proxy protocol client port provided
>
> diff -r 5debefd670bc -r 708e5e987379 proxy_protocol.t
> --- a/proxy_protocol.t Mon Mar 28 19:47:38 2016 +0300
> +++ b/proxy_protocol.t Thu Mar 31 17:30:44 2016 +0200
> @@ -26,7 +26,7 @@
>
> my $t = Test::Nginx->new()->has(qw/http access ipv6 realip/);
>
> -$t->write_file_expand('nginx.conf', <<'EOF')->plan(18);
> +$t->write_file_expand('nginx.conf', <<'EOF')->plan(22);
>
> %%TEST_GLOBALS%%
>
> @@ -38,7 +38,7 @@
> http {
> %%TEST_GLOBALS_HTTP%%
>
> - log_format pp '$remote_addr $request';
> + log_format pp '$remote_addr $request $proxy_protocol_port';
>
> server {
> listen 127.0.0.1:8080 [1] proxy_protocol;
> @@ -47,6 +47,7 @@
> set_real_ip_from 127.0.0.1/32 [2];
> add_header X-IP $remote_addr;
> add_header X-PP $proxy_protocol_addr;
> + add_header X-PORT $proxy_protocol_port;
>
> location /pp {
> real_ip_header proxy_protocol;
> @@ -81,11 +82,14 @@
> $r = pp_get('/t1', $tcp4);
> like($r, qr/SEE-THIS/, 'tcp4 request');
> like($r, qr/X-PP: 192.0.2.1/ [3], 'tcp4 proxy');
> +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port');
> unlike($r, qr/X-IP: 192.0.2.1/ [3], 'tcp4 client');
>
> $r = pp_get('/t1', $tcp6);
> like($r, qr/SEE-THIS/, 'tcp6 request');
> +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port');
> like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy');
> +
> unlike($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client');
>
> like(pp_get('/t1', $unk1), qr/SEE-THIS/, 'unknown request 1');
> @@ -96,11 +100,13 @@
> $r = pp_get('/pp', $tcp4);
> like($r, qr/SEE-THIS/, 'tcp4 request realip');
> like($r, qr/X-PP: 192.0.2.1/ [3], 'tcp4 proxy realip');
> +like($r, qr/X-PORT: 1234/, 'tcp4 proxy port realip');
> like($r, qr/X-IP: 192.0.2.1/ [3], 'tcp4 client realip');
>
> $r = pp_get('/pp', $tcp6);
> like($r, qr/SEE-THIS/, 'tcp6 request realip');
> like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy realip');
> +like($r, qr/X-PORT: 1234/, 'tcp6 proxy port realip');
> like($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client realip');
>
> # access
> @@ -125,8 +131,8 @@
> close LOG;
> }
>
> -like($log, qr!^192\.0\.2\.1 GET /pp_4!m, 'tcp4 access log');
> -like($log, qr!^2001:DB8::1 GET /pp_6!mi, 'tcp6 access log');
> +like($log, qr!^192\.0\.2\.1 GET /pp_4 HTTP/1.0 1234!m, 'tcp4 access
> log');
> +like($log, qr!^2001:DB8::1 GET /pp_6 HTTP/1.0 1234!mi, 'tcp6 access
> log');
>
>
> ###############################################################################
>
> # HG changeset patch
> # User Tony Fouchard <tony.fouchard at blablacar.com>
> # Date 1459438562 -7200
> # Thu Mar 31 17:36:02 2016 +0200
> # Branch feat-proxy-protocol-port
> # Node ID 6cd4f889089344db865cd07400c15e4d5966aa01
> # Parent 2b7dacb381ed1c4583aa048f1b22bdc141259407
> Retrieve the proxy protocol client port provided
>
> diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_connection.h
> --- a/src/core/ngx_connection.h Thu Mar 31 02:34:04 2016 +0300
> +++ b/src/core/ngx_connection.h Thu Mar 31 17:36:02 2016 +0200
> @@ -149,6 +149,7 @@
> ngx_str_t addr_text;
>
> ngx_str_t proxy_protocol_addr;
> + ngx_str_t proxy_protocol_port;
>
> #if (NGX_SSL)
> ngx_ssl_connection_t *ssl;
> diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_proxy_protocol.c
> --- a/src/core/ngx_proxy_protocol.c Thu Mar 31 02:34:04 2016 +0300
> +++ b/src/core/ngx_proxy_protocol.c Thu Mar 31 17:36:02 2016 +0200
> @@ -12,8 +12,8 @@
> u_char *
> ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char
> *last)
> {
> - size_t len;
> - u_char ch, *p, *addr;
> + size_t len, plen;
> + u_char ch, *p, *addr, *paddr;
>
> p = buf;
> len = last - buf;
> @@ -74,6 +74,57 @@
> 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;
> + }
> +
> + if (ch != ':' && ch != '.'
> + && (ch < 'a' || ch > 'f')
> + && (ch < 'A' || ch > 'F')
> + && (ch < '0' || ch > '9'))
> + {
> + goto invalid;
> + }
> + }
> +
> + paddr = p;
>
> +
> + for ( ;; ) {
> + if (p == last) {
> + goto invalid;
> + }
> +
> + ch = *p++;
> +
> + if (ch == ' ') {
> + break;
> + }
> +
> + if (ch < '0' || ch > '9') {
> + goto invalid;
> + }
> + }
> +
> + plen = p - paddr - 1;
> + c->proxy_protocol_port.data = ngx_pnalloc(c->pool, plen);
> +
> + if (c->proxy_protocol_port.data == NULL) {
> + return NULL;
> + }
> +
> + ngx_memcpy(c->proxy_protocol_port.data, paddr, plen);
> + c->proxy_protocol_port.len = plen;
> +
> + ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
> + "PROXY protocol port: \"%V\"",
> &c->proxy_protocol_port);
> +
> skip:
>
> for ( /* void */ ; p < last - 1; p++) {
> diff -r 2b7dacb381ed -r 6cd4f8890893 src/http/ngx_http_variables.c
> --- a/src/http/ngx_http_variables.c Thu Mar 31 02:34:04 2016 +0300
> +++ b/src/http/ngx_http_variables.c Thu Mar 31 17:36:02 2016 +0200
> @@ -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 },
> @@ -1250,6 +1255,20 @@
>
> static ngx_int_t
> +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
> + ngx_http_variable_value_t *v, uintptr_t data)
> +{
> + v->len = r->connection->proxy_protocol_port.len;
> + v->valid = 1;
> + v->no_cacheable = 0;
> + v->not_found = 0;
> + v->data = r->connection->proxy_protocol_port.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)
> {
>
>
>
> Links:
> ------
> [1] http://127.0.0.1:8080
> [2] http://127.0.0.1/32
> [3] http://192.0.2.1/
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
More information about the nginx-devel
mailing list