mirror of
https://github.com/nginx/nginx.git
synced 2024-11-21 16:28:40 +00:00
Retain CAP_NET_RAW capability for transparent proxying.
The capability is retained automatically in unprivileged worker processes after changing UID if transparent proxying is enabled at least once in nginx configuration. The feature is only available in Linux.
This commit is contained in:
parent
d2d737e70b
commit
752f66bf7d
@ -157,6 +157,37 @@ ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# prctl(PR_SET_KEEPCAPS)
|
||||
|
||||
ngx_feature="prctl(PR_SET_KEEPCAPS)"
|
||||
ngx_feature_name="NGX_HAVE_PR_SET_KEEPCAPS"
|
||||
ngx_feature_run=yes
|
||||
ngx_feature_incs="#include <sys/prctl.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) return 1"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# capabilities
|
||||
|
||||
ngx_feature="capabilities"
|
||||
ngx_feature_name="NGX_HAVE_CAPABILITIES"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sys/capability.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="struct __user_cap_data_struct data;
|
||||
struct __user_cap_header_struct header;
|
||||
|
||||
header.version = _LINUX_CAPABILITY_VERSION_3;
|
||||
data.effective = CAP_TO_MASK(CAP_NET_RAW);
|
||||
data.permitted = 0;
|
||||
|
||||
(void) capset(&header, &data)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# crypt_r()
|
||||
|
||||
ngx_feature="crypt_r()"
|
||||
|
@ -114,6 +114,8 @@ typedef struct {
|
||||
|
||||
ngx_array_t env;
|
||||
char **environment;
|
||||
|
||||
ngx_uint_t transparent; /* unsigned transparent:1; */
|
||||
} ngx_core_conf_t;
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user