nginx - get value of the header - x_forwarded_for in Nginx module (Naxsi)

Marcin Kozlowski marcinguy at gmail.com
Mon Dec 30 15:47:59 UTC 2019


I don't work with NGINX and modules and C daily.

Still struggling with it. Feel free to contact me via the list or to avoid
spamming privately. Help will be greatly appreciated.

Trying to add whitelisting of IP to NAXSI

https://github.com/nbs-system/naxsi



How can I add simply one entry being IP to headers_ar?



  headers_ar = ngx_array_create(cf->pool, 1, sizeof(ngx_hash_key_t));

  ngx_array_t *headers_ar_c;
  headers_ar_c = ngx_array_push(headers_ar);

  hash_init.key = &ngx_hash_key_lc;
  hash_init.pool = cf->pool;
  hash_init.temp_pool = NULL;
  hash_init.max_size  = 1024;
  hash_init.bucket_size = 512;


  dlc->passr_headers_hash =  (ngx_hash_t*) ngx_pcalloc(cf->pool,
sizeof(ngx_hash_t));
    hash_init.hash = dlc->passr_headers_hash;
    hash_init.name = "passr_headers_hash";

    if (ngx_hash_init(&hash_init, (ngx_hash_key_t*) headers_ar->elts,
                      headers_ar->nelts) != NGX_OK) {
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "$HEADERS hashtable init
failed"); /* LCOV_EXCL_LINE */
      return (NGX_ERROR); /* LCOV_EXCL_LINE */
    }

    else {
      NX_LOG_DEBUG(_debug_whitelist, NGX_LOG_EMERG, cf, 0, "$HEADERS
hashtable init successed %d !",
                         dlc->passr_headers_hash->size);
    }



  return (NGX_OK);





Later I have a function that looks for it in hash

Find in hash function:

ngx_http_pass_rule_t *
nx_find_pass_in_hash(
                ngx_http_request_t *req,
                ngx_str_t *mstr,
                ngx_http_dummy_loc_conf_t *cf,
                enum DUMMY_MATCH_ZONE zone)
{
ngx_http_pass_rule_t    *b = NULL;

ngx_uint_t   key;

ngx_str_t scratch = {.data = mstr->data, .len = mstr->len};

ngx_str_t k1 = ngx_string("key1");
key = ngx_hash_key(scratch.data, scratch.len);

b  = (ngx_http_pass_rule_t*)  ngx_hash_find(cf->passr_headers_hash, key,
k1.data, k1.len);
if (b == NULL) {
    /* key not found */
  NX_DEBUG(_debug_custom_score,           NGX_LOG_DEBUG_HTTP,
req->connection->log, 0,
                "find hash 1");

}else{
 NX_DEBUG(_debug_custom_score,           NGX_LOG_DEBUG_HTTP,
req->connection->log, 0,
                "find hash 2");


}

return b;

}

Thanks,




On Sun, Dec 29, 2019 at 3:27 AM Hung Nguyen <hungnv at opensource.com.vn>
wrote:

> Hello,
>
> I suggest you to read nginx development guide which is available on
> nginx.org.
>
> About getting x forward for headers, if you take a look at some built in
> module there’s already exist implementation which takes the headers and
> returns an array.
>
> --
> Hưng
>
> On Dec 29, 2019, at 03:49, Robert Paprocki <
> rpaprocki at fearnothingproductions.net> wrote:
>
> The array has 0 nelts because you haven’t added anything to do. nelts is
> the number of elements in the array, not the size of the array.
>
> Add an element to the array with ngx_array_push().
>
> On Dec 28, 2019, at 11:35, Marcin Kozlowski <marcinguy at gmail.com> wrote:
>
> 
> Still have few questions. Help would be great
>
> Beginner in writing NGINX modules
>
> Have this question
>
> 1) How do I create array, add element to it and than create a hashtable
> from it.
>
> Below I try to achieve it:
>
> NX_LOG_DEBUG(_debug_whitelist_heavy,
> NGX_LOG_EMERG, cf, 0,
>                "finalizing hashtables array %i",  dlc->pass_rules->nelts);
>
> headers_ar = ngx_array_create(cf->pool, dlc->pass_rules->nelts,
> sizeof(ngx_hash_key_t));
>
>
>
> if (headers_ar) {
>     NX_LOG_DEBUG(_debug_readconf,  NGX_LOG_EMERG, cf, 0,
>                "headers array %i",headers_ar->nelts);
>
> 2) Why headers_ar has 0 elemets
>
> nginx: [emerg] finalizing hashtables array 6 in /etc/nginx/nginx.conf:124
> nginx: [emerg] headers array 0 in /etc/nginx/nginx.conf:124
>
>
>
> 3) I later want to build hashtable based on this array:
>
>     dlc->passr_headers_hash =  (ngx_hash_t*) ngx_pcalloc(cf->pool,
> sizeof(ngx_hash_t));
>     hash_init.hash = dlc->passr_headers_hash;
>     hash_init.name = "passr_headers_hash";
>
>
>
>     if (ngx_hash_init(&hash_init, (ngx_hash_key_t*) headers_ar->elts,
>                       headers_ar->nelts) != NGX_OK) {
>       ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "$HEADERS hashtable init
> failed"); /* LCOV_EXCL_LINE */
>       return (NGX_ERROR); /* LCOV_EXCL_LINE */
>     }
>
>     else {
>       NX_LOG_DEBUG(_debug_whitelist, NGX_LOG_EMERG, cf, 0, "$HEADERS
> hashtable init successed %d !",
>                          dlc->passr_headers_hash->size);
>     }
>
>
>
> 4) Can somebody post simple code that
>
> a) creates array
> b) pushes one IP
> c) create hashtable from it
>
> Thanks,
>
>
> On Sat, Dec 28, 2019 at 3:36 PM Marcin Kozlowski <marcinguy at gmail.com>
> wrote:
>
>> Ignore my last post.
>>
>> My error.
>>
>> Thanks,
>>
>> On Fri, Dec 27, 2019 at 11:42 PM Marcin Kozlowski <marcinguy at gmail.com>
>> wrote:
>>
>>> Thanks. Almost got my modifications to NAXSI ready.
>>>
>>> But currently have a blocker with getting just the X-Forwarded-for IP
>>>
>>> The code below:
>>>
>>> ngx_uint_t n;
>>> ngx_table_elt_t **h;
>>> ngx_array_t a;
>>> a = req->headers_in.x_forwarded_for;
>>> n = a.nelts;
>>> h = a.elts;
>>>
>>>
>>> for (i = 0; i<n; i++) {
>>>    ngx_log_error(NGX_LOG_ERR, req->connection->log,
>>>               0, "x_forwarded_for: %s", h[i]->value.data);
>>> }
>>>
>>> gets a String with several IP (i.e client, server, request etc)
>>>
>>> Tried to parse the string using strtok(), interating through it .... but
>>> it segfaults. I guess I am missing some NGINX module knowledge.
>>>
>>> How to properly get first string up to first "," from the
>>> h[i]->value.data using NGINX functions/types or other correct way to do it.
>>>
>>> Thanks,
>>>
>>>
>>>
>>>
>>>
>>> On Wed, Dec 25, 2019 at 12:17 PM Ruslan Ermilov <ru at nginx.com> wrote:
>>>
>>>> On Tue, Dec 24, 2019 at 08:00:26PM +0100, Marcin Kozlowski wrote:
>>>> > Thanks.
>>>> >
>>>> > Works. For the reference, this is the code I used:
>>>> >
>>>> >   ngx_uint_t n;
>>>> >   ngx_table_elt_t **h;
>>>> >   ngx_array_t a;
>>>> >   a = req->headers_in.x_forwarded_for;
>>>> >   n = a.nelts;
>>>> >   h = a.elts;
>>>> >
>>>> >
>>>> >   for (i = 0; i<n; i++) {
>>>> >     ngx_log_error(NGX_LOG_ERR, req->connection->log,
>>>> >               0, "x_forwarded_for: %s", h[i]->value.data);
>>>> >   }
>>>> >
>>>> > BTW What would be the best practice in NGINX NASIX module or any other
>>>> > module to load a file with hundreds entries of IPs (hashmap, or what
>>>> > structure would be best?) which should be whitelisted later for
>>>> comparison
>>>> > in NASIX module logic. Those IP should never be blocked by NAXSI.
>>>> >
>>>> > When should I load this file in memory, in which component
>>>> > /module/function/step?
>>>> >
>>>> > Links to some guides/sample code would be also appreciated.
>>>> >
>>>> > Thanks,
>>>>
>>>> http://nginx.org/en/docs/http/ngx_http_geo_module.html
>>>> _______________________________________________
>>>> nginx-devel mailing list
>>>> nginx-devel at nginx.org
>>>> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>>>>
>>> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20191230/9fd946c4/attachment.htm>


More information about the nginx-devel mailing list