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