<div dir="ltr">Hi,<div><br></div><div>I tried this with 1.2.6 and it works just fine. Have you given this any scrutiny in real life production systems?</div><div><br></div><div style>Thx,</div><div style>ssehic</div></div>
<div class="gmail_extra"><br clear="all"><div><br>Best regards,<br><br>Srebrenko Sehic<br>Armorlogic<br><br>Phone: +45 70 27 77 32<br>Mobile: +45 26 10 02 76<br><br><a href="http://www.armorlogic.com" target="_blank">http://www.armorlogic.com</a></div>

<br><br><div class="gmail_quote">On Thu, Oct 28, 2010 at 4:14 PM, David Gwynne <span dir="ltr"><<a href="mailto:loki@animata.net" target="_blank">loki@animata.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
openbsd has a setsockopt option called SO_BINDANY that allows a<br>
process to bind to any ip address, even if it is not local to the<br>
system. the patch below uses it to allow nginx to connect to a<br>
backend server using the ip of the client making the request.<br>
<br>
my main goal here is to allow the backend server to know the ip of<br>
the client actually making the request without having to look at<br>
extra hhtp headers<br>
<br>
i thought id throw this out there to get some help since this is<br>
my first attempt at tweaking nginx. there are a few issues with<br>
this implementation:<br>
<br>
1. it is completely specific to openbsd.<br>
2. it needs root privileges to use the SO_BINDANY sockopt.<br>
3. im not sure if connections to backends are cached. if so then<br>
it is probable that a different client will reuse a previous clients<br>
proxy connection, so it will appear that the same client made both<br>
requests to the backend.<br>
<br>
to use this you just configure nginx to run as root and add<br>
"proxy_transparent on" to the sections you want this feature enabled<br>
on. you will need to add appropriate "pass out proto tcp divert-reply"<br>
rules to pf for the SO_BINDANY sockopt to work too.<br>
<br>
if anyone has some tips on how to handle problems 2 and 3 i would<br>
be grateful.<br>
<br>
cheers,<br>
dlg<br>
<br>
<br>
--- src/event/ngx_event_connect.c.orig  Thu Nov 26 04:03:59 2009<br>
+++ src/event/ngx_event_connect.c       Thu Oct 28 23:22:37 2010<br>
@@ -11,7 +11,7 @@<br>
<br>
<br>
 ngx_int_t<br>
-ngx_event_connect_peer(ngx_peer_connection_t *pc)<br>
+ngx_event_connect_peer(ngx_peer_connection_t *pc, ngx_connection_t *cc)<br>
 {<br>
     int                rc;<br>
     ngx_int_t          event;<br>
@@ -20,6 +20,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)<br>
     ngx_socket_t       s;<br>
     ngx_event_t       *rev, *wev;<br>
     ngx_connection_t  *c;<br>
+    int                bindany;<br>
<br>
     rc = pc->get(pc, pc->data);<br>
     if (rc != NGX_OK) {<br>
@@ -46,6 +47,40 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)<br>
         }<br>
<br>
         return NGX_ERROR;<br>
+    }<br>
+<br>
+    if (cc != NULL) {<br>
+        bindany = 1;<br>
+        if (setsockopt(s, SOL_SOCKET, SO_BINDANY,<br>
+                      &bindany, sizeof(bindany)) == -1)<br>
+        {<br>
+            ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,<br>
+                          "setsockopt(SO_BINDANY) failed");<br>
+<br>
+            ngx_free_connection(c);<br>
+<br>
+            if (ngx_close_socket(s) == -1) {<br>
+                ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,<br>
+                              ngx_close_socket_n " failed");<br>
+            }<br>
+<br>
+            return NGX_ERROR;<br>
+        }<br>
+<br>
+       if (bind(s, cc->sockaddr, cc->socklen) == -1)<br>
+       {<br>
+            ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,<br>
+                          "bind() failed");<br>
+<br>
+            ngx_free_connection(c);<br>
+<br>
+            if (ngx_close_socket(s) == -1) {<br>
+                ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,<br>
+                              ngx_close_socket_n " failed");<br>
+            }<br>
+<br>
+            return NGX_ERROR;<br>
+       }<br>
     }<br>
<br>
     if (pc->rcvbuf) {<br>
--- src/event/ngx_event_connect.h.orig  Tue Nov  3 01:24:02 2009<br>
+++ src/event/ngx_event_connect.h       Thu Oct 28 23:22:37 2010<br>
@@ -68,7 +68,8 @@ struct ngx_peer_connection_s {<br>
 };<br>
<br>
<br>
-ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc);<br>
+ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc,<br>
+    ngx_connection_t *cc);<br>
 ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data);<br>
<br>
<br>
--- src/http/modules/ngx_http_proxy_module.c.orig       Mon May 24 21:01:05 2010<br>
+++ src/http/modules/ngx_http_proxy_module.c    Thu Oct 28 23:42:10 2010<br>
@@ -71,6 +71,7 @@ typedef struct {<br>
     ngx_http_proxy_vars_t          vars;<br>
<br>
     ngx_flag_t                     redirect;<br>
+    ngx_flag_t                     transparent;<br>
<br>
     ngx_uint_t                     headers_hash_max_size;<br>
     ngx_uint_t                     headers_hash_bucket_size;<br>
@@ -196,6 +197,13 @@ static ngx_command_t  ngx_http_proxy_commands[] = {<br>
       0,<br>
       NULL },<br>
<br>
+    { ngx_string("proxy_transparent"),<br>
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,<br>
+      ngx_conf_set_flag_slot,<br>
+      NGX_HTTP_LOC_CONF_OFFSET,<br>
+      offsetof(ngx_http_proxy_loc_conf_t, transparent),<br>
+      NULL },<br>
+<br>
     { ngx_string("proxy_store"),<br>
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,<br>
       ngx_http_proxy_store,<br>
@@ -626,6 +634,7 @@ ngx_http_proxy_handler(ngx_http_request_t *r)<br>
     u->abort_request = ngx_http_proxy_abort_request;<br>
     u->finalize_request = ngx_http_proxy_finalize_request;<br>
     r->state = 0;<br>
+    r->transparent = (plcf->transparent == 1);<br>
<br>
     if (plcf->redirects) {<br>
         u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;<br>
@@ -1940,6 +1949,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)<br>
     conf->upstream.cyclic_temp_file = 0;<br>
<br>
     conf->redirect = NGX_CONF_UNSET;<br>
+    conf->transparent = NGX_CONF_UNSET;<br>
     conf->upstream.change_buffering = 1;<br>
<br>
     conf->headers_hash_max_size = NGX_CONF_UNSET_UINT;<br>
@@ -2214,6 +2224,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *pa<br>
             }<br>
         }<br>
     }<br>
+<br>
+    ngx_conf_merge_value(conf->transparent, prev->transparent, 0);<br>
<br>
     /* STUB */<br>
     if (prev->proxy_lengths) {<br>
--- src/http/ngx_http_request.h.orig    Mon May 24 22:35:10 2010<br>
+++ src/http/ngx_http_request.h Thu Oct 28 23:22:37 2010<br>
@@ -511,6 +511,8 @@ struct ngx_http_request_s {<br>
     unsigned                          stat_writing:1;<br>
 #endif<br>
<br>
+    unsigned                          transparent:1;<br>
+<br>
     /* used to parse HTTP headers */<br>
<br>
     ngx_uint_t                        state;<br>
--- src/http/ngx_http_upstream.c.orig   Mon May 24 22:35:10 2010<br>
+++ src/http/ngx_http_upstream.c        Thu Oct 28 23:22:37 2010<br>
@@ -1066,7 +1066,8 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_h<br>
     u->state->response_sec = tp->sec;<br>
     u->state->response_msec = tp->msec;<br>
<br>
-    rc = ngx_event_connect_peer(&u->peer);<br>
+    rc = ngx_event_connect_peer(&u->peer, r->transparent ?<br>
+                                r->connection : NULL);<br>
<br>
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,<br>
                    "http upstream connect: %i", rc);<br>
--- src/mail/ngx_mail_auth_http_module.c.orig   Fri May 14 19:56:37 2010<br>
+++ src/mail/ngx_mail_auth_http_module.c        Thu Oct 28 23:22:37 2010<br>
@@ -191,7 +191,7 @@ ngx_mail_auth_http_init(ngx_mail_session_t *s)<br>
     ctx->peer.log = s->connection->log;<br>
     ctx->peer.log_error = NGX_ERROR_ERR;<br>
<br>
-    rc = ngx_event_connect_peer(&ctx->peer);<br>
+    rc = ngx_event_connect_peer(&ctx->peer, NULL);<br>
<br>
     if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {<br>
         if (ctx->peer.connection) {<br>
--- src/mail/ngx_mail_proxy_module.c.orig       Thu Oct 28 23:32:15 2010<br>
+++ src/mail/ngx_mail_proxy_module.c    Thu Oct 28 23:30:53 2010<br>
@@ -147,7 +147,7 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t<br>
     p->upstream.log = s->connection->log;<br>
     p->upstream.log_error = NGX_ERROR_ERR;<br>
<br>
-    rc = ngx_event_connect_peer(&p->upstream);<br>
+    rc = ngx_event_connect_peer(&p->upstream, NULL);<br>
<br>
     if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {<br>
         ngx_mail_proxy_internal_server_error(s);<br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
<a href="http://nginx.org/mailman/listinfo/nginx-devel" target="_blank">http://nginx.org/mailman/listinfo/nginx-devel</a><br>
</blockquote></div><br></div>