<div dir="ltr"><span style="font-size:12.8px">Hi guys,</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">I need to log the user remote port at nginx level when requests are passed through <span class="">proxy</span> protocol (legal requirement), but looking at implementation I saw that all of the work stopped after reading source IP.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">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.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">I have tried to implement what I needed and update the test case.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Regards.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style=""><div style=""><span style="font-size:12.8px"># HG changeset patch</span></div><div style=""><span style="font-size:12.8px"># User Tony Fouchard <<a href="mailto:tony.fouchard@blablacar.com">tony.fouchard@blablacar.com</a>></span></div><div style=""><span style="font-size:12.8px"># Date 1459438244 -7200</span></div><div style=""><span style="font-size:12.8px">#      Thu Mar 31 17:30:44 2016 +0200</span></div><div style=""><span style="font-size:12.8px"># Node ID 708e5e9873798be8786aa0234c9712ef94b5a1e2</span></div><div style=""><span style="font-size:12.8px"># Parent  5debefd670bcbc1d4344913bd4754452892f4cb2</span></div><div style=""><span style="font-size:12.8px">Retrieve the proxy protocol client port provided</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">diff -r 5debefd670bc -r 708e5e987379 proxy_protocol.t</span></div><div style=""><span style="font-size:12.8px">--- a/proxy_protocol.t  Mon Mar 28 19:47:38 2016 +0300</span></div><div style=""><span style="font-size:12.8px">+++ b/proxy_protocol.t  Thu Mar 31 17:30:44 2016 +0200</span></div><div style=""><span style="font-size:12.8px">@@ -26,7 +26,7 @@</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"> my $t = Test::Nginx->new()->has(qw/http access ipv6 realip/);</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">-$t->write_file_expand('nginx.conf', <<'EOF')->plan(18);</span></div><div style=""><span style="font-size:12.8px">+$t->write_file_expand('nginx.conf', <<'EOF')->plan(22);</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"> %%TEST_GLOBALS%%</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">@@ -38,7 +38,7 @@</span></div><div style=""><span style="font-size:12.8px"> http {</span></div><div style=""><span style="font-size:12.8px">     %%TEST_GLOBALS_HTTP%%</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">-    log_format pp '$remote_addr $request';</span></div><div style=""><span style="font-size:12.8px">+    log_format pp '$remote_addr $request $proxy_protocol_port';</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">     server {</span></div><div style=""><span style="font-size:12.8px">         listen       <a href="http://127.0.0.1:8080">127.0.0.1:8080</a> proxy_protocol;</span></div><div style=""><span style="font-size:12.8px">@@ -47,6 +47,7 @@</span></div><div style=""><span style="font-size:12.8px">         set_real_ip_from  <a href="http://127.0.0.1/32">127.0.0.1/32</a>;</span></div><div style=""><span style="font-size:12.8px">         add_header X-IP $remote_addr;</span></div><div style=""><span style="font-size:12.8px">         add_header X-PP $proxy_protocol_addr;</span></div><div style=""><span style="font-size:12.8px">+        add_header X-PORT $proxy_protocol_port;</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">         location /pp {</span></div><div style=""><span style="font-size:12.8px">             real_ip_header proxy_protocol;</span></div><div style=""><span style="font-size:12.8px">@@ -81,11 +82,14 @@</span></div><div style=""><span style="font-size:12.8px"> $r = pp_get('/t1', $tcp4);</span></div><div style=""><span style="font-size:12.8px"> like($r, qr/SEE-THIS/, 'tcp4 request');</span></div><div style=""><span style="font-size:12.8px"> like($r, qr/X-PP: <a href="http://192.0.2.1/">192.0.2.1/</a>, 'tcp4 proxy');</span></div><div style=""><span style="font-size:12.8px">+like($r, qr/X-PORT: 1234/, 'tcp4 proxy port');</span></div><div style=""><span style="font-size:12.8px"> unlike($r, qr/X-IP: <a href="http://192.0.2.1/">192.0.2.1/</a>, 'tcp4 client');</span></div><div style=""><div><br></div><div> $r = pp_get('/t1', $tcp6);</div><div> like($r, qr/SEE-THIS/, 'tcp6 request');</div><div>+like($r, qr/X-PORT: 1234/, 'tcp6 proxy port');</div><div> like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy');</div><div>+</div><div> unlike($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client');</div><div><br></div><div> like(pp_get('/t1', $unk1), qr/SEE-THIS/, 'unknown request 1');</div><div>@@ -96,11 +100,13 @@</div><div> $r = pp_get('/pp', $tcp4);</div><div> like($r, qr/SEE-THIS/, 'tcp4 request realip');</div><div> like($r, qr/X-PP: <a href="http://192.0.2.1/">192.0.2.1/</a>, 'tcp4 proxy realip');</div><div>+like($r, qr/X-PORT: 1234/, 'tcp4 proxy port realip');</div><div> like($r, qr/X-IP: <a href="http://192.0.2.1/">192.0.2.1/</a>, 'tcp4 client realip');</div><div><br></div><div> $r = pp_get('/pp', $tcp6);</div><div> like($r, qr/SEE-THIS/, 'tcp6 request realip');</div><div> like($r, qr/X-PP: 2001:DB8::1/i, 'tcp6 proxy realip');</div><div>+like($r, qr/X-PORT: 1234/, 'tcp6 proxy port realip');</div><div> like($r, qr/X-IP: 2001:DB8::1/i, 'tcp6 client realip');</div><div><br></div><div> # access</div><div>@@ -125,8 +131,8 @@</div><div>        close LOG;</div><div> }</div><div><br></div><div>-like($log, qr!^192\.0\.2\.1 GET /pp_4!m, 'tcp4 access log');</div><div>-like($log, qr!^2001:DB8::1 GET /pp_6!mi, 'tcp6 access log');</div><div>+like($log, qr!^192\.0\.2\.1 GET /pp_4 HTTP/1.0 1234!m, 'tcp4 access log');</div><div>+like($log, qr!^2001:DB8::1 GET /pp_6 HTTP/1.0 1234!mi, 'tcp6 access log');</div><div><br></div><div> ###############################################################################</div></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><div style=""><span style="font-size:12.8px"># HG changeset patch</span></div><div style=""><span style="font-size:12.8px"># User Tony Fouchard <<a href="mailto:tony.fouchard@blablacar.com">tony.fouchard@blablacar.com</a>></span></div><div style=""><span style="font-size:12.8px"># Date 1459438562 -7200</span></div><div style=""><span style="font-size:12.8px">#      Thu Mar 31 17:36:02 2016 +0200</span></div><div style=""><span style="font-size:12.8px"># Branch feat-proxy-protocol-port</span></div><div style=""><span style="font-size:12.8px"># Node ID 6cd4f889089344db865cd07400c15e4d5966aa01</span></div><div style=""><span style="font-size:12.8px"># Parent  2b7dacb381ed1c4583aa048f1b22bdc141259407</span></div><div style=""><span style="font-size:12.8px">Retrieve the proxy protocol client port provided</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_connection.h</span></div><div style=""><span style="font-size:12.8px">--- a/src/core/ngx_connection.h Thu Mar 31 02:34:04 2016 +0300</span></div><div style=""><span style="font-size:12.8px">+++ b/src/core/ngx_connection.h Thu Mar 31 17:36:02 2016 +0200</span></div><div style=""><span style="font-size:12.8px">@@ -149,6 +149,7 @@</span></div><div style=""><span style="font-size:12.8px">     ngx_str_t           addr_text;</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">     ngx_str_t           proxy_protocol_addr;</span></div><div style=""><span style="font-size:12.8px">+    ngx_str_t           proxy_protocol_port;</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"> #if (NGX_SSL)</span></div><div style=""><span style="font-size:12.8px">     ngx_ssl_connection_t  *ssl;</span></div><div style=""><span style="font-size:12.8px">diff -r 2b7dacb381ed -r 6cd4f8890893 src/core/ngx_proxy_protocol.c</span></div><div style=""><span style="font-size:12.8px">--- a/src/core/ngx_proxy_protocol.c     Thu Mar 31 02:34:04 2016 +0300</span></div><div style=""><span style="font-size:12.8px">+++ b/src/core/ngx_proxy_protocol.c     Thu Mar 31 17:36:02 2016 +0200</span></div><div style=""><span style="font-size:12.8px">@@ -12,8 +12,8 @@</span></div><div style=""><span style="font-size:12.8px"> u_char *</span></div><div style=""><span style="font-size:12.8px"> ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)</span></div><div style=""><span style="font-size:12.8px"> {</span></div><div style=""><span style="font-size:12.8px">-    size_t  len;</span></div><div style=""><span style="font-size:12.8px">-    u_char  ch, *p, *addr;</span></div><div style=""><span style="font-size:12.8px">+    size_t  len, plen;</span></div><div style=""><span style="font-size:12.8px">+    u_char  ch, *p, *addr, *paddr;</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">     p = buf;</span></div><div style=""><span style="font-size:12.8px">     len = last - buf;</span></div><div style=""><span style="font-size:12.8px">@@ -74,6 +74,57 @@</span></div><div style=""><span style="font-size:12.8px">     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,</span></div><div style=""><span style="font-size:12.8px">                    "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr);</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">+    for ( ;; ) {</span></div><div style=""><span style="font-size:12.8px">+        if (p == last) {</span></div><div style=""><span style="font-size:12.8px">+            goto invalid;</span></div><div style=""><span style="font-size:12.8px">+        }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+        ch = *p++;</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+        if (ch == ' ') {</span></div><div style=""><span style="font-size:12.8px">+            break;</span></div><div style=""><span style="font-size:12.8px">+        }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+        if (ch != ':' && ch != '.'</span></div><div style=""><span style="font-size:12.8px">+            && (ch < 'a' || ch > 'f')</span></div><div style=""><span style="font-size:12.8px">+            && (ch < 'A' || ch > 'F')</span></div><div style=""><span style="font-size:12.8px">+            && (ch < '0' || ch > '9'))</span></div><div style=""><span style="font-size:12.8px">+        {</span></div><div style=""><span style="font-size:12.8px">+            goto invalid;</span></div><div style=""><span style="font-size:12.8px">+        }</span></div><div style=""><span style="font-size:12.8px">+    }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+    paddr = p;</span></div><div style=""><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+    for ( ;; ) {</span></div><div style=""><span style="font-size:12.8px">+        if (p == last) {</span></div><div style=""><span style="font-size:12.8px">+            goto invalid;</span></div><div style=""><span style="font-size:12.8px">+        }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+        ch = *p++;</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+        if (ch == ' ') {</span></div><div style=""><span style="font-size:12.8px">+            break;</span></div><div style=""><span style="font-size:12.8px">+        }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+        if (ch < '0' || ch > '9') {</span></div><div style=""><span style="font-size:12.8px">+            goto invalid;</span></div><div style=""><span style="font-size:12.8px">+        }</span></div><div style=""><span style="font-size:12.8px">+    }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+    plen = p - paddr - 1;</span></div><div style=""><span style="font-size:12.8px">+    c->proxy_protocol_port.data = ngx_pnalloc(c->pool, plen);</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+    if (c->proxy_protocol_port.data == NULL) {</span></div><div style=""><span style="font-size:12.8px">+        return NULL;</span></div><div style=""><span style="font-size:12.8px">+    }</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+    ngx_memcpy(c->proxy_protocol_port.data, paddr, plen);</span></div><div style=""><span style="font-size:12.8px">+    c->proxy_protocol_port.len = plen;</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">+    ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,</span></div><div style=""><span style="font-size:12.8px">+                   "PROXY protocol port: \"%V\"", &c->proxy_protocol_port);</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px"> skip:</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">     for ( /* void */ ; p < last - 1; p++) {</span></div><div style=""><span style="font-size:12.8px">diff -r 2b7dacb381ed -r 6cd4f8890893 src/http/ngx_http_variables.c</span></div><div style=""><span style="font-size:12.8px">--- a/src/http/ngx_http_variables.c     Thu Mar 31 02:34:04 2016 +0300</span></div><div style=""><span style="font-size:12.8px">+++ b/src/http/ngx_http_variables.c     Thu Mar 31 17:36:02 2016 +0200</span></div><div style=""><span style="font-size:12.8px">@@ -58,6 +58,8 @@</span></div><div style=""><span style="font-size:12.8px">     ngx_http_variable_value_t *v, uintptr_t data);</span></div><div style=""><span style="font-size:12.8px"> static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,</span></div><div style=""><span style="font-size:12.8px">     ngx_http_variable_value_t *v, uintptr_t data);</span></div><div style=""><span style="font-size:12.8px">+static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,</span></div><div style=""><span style="font-size:12.8px">+    ngx_http_variable_value_t *v, uintptr_t data);</span></div><div style=""><span style="font-size:12.8px"> static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,</span></div><div style=""><span style="font-size:12.8px">     ngx_http_variable_value_t *v, uintptr_t data);</span></div><div style=""><span style="font-size:12.8px"> static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,</span></div><div style=""><span style="font-size:12.8px">@@ -192,6 +194,9 @@</span></div><div style=""><span style="font-size:12.8px">     { ngx_string("proxy_protocol_addr"), NULL,</span></div><div style=""><span style="font-size:12.8px">       ngx_http_variable_proxy_protocol_addr, 0, 0, 0 },</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">+    { ngx_string("proxy_protocol_port"), NULL,</span></div><div style=""><span style="font-size:12.8px">+      ngx_http_variable_proxy_protocol_port, 0, 0, 0 },</span></div><div style=""><span style="font-size:12.8px">+</span></div><div style=""><span style="font-size:12.8px">     { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },</span></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px">     { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },</span></div><div style=""><span style="font-size:12.8px">@@ -1250,6 +1255,20 @@</span></div><div style=""><div><br></div><div><br></div><div> static ngx_int_t</div><div>+ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,</div><div>+    ngx_http_variable_value_t *v, uintptr_t data)</div><div>+{</div><div>+    v->len = r->connection->proxy_protocol_port.len;</div><div>+    v->valid = 1;</div><div>+    v->no_cacheable = 0;</div><div>+    v->not_found = 0;</div><div>+    v->data = r->connection->proxy_protocol_port.data;</div><div>+</div><div>+    return NGX_OK;</div><div>+}</div><div>+</div><div>+</div><div>+static ngx_int_t</div><div> ngx_http_variable_server_addr(ngx_http_request_t *r,</div><div>     ngx_http_variable_value_t *v, uintptr_t data)</div><div> {</div></div><div style=""><br></div><div style=""><br></div></div></div><div style=""><span style="font-size:12.8px"><br></span></div><div style=""><span style="font-size:12.8px"><br></span></div></div></div>