aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_cycle.h2
-rw-r--r--src/http/ngx_http_upstream.c6
-rw-r--r--src/os/unix/ngx_linux_config.h5
-rw-r--r--src/os/unix/ngx_process_cycle.c32
-rw-r--r--src/stream/ngx_stream_proxy_module.c6
5 files changed, 51 insertions, 0 deletions
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 2b48ccbd6..a825da2f9 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -114,6 +114,8 @@ typedef struct {
ngx_array_t env;
char **environment;
+
+ ngx_uint_t transparent; /* unsigned transparent:1; */
} ngx_core_conf_t;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 6d0f4ee52..f8d5707d3 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -6078,6 +6078,12 @@ 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)
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
+ ngx_core_module);
+
+ ccf->transparent = 1;
local->transparent = 1;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
index 2f6129d88..b22ea4378 100644
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -99,6 +99,11 @@ typedef struct iocb ngx_aiocb_t;
#endif
+#if (NGX_HAVE_CAPABILITIES)
+#include <sys/capability.h>
+#endif
+
+
#define NGX_LISTEN_BACKLOG 511
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index a20a515c7..40654b3a2 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -839,12 +839,44 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
ccf->username, ccf->group);
}
+#if (NGX_HAVE_PR_SET_KEEPCAPS && NGX_HAVE_CAPABILITIES)
+ if (ccf->transparent && ccf->user) {
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "prctl(PR_SET_KEEPCAPS, 1) failed");
+ /* fatal */
+ exit(2);
+ }
+ }
+#endif
+
if (setuid(ccf->user) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setuid(%d) failed", ccf->user);
/* fatal */
exit(2);
}
+
+#if (NGX_HAVE_CAPABILITIES)
+ if (ccf->transparent && ccf->user) {
+ struct __user_cap_data_struct data;
+ struct __user_cap_header_struct header;
+
+ ngx_memzero(&header, sizeof(struct __user_cap_header_struct));
+ ngx_memzero(&data, sizeof(struct __user_cap_data_struct));
+
+ header.version = _LINUX_CAPABILITY_VERSION_3;
+ data.effective = CAP_TO_MASK(CAP_NET_RAW);
+ data.permitted = data.effective;
+
+ if (capset(&header, &data) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "capset() failed");
+ /* fatal */
+ exit(2);
+ }
+ }
+#endif
}
if (worker >= 0) {
diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c
index ad81cc8b7..818d7329b 100644
--- a/src/stream/ngx_stream_proxy_module.c
+++ b/src/stream/ngx_stream_proxy_module.c
@@ -2155,6 +2155,12 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (cf->args->nelts > 2) {
if (ngx_strcmp(value[2].data, "transparent") == 0) {
#if (NGX_HAVE_TRANSPARENT_PROXY)
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
+ ngx_core_module);
+
+ ccf->transparent = 1;
local->transparent = 1;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,