Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_stream.h>
0011 
0012 
0013 typedef struct {
0014     ngx_array_t       *from;     /* array of ngx_cidr_t */
0015 } ngx_stream_realip_srv_conf_t;
0016 
0017 
0018 typedef struct {
0019     struct sockaddr   *sockaddr;
0020     socklen_t          socklen;
0021     ngx_str_t          addr_text;
0022 } ngx_stream_realip_ctx_t;
0023 
0024 
0025 static ngx_int_t ngx_stream_realip_handler(ngx_stream_session_t *s);
0026 static ngx_int_t ngx_stream_realip_set_addr(ngx_stream_session_t *s,
0027     ngx_addr_t *addr);
0028 static char *ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
0029     void *conf);
0030 static void *ngx_stream_realip_create_srv_conf(ngx_conf_t *cf);
0031 static char *ngx_stream_realip_merge_srv_conf(ngx_conf_t *cf, void *parent,
0032     void *child);
0033 static ngx_int_t ngx_stream_realip_add_variables(ngx_conf_t *cf);
0034 static ngx_int_t ngx_stream_realip_init(ngx_conf_t *cf);
0035 
0036 
0037 static ngx_int_t ngx_stream_realip_remote_addr_variable(ngx_stream_session_t *s,
0038     ngx_stream_variable_value_t *v, uintptr_t data);
0039 static ngx_int_t ngx_stream_realip_remote_port_variable(ngx_stream_session_t *s,
0040     ngx_stream_variable_value_t *v, uintptr_t data);
0041 
0042 
0043 static ngx_command_t  ngx_stream_realip_commands[] = {
0044 
0045     { ngx_string("set_real_ip_from"),
0046       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0047       ngx_stream_realip_from,
0048       NGX_STREAM_SRV_CONF_OFFSET,
0049       0,
0050       NULL },
0051 
0052       ngx_null_command
0053 };
0054 
0055 
0056 static ngx_stream_module_t  ngx_stream_realip_module_ctx = {
0057     ngx_stream_realip_add_variables,       /* preconfiguration */
0058     ngx_stream_realip_init,                /* postconfiguration */
0059 
0060     NULL,                                  /* create main configuration */
0061     NULL,                                  /* init main configuration */
0062 
0063     ngx_stream_realip_create_srv_conf,     /* create server configuration */
0064     ngx_stream_realip_merge_srv_conf       /* merge server configuration */
0065 };
0066 
0067 
0068 ngx_module_t  ngx_stream_realip_module = {
0069     NGX_MODULE_V1,
0070     &ngx_stream_realip_module_ctx,         /* module context */
0071     ngx_stream_realip_commands,            /* module directives */
0072     NGX_STREAM_MODULE,                     /* module type */
0073     NULL,                                  /* init master */
0074     NULL,                                  /* init module */
0075     NULL,                                  /* init process */
0076     NULL,                                  /* init thread */
0077     NULL,                                  /* exit thread */
0078     NULL,                                  /* exit process */
0079     NULL,                                  /* exit master */
0080     NGX_MODULE_V1_PADDING
0081 };
0082 
0083 
0084 static ngx_stream_variable_t  ngx_stream_realip_vars[] = {
0085 
0086     { ngx_string("realip_remote_addr"), NULL,
0087       ngx_stream_realip_remote_addr_variable, 0, 0, 0 },
0088 
0089     { ngx_string("realip_remote_port"), NULL,
0090       ngx_stream_realip_remote_port_variable, 0, 0, 0 },
0091 
0092       ngx_stream_null_variable
0093 };
0094 
0095 
0096 static ngx_int_t
0097 ngx_stream_realip_handler(ngx_stream_session_t *s)
0098 {
0099     ngx_addr_t                     addr;
0100     ngx_connection_t              *c;
0101     ngx_stream_realip_srv_conf_t  *rscf;
0102 
0103     rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_realip_module);
0104 
0105     if (rscf->from == NULL) {
0106         return NGX_DECLINED;
0107     }
0108 
0109     c = s->connection;
0110 
0111     if (c->proxy_protocol_addr.len == 0) {
0112         return NGX_DECLINED;
0113     }
0114 
0115     if (ngx_cidr_match(c->sockaddr, rscf->from) != NGX_OK) {
0116         return NGX_DECLINED;
0117     }
0118 
0119     if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol_addr.data,
0120                        c->proxy_protocol_addr.len)
0121         != NGX_OK)
0122     {
0123         return NGX_DECLINED;
0124     }
0125 
0126     ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port);
0127 
0128     return ngx_stream_realip_set_addr(s, &addr);
0129 }
0130 
0131 
0132 static ngx_int_t
0133 ngx_stream_realip_set_addr(ngx_stream_session_t *s, ngx_addr_t *addr)
0134 {
0135     size_t                    len;
0136     u_char                   *p;
0137     u_char                    text[NGX_SOCKADDR_STRLEN];
0138     ngx_connection_t         *c;
0139     ngx_stream_realip_ctx_t  *ctx;
0140 
0141     c = s->connection;
0142 
0143     ctx = ngx_palloc(c->pool, sizeof(ngx_stream_realip_ctx_t));
0144     if (ctx == NULL) {
0145         return NGX_ERROR;
0146     }
0147 
0148     len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
0149                         NGX_SOCKADDR_STRLEN, 0);
0150     if (len == 0) {
0151         return NGX_ERROR;
0152     }
0153 
0154     p = ngx_pnalloc(c->pool, len);
0155     if (p == NULL) {
0156         return NGX_ERROR;
0157     }
0158 
0159     ngx_memcpy(p, text, len);
0160 
0161     ngx_stream_set_ctx(s, ctx, ngx_stream_realip_module);
0162 
0163     ctx->sockaddr = c->sockaddr;
0164     ctx->socklen = c->socklen;
0165     ctx->addr_text = c->addr_text;
0166 
0167     c->sockaddr = addr->sockaddr;
0168     c->socklen = addr->socklen;
0169     c->addr_text.len = len;
0170     c->addr_text.data = p;
0171 
0172     return NGX_DECLINED;
0173 }
0174 
0175 
0176 static char *
0177 ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0178 {
0179     ngx_stream_realip_srv_conf_t *rscf = conf;
0180 
0181     ngx_int_t             rc;
0182     ngx_str_t            *value;
0183     ngx_url_t             u;
0184     ngx_cidr_t            c, *cidr;
0185     ngx_uint_t            i;
0186     struct sockaddr_in   *sin;
0187 #if (NGX_HAVE_INET6)
0188     struct sockaddr_in6  *sin6;
0189 #endif
0190 
0191     value = cf->args->elts;
0192 
0193     if (rscf->from == NULL) {
0194         rscf->from = ngx_array_create(cf->pool, 2,
0195                                       sizeof(ngx_cidr_t));
0196         if (rscf->from == NULL) {
0197             return NGX_CONF_ERROR;
0198         }
0199     }
0200 
0201 #if (NGX_HAVE_UNIX_DOMAIN)
0202 
0203     if (ngx_strcmp(value[1].data, "unix:") == 0) {
0204         cidr = ngx_array_push(rscf->from);
0205         if (cidr == NULL) {
0206             return NGX_CONF_ERROR;
0207         }
0208 
0209         cidr->family = AF_UNIX;
0210         return NGX_CONF_OK;
0211     }
0212 
0213 #endif
0214 
0215     rc = ngx_ptocidr(&value[1], &c);
0216 
0217     if (rc != NGX_ERROR) {
0218         if (rc == NGX_DONE) {
0219             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
0220                                "low address bits of %V are meaningless",
0221                                &value[1]);
0222         }
0223 
0224         cidr = ngx_array_push(rscf->from);
0225         if (cidr == NULL) {
0226             return NGX_CONF_ERROR;
0227         }
0228 
0229         *cidr = c;
0230 
0231         return NGX_CONF_OK;
0232     }
0233 
0234     ngx_memzero(&u, sizeof(ngx_url_t));
0235     u.host = value[1];
0236 
0237     if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
0238         if (u.err) {
0239             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0240                                "%s in set_real_ip_from \"%V\"",
0241                                u.err, &u.host);
0242         }
0243 
0244         return NGX_CONF_ERROR;
0245     }
0246 
0247     cidr = ngx_array_push_n(rscf->from, u.naddrs);
0248     if (cidr == NULL) {
0249         return NGX_CONF_ERROR;
0250     }
0251 
0252     ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
0253 
0254     for (i = 0; i < u.naddrs; i++) {
0255         cidr[i].family = u.addrs[i].sockaddr->sa_family;
0256 
0257         switch (cidr[i].family) {
0258 
0259 #if (NGX_HAVE_INET6)
0260         case AF_INET6:
0261             sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
0262             cidr[i].u.in6.addr = sin6->sin6_addr;
0263             ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
0264             break;
0265 #endif
0266 
0267         default: /* AF_INET */
0268             sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
0269             cidr[i].u.in.addr = sin->sin_addr.s_addr;
0270             cidr[i].u.in.mask = 0xffffffff;
0271             break;
0272         }
0273     }
0274 
0275     return NGX_CONF_OK;
0276 }
0277 
0278 
0279 static void *
0280 ngx_stream_realip_create_srv_conf(ngx_conf_t *cf)
0281 {
0282     ngx_stream_realip_srv_conf_t  *conf;
0283 
0284     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_realip_srv_conf_t));
0285     if (conf == NULL) {
0286         return NULL;
0287     }
0288 
0289     /*
0290      * set by ngx_pcalloc():
0291      *
0292      *     conf->from = NULL;
0293      */
0294 
0295     return conf;
0296 }
0297 
0298 
0299 static char *
0300 ngx_stream_realip_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
0301 {
0302     ngx_stream_realip_srv_conf_t *prev = parent;
0303     ngx_stream_realip_srv_conf_t *conf = child;
0304 
0305     if (conf->from == NULL) {
0306         conf->from = prev->from;
0307     }
0308 
0309     return NGX_CONF_OK;
0310 }
0311 
0312 
0313 static ngx_int_t
0314 ngx_stream_realip_add_variables(ngx_conf_t *cf)
0315 {
0316     ngx_stream_variable_t  *var, *v;
0317 
0318     for (v = ngx_stream_realip_vars; v->name.len; v++) {
0319         var = ngx_stream_add_variable(cf, &v->name, v->flags);
0320         if (var == NULL) {
0321             return NGX_ERROR;
0322         }
0323 
0324         var->get_handler = v->get_handler;
0325         var->data = v->data;
0326     }
0327 
0328     return NGX_OK;
0329 }
0330 
0331 
0332 static ngx_int_t
0333 ngx_stream_realip_init(ngx_conf_t *cf)
0334 {
0335     ngx_stream_handler_pt        *h;
0336     ngx_stream_core_main_conf_t  *cmcf;
0337 
0338     cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
0339 
0340     h = ngx_array_push(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers);
0341     if (h == NULL) {
0342         return NGX_ERROR;
0343     }
0344 
0345     *h = ngx_stream_realip_handler;
0346 
0347     return NGX_OK;
0348 }
0349 
0350 
0351 static ngx_int_t
0352 ngx_stream_realip_remote_addr_variable(ngx_stream_session_t *s,
0353     ngx_stream_variable_value_t *v, uintptr_t data)
0354 {
0355     ngx_str_t                *addr_text;
0356     ngx_stream_realip_ctx_t  *ctx;
0357 
0358     ctx = ngx_stream_get_module_ctx(s, ngx_stream_realip_module);
0359 
0360     addr_text = ctx ? &ctx->addr_text : &s->connection->addr_text;
0361 
0362     v->len = addr_text->len;
0363     v->valid = 1;
0364     v->no_cacheable = 0;
0365     v->not_found = 0;
0366     v->data = addr_text->data;
0367 
0368     return NGX_OK;
0369 }
0370 
0371 
0372 static ngx_int_t
0373 ngx_stream_realip_remote_port_variable(ngx_stream_session_t *s,
0374     ngx_stream_variable_value_t *v, uintptr_t data)
0375 {
0376     ngx_uint_t                port;
0377     struct sockaddr          *sa;
0378     ngx_stream_realip_ctx_t  *ctx;
0379 
0380     ctx = ngx_stream_get_module_ctx(s, ngx_stream_realip_module);
0381 
0382     sa = ctx ? ctx->sockaddr : s->connection->sockaddr;
0383 
0384     v->len = 0;
0385     v->valid = 1;
0386     v->no_cacheable = 0;
0387     v->not_found = 0;
0388 
0389     v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1);
0390     if (v->data == NULL) {
0391         return NGX_ERROR;
0392     }
0393 
0394     port = ngx_inet_get_port(sa);
0395 
0396     if (port > 0 && port < 65536) {
0397         v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
0398     }
0399 
0400     return NGX_OK;
0401 }