mirror of
https://github.com/nginx/nginx.git
synced 2025-06-09 19:12:47 +08:00
Upstream: the "transparent" parameter of proxy_bind and friends.
This parameter lets binding the proxy connection to a non-local address. Upstream will see the connection as coming from that address. When used with $remote_addr, upstream will accept the connection from real client address. Example: proxy_bind $remote_addr transparent;
This commit is contained in:
parent
77ec993fd7
commit
be79f5cb16
38
auto/unix
38
auto/unix
@ -329,6 +329,44 @@ ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)"
|
|||||||
. auto/feature
|
. auto/feature
|
||||||
|
|
||||||
|
|
||||||
|
# NetBSD bind to any address for transparent proxying
|
||||||
|
|
||||||
|
ngx_feature="SO_BINDANY"
|
||||||
|
ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY"
|
||||||
|
ngx_feature_run=no
|
||||||
|
ngx_feature_incs="#include <sys/socket.h>"
|
||||||
|
ngx_feature_path=
|
||||||
|
ngx_feature_libs=
|
||||||
|
ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_BINDANY, NULL, 0)"
|
||||||
|
. auto/feature
|
||||||
|
|
||||||
|
|
||||||
|
# Linux transparent proxying
|
||||||
|
|
||||||
|
ngx_feature="IP_TRANSPARENT"
|
||||||
|
ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY"
|
||||||
|
ngx_feature_run=no
|
||||||
|
ngx_feature_incs="#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>"
|
||||||
|
ngx_feature_path=
|
||||||
|
ngx_feature_libs=
|
||||||
|
ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)"
|
||||||
|
. auto/feature
|
||||||
|
|
||||||
|
|
||||||
|
# FreeBSD bind to any address for transparent proxying
|
||||||
|
|
||||||
|
ngx_feature="IP_BINDANY"
|
||||||
|
ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY"
|
||||||
|
ngx_feature_run=no
|
||||||
|
ngx_feature_incs="#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>"
|
||||||
|
ngx_feature_path=
|
||||||
|
ngx_feature_libs=
|
||||||
|
ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)"
|
||||||
|
. auto/feature
|
||||||
|
|
||||||
|
|
||||||
# BSD way to get IPv4 datagram destination address
|
# BSD way to get IPv4 datagram destination address
|
||||||
|
|
||||||
ngx_feature="IP_RECVDSTADDR"
|
ngx_feature="IP_RECVDSTADDR"
|
||||||
|
@ -11,6 +11,12 @@
|
|||||||
#include <ngx_event_connect.h>
|
#include <ngx_event_connect.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
static ngx_int_t ngx_event_connect_set_transparent(ngx_peer_connection_t *pc,
|
||||||
|
ngx_socket_t s);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
||||||
{
|
{
|
||||||
@ -72,6 +78,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pc->local) {
|
if (pc->local) {
|
||||||
|
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
if (pc->transparent) {
|
||||||
|
if (ngx_event_connect_set_transparent(pc, s) != NGX_OK) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) {
|
if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) {
|
||||||
ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno,
|
ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno,
|
||||||
"bind(%V) failed", &pc->local->name);
|
"bind(%V) failed", &pc->local->name);
|
||||||
@ -249,6 +264,94 @@ failed:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, ngx_socket_t s)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
value = 1;
|
||||||
|
|
||||||
|
#if defined(SO_BINDANY)
|
||||||
|
|
||||||
|
if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
|
||||||
|
(const void *) &value, sizeof(int)) == -1)
|
||||||
|
{
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||||
|
"setsockopt(SO_BINDANY) failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
switch (pc->local->sockaddr->sa_family) {
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
|
||||||
|
#if defined(IP_TRANSPARENT)
|
||||||
|
|
||||||
|
if (setsockopt(s, IPPROTO_IP, IP_TRANSPARENT,
|
||||||
|
(const void *) &value, sizeof(int)) == -1)
|
||||||
|
{
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||||
|
"setsockopt(IP_TRANSPARENT) failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(IP_BINDANY)
|
||||||
|
|
||||||
|
if (setsockopt(s, IPPROTO_IP, IP_BINDANY,
|
||||||
|
(const void *) &value, sizeof(int)) == -1)
|
||||||
|
{
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||||
|
"setsockopt(IP_BINDANY) failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
|
||||||
|
#if defined(IPV6_TRANSPARENT)
|
||||||
|
|
||||||
|
if (setsockopt(s, IPPROTO_IPV6, IPV6_TRANSPARENT,
|
||||||
|
(const void *) &value, sizeof(int)) == -1)
|
||||||
|
{
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||||
|
"setsockopt(IPV6_TRANSPARENT) failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(IPV6_BINDANY)
|
||||||
|
|
||||||
|
if (setsockopt(s, IPPROTO_IPV6, IPV6_BINDANY,
|
||||||
|
(const void *) &value, sizeof(int)) == -1)
|
||||||
|
{
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||||
|
"setsockopt(IPV6_BINDANY) failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif /* NGX_HAVE_INET6 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SO_BINDANY */
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
|
ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
|
||||||
{
|
{
|
||||||
|
@ -61,6 +61,9 @@ struct ngx_peer_connection_s {
|
|||||||
ngx_log_t *log;
|
ngx_log_t *log;
|
||||||
|
|
||||||
unsigned cached:1;
|
unsigned cached:1;
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
unsigned transparent:1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ngx_connection_log_error_e */
|
/* ngx_connection_log_error_e */
|
||||||
unsigned log_error:2;
|
unsigned log_error:2;
|
||||||
|
@ -279,7 +279,7 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("fastcgi_bind"),
|
{ ngx_string("fastcgi_bind"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_http_upstream_bind_set_slot,
|
ngx_http_upstream_bind_set_slot,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local),
|
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local),
|
||||||
|
@ -61,7 +61,7 @@ static ngx_command_t ngx_http_memcached_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("memcached_bind"),
|
{ ngx_string("memcached_bind"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_http_upstream_bind_set_slot,
|
ngx_http_upstream_bind_set_slot,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
offsetof(ngx_http_memcached_loc_conf_t, upstream.local),
|
offsetof(ngx_http_memcached_loc_conf_t, upstream.local),
|
||||||
|
@ -316,7 +316,7 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("proxy_bind"),
|
{ ngx_string("proxy_bind"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_http_upstream_bind_set_slot,
|
ngx_http_upstream_bind_set_slot,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.local),
|
offsetof(ngx_http_proxy_loc_conf_t, upstream.local),
|
||||||
|
@ -136,7 +136,7 @@ static ngx_command_t ngx_http_scgi_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("scgi_bind"),
|
{ ngx_string("scgi_bind"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_http_upstream_bind_set_slot,
|
ngx_http_upstream_bind_set_slot,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
offsetof(ngx_http_scgi_loc_conf_t, upstream.local),
|
offsetof(ngx_http_scgi_loc_conf_t, upstream.local),
|
||||||
|
@ -196,7 +196,7 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("uwsgi_bind"),
|
{ ngx_string("uwsgi_bind"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_http_upstream_bind_set_slot,
|
ngx_http_upstream_bind_set_slot,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
|
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
|
||||||
|
@ -5788,7 +5788,7 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
|
||||||
*plocal = NULL;
|
*plocal = NULL;
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
@ -5841,6 +5841,22 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cf->args->nelts > 2) {
|
||||||
|
if (ngx_strcmp(value[2].data, "transparent") == 0) {
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
local->transparent = 1;
|
||||||
|
#else
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"transparent proxying is not supported "
|
||||||
|
"on this platform, ignored");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"invalid parameter \"%V\"", &value[2]);
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5858,6 +5874,10 @@ ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
u->peer.transparent = local->transparent;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (local->value == NULL) {
|
if (local->value == NULL) {
|
||||||
u->peer.local = local->addr;
|
u->peer.local = local->addr;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
@ -133,6 +133,9 @@ struct ngx_http_upstream_srv_conf_s {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_addr_t *addr;
|
ngx_addr_t *addr;
|
||||||
ngx_http_complex_value_t *value;
|
ngx_http_complex_value_t *value;
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
ngx_uint_t transparent; /* unsigned transparent:1; */
|
||||||
|
#endif
|
||||||
} ngx_http_upstream_local_t;
|
} ngx_http_upstream_local_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_addr_t *addr;
|
ngx_addr_t *addr;
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
ngx_uint_t transparent; /* unsigned transparent:1; */
|
||||||
|
#endif
|
||||||
} ngx_stream_upstream_local_t;
|
} ngx_stream_upstream_local_t;
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +123,7 @@ static ngx_command_t ngx_stream_proxy_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("proxy_bind"),
|
{ ngx_string("proxy_bind"),
|
||||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
|
||||||
ngx_stream_proxy_bind,
|
ngx_stream_proxy_bind,
|
||||||
NGX_STREAM_SRV_CONF_OFFSET,
|
NGX_STREAM_SRV_CONF_OFFSET,
|
||||||
0,
|
0,
|
||||||
@ -443,16 +446,63 @@ static ngx_int_t
|
|||||||
ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
|
ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
|
||||||
ngx_stream_upstream_local_t *local)
|
ngx_stream_upstream_local_t *local)
|
||||||
{
|
{
|
||||||
|
ngx_addr_t *addr;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (local == NULL) {
|
if (local == NULL) {
|
||||||
u->peer.local = NULL;
|
u->peer.local = NULL;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
u->peer.transparent = local->transparent;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (local->addr) {
|
if (local->addr) {
|
||||||
u->peer.local = local->addr;
|
u->peer.local = local->addr;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* $remote_addr */
|
||||||
|
|
||||||
|
c = s->connection;
|
||||||
|
|
||||||
|
addr = ngx_palloc(c->pool, sizeof(ngx_addr_t));
|
||||||
|
if (addr == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr->socklen = c->socklen;
|
||||||
|
|
||||||
|
addr->sockaddr = ngx_palloc(c->pool, addr->socklen);
|
||||||
|
if (addr->sockaddr == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen);
|
||||||
|
|
||||||
|
switch (addr->sockaddr->sa_family) {
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
sin = (struct sockaddr_in *) addr->sockaddr;
|
||||||
|
sin->sin_port = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6 *) addr->sockaddr;
|
||||||
|
sin6->sin6_port = 0;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
addr->name = c->addr_text;
|
||||||
|
u->peer.local = addr;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1676,7 +1726,7 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
|
||||||
pscf->local = NULL;
|
pscf->local = NULL;
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
@ -1688,6 +1738,7 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
pscf->local = local;
|
pscf->local = local;
|
||||||
|
|
||||||
|
if (ngx_strcmp(value[1].data, "$remote_addr") != 0) {
|
||||||
local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
|
local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
|
||||||
if (local->addr == NULL) {
|
if (local->addr == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
@ -1708,6 +1759,24 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
default:
|
default:
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cf->args->nelts > 2) {
|
||||||
|
if (ngx_strcmp(value[2].data, "transparent") == 0) {
|
||||||
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
|
local->transparent = 1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"transparent proxying is not supported "
|
||||||
|
"on this platform, ignored");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"invalid parameter \"%V\"", &value[2]);
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user