Changeset 7174:84e53e4735a4 in nginx


Ignore:
Timestamp:
12/13/17 17:40:53 (2 days ago)
Author:
Roman Arutyunyan <arut@…>
Branch:
default
Tags:
tip
Message:

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.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • auto/os/linux

    r7010 r7174  
    158158
    159159
     160# prctl(PR_SET_KEEPCAPS)
     161
     162ngx_feature="prctl(PR_SET_KEEPCAPS)"
     163ngx_feature_name="NGX_HAVE_PR_SET_KEEPCAPS"
     164ngx_feature_run=yes
     165ngx_feature_incs="#include <sys/prctl.h>"
     166ngx_feature_path=
     167ngx_feature_libs=
     168ngx_feature_test="if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) return 1"
     169. auto/feature
     170
     171
     172# capabilities
     173
     174ngx_feature="capabilities"
     175ngx_feature_name="NGX_HAVE_CAPABILITIES"
     176ngx_feature_run=no
     177ngx_feature_incs="#include <sys/capability.h>"
     178ngx_feature_path=
     179ngx_feature_libs=
     180ngx_feature_test="struct __user_cap_data_struct    data;
     181                  struct __user_cap_header_struct  header;
     182
     183                  header.version = _LINUX_CAPABILITY_VERSION_3;
     184                  data.effective = CAP_TO_MASK(CAP_NET_RAW);
     185                  data.permitted = 0;
     186
     187                  (void) capset(&header, &data)"
     188. auto/feature
     189
     190
    160191# crypt_r()
    161192
  • src/core/ngx_cycle.h

    r6930 r7174  
    115115    ngx_array_t               env;
    116116    char                    **environment;
     117
     118    ngx_uint_t                transparent;  /* unsigned  transparent:1; */
    117119} ngx_core_conf_t;
    118120
  • src/http/ngx_http_upstream.c

    r7166 r7174  
    60796079        if (ngx_strcmp(value[2].data, "transparent") == 0) {
    60806080#if (NGX_HAVE_TRANSPARENT_PROXY)
     6081            ngx_core_conf_t  *ccf;
     6082
     6083            ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
     6084                                                   ngx_core_module);
     6085
     6086            ccf->transparent = 1;
    60816087            local->transparent = 1;
    60826088#else
  • src/os/unix/ngx_linux_config.h

    r6380 r7174  
    100100
    101101
     102#if (NGX_HAVE_CAPABILITIES)
     103#include <sys/capability.h>
     104#endif
     105
     106
    102107#define NGX_LISTEN_BACKLOG        511
    103108
  • src/os/unix/ngx_process_cycle.c

    r7162 r7174  
    840840        }
    841841
     842#if (NGX_HAVE_PR_SET_KEEPCAPS && NGX_HAVE_CAPABILITIES)
     843        if (ccf->transparent && ccf->user) {
     844            if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
     845                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
     846                              "prctl(PR_SET_KEEPCAPS, 1) failed");
     847                /* fatal */
     848                exit(2);
     849            }
     850        }
     851#endif
     852
    842853        if (setuid(ccf->user) == -1) {
    843854            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
     
    846857            exit(2);
    847858        }
     859
     860#if (NGX_HAVE_CAPABILITIES)
     861        if (ccf->transparent && ccf->user) {
     862            struct __user_cap_data_struct    data;
     863            struct __user_cap_header_struct  header;
     864
     865            ngx_memzero(&header, sizeof(struct __user_cap_header_struct));
     866            ngx_memzero(&data, sizeof(struct __user_cap_data_struct));
     867
     868            header.version = _LINUX_CAPABILITY_VERSION_3;
     869            data.effective = CAP_TO_MASK(CAP_NET_RAW);
     870            data.permitted = data.effective;
     871
     872            if (capset(&header, &data) == -1) {
     873                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
     874                              "capset() failed");
     875                /* fatal */
     876                exit(2);
     877            }
     878        }
     879#endif
    848880    }
    849881
  • src/stream/ngx_stream_proxy_module.c

    r7156 r7174  
    21562156        if (ngx_strcmp(value[2].data, "transparent") == 0) {
    21572157#if (NGX_HAVE_TRANSPARENT_PROXY)
     2158            ngx_core_conf_t  *ccf;
     2159
     2160            ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
     2161                                                   ngx_core_module);
     2162
     2163            ccf->transparent = 1;
    21582164            local->transparent = 1;
    21592165#else
Note: See TracChangeset for help on using the changeset viewer.