Klaus Demo nginx / 752f66b
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. Roman Arutyunyan 4 years ago
6 changed file(s) with 82 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
156156 . auto/feature
157157
158158
159 # prctl(PR_SET_KEEPCAPS)
160
161 ngx_feature="prctl(PR_SET_KEEPCAPS)"
162 ngx_feature_name="NGX_HAVE_PR_SET_KEEPCAPS"
163 ngx_feature_run=yes
164 ngx_feature_incs="#include <sys/prctl.h>"
165 ngx_feature_path=
166 ngx_feature_libs=
167 ngx_feature_test="if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) return 1"
168 . auto/feature
169
170
171 # capabilities
172
173 ngx_feature="capabilities"
174 ngx_feature_name="NGX_HAVE_CAPABILITIES"
175 ngx_feature_run=no
176 ngx_feature_incs="#include <sys/capability.h>"
177 ngx_feature_path=
178 ngx_feature_libs=
179 ngx_feature_test="struct __user_cap_data_struct data;
180 struct __user_cap_header_struct header;
181
182 header.version = _LINUX_CAPABILITY_VERSION_3;
183 data.effective = CAP_TO_MASK(CAP_NET_RAW);
184 data.permitted = 0;
185
186 (void) capset(&header, &data)"
187 . auto/feature
188
189
159190 # crypt_r()
160191
161192 ngx_feature="crypt_r()"
113113
114114 ngx_array_t env;
115115 char **environment;
116
117 ngx_uint_t transparent; /* unsigned transparent:1; */
116118 } ngx_core_conf_t;
117119
118120
60776077 if (cf->args->nelts > 2) {
60786078 if (ngx_strcmp(value[2].data, "transparent") == 0) {
60796079 #if (NGX_HAVE_TRANSPARENT_PROXY)
6080 ngx_core_conf_t *ccf;
6081
6082 ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
6083 ngx_core_module);
6084
6085 ccf->transparent = 1;
60806086 local->transparent = 1;
60816087 #else
60826088 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
9898 #endif
9999
100100
101 #if (NGX_HAVE_CAPABILITIES)
102 #include <sys/capability.h>
103 #endif
104
105
101106 #define NGX_LISTEN_BACKLOG 511
102107
103108
838838 ccf->username, ccf->group);
839839 }
840840
841 #if (NGX_HAVE_PR_SET_KEEPCAPS && NGX_HAVE_CAPABILITIES)
842 if (ccf->transparent && ccf->user) {
843 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
844 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
845 "prctl(PR_SET_KEEPCAPS, 1) failed");
846 /* fatal */
847 exit(2);
848 }
849 }
850 #endif
851
841852 if (setuid(ccf->user) == -1) {
842853 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
843854 "setuid(%d) failed", ccf->user);
844855 /* fatal */
845856 exit(2);
846857 }
858
859 #if (NGX_HAVE_CAPABILITIES)
860 if (ccf->transparent && ccf->user) {
861 struct __user_cap_data_struct data;
862 struct __user_cap_header_struct header;
863
864 ngx_memzero(&header, sizeof(struct __user_cap_header_struct));
865 ngx_memzero(&data, sizeof(struct __user_cap_data_struct));
866
867 header.version = _LINUX_CAPABILITY_VERSION_3;
868 data.effective = CAP_TO_MASK(CAP_NET_RAW);
869 data.permitted = data.effective;
870
871 if (capset(&header, &data) == -1) {
872 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
873 "capset() failed");
874 /* fatal */
875 exit(2);
876 }
877 }
878 #endif
847879 }
848880
849881 if (worker >= 0) {
21542154 if (cf->args->nelts > 2) {
21552155 if (ngx_strcmp(value[2].data, "transparent") == 0) {
21562156 #if (NGX_HAVE_TRANSPARENT_PROXY)
2157 ngx_core_conf_t *ccf;
2158
2159 ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
2160 ngx_core_module);
2161
2162 ccf->transparent = 1;
21572163 local->transparent = 1;
21582164 #else
21592165 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,