CORS configuration for authenticated users through access_by_lua_file

Apologies if this post shouldn't be here and would be grateful;l if you point me in the right direction.

I hope I can get some help here as I'm struggling to get it solved.

We're using openresty as proxy service to elasticsearch back-end. Elasticsearch is available on https://es.example.com
and configs used for setting access are as follow:

  1. /usr/local/openresty/nginx/conf/nginx.conf

    user nobody;
    worker_processes auto;
    pid /run/openresty.pid;

    events {
    worker_connections 1024;
    }

    http {
    include mime.types;
    default_type application/octet-stream;

     sendfile        on;
     tcp_nopush      on;
     tcp_nodelay     on;
    
    
     keepalive_timeout  65;
    
    
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_prefer_server_ciphers on;
    
    
     access_log /var/log/openresty/access.log;
     error_log /var/log/openresty/error.log;
    
    
     gzip  on;
     gzip_disable "msie6";
    
    
     include ../sites/*;
    

    }

  2. /usr/local/openresty/nginx/sites/es.example.com.conf

    upstream es-cluster {
    server server01:9200;
    server server02:9200;
    server server03:9200;
    keepalive 900;
    }

    server {

    listen 80;
    server_name es.example.com;
    server_tokens off;

    access_log /var/log/openresty/es.example.com_access.log;
    error_log /var/log/openresty/es.example.com_error.log;

    location / {
    auth_basic "Protected Elasticsearch";
    auth_basic_user_file /usr/local/openresty/nginx/authorize/elasticsearch/users;
    access_by_lua_file /usr/local/openresty/nginx/authorize/elasticsearch/authorize.lua;

       proxy_pass http://es-cluster;
       proxy_redirect off;
       proxy_buffering off;
                 proxy_http_version      1.1;
                 proxy_set_header        Connection "Keep-Alive";
                 proxy_set_header        Proxy-Connection "Keep-Alive";
                 proxy_set_header        Host $http_host;
                 proxy_set_header        X-Real-IP $remote_addr;
                 proxy_connect_timeout   150;
                 proxy_send_timeout      900;
                 proxy_read_timeout      900;
                 proxy_buffers           16 64k;
                 proxy_busy_buffers_size 64k;
                 client_body_buffer_size 128k;
    

    }
    }

  3. /usr/local/openresty/nginx/authorize/elasticsearch/authorize.lua

    -- Users list:
    local userGroups = {
    user = "user",
    dev = "dev",
    admin = "admin",
    }

    -- Groups / Roles list:
    local restrictions = {
    user = {
    ["^/monitor*"] = { "HEAD", "GET" }
    },

    dev = {
    ["^/monitor*"] = { "HEAD", "GET", "PUT", "POST" },
    ["^/log*"] = { "HEAD", "GET", "PUT", "POST" }
    },

    admin = {
    ["^/"] = { "HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS" },
    ["^/app/
    "] = { "HEAD", "GET", "POST" }, -- Kibana
    ["^/bundles/"] = { "HEAD", "GET", "POST" }, -- Kibana
    ["^/static/
    "] = { "HEAD", "GET" }, -- Elastic-HQ
    ["^/api/*"] = { "HEAD", "GET", "POST" } -- Elastic-HQ
    },

    adminlogs = {
    ["^/log*"] = { "HEAD", "GET", "POST", "PUT", "DELETE" }
    }
    }

    -- Write 403 message function
    function write403Message ()
    ngx.header.content_type = 'text/plain'
    ngx.status = 403
    ngx.say("403 Forbidden: You don't have access to this resource.")
    return ngx.exit(403)
    end

    -- get authenticated user as role
    local user = ngx.var.remote_user -- Get user
    local role = userGroups[user] -- Get group

    -- exit 403 when no matching role has been found
    if restrictions[role] == nil then
    return write403Message()
    end

    -- get URL
    local uri = ngx.var.uri

    -- get method
    local method = ngx.req.get_method()

    local allowed = false

    for path, methods in pairs(restrictions[role]) do
    -- path matched rules?
    local p = string.match(uri, path)

    -- method matched rules?
    local m = nil
    for _, _method in pairs(methods) do
    m = m and m or string.match(method, _method)
    end

    if p and m then
    allowed = true
    break
    end
    end

    if not allowed then
    return write403Message()
    end

we're looking at enabling cors option to allow access from domain https://kibana.domain.com to https://es.example.com
The following changes were applied to elasticsearch config (es ver 2.4)
/etc/elasticsearch/elasticsearch.yml

...
http.cors.enabled: true
http.cors.allow-origin: "kibana.domain.com"
http.cors.allow-credentials: true
http.cors.allow-methods: "DELETE, GET, HEAD, OPTIONS, POST, PUT"
http.cors.allow-headers: "Origin, Accept, Content-Type, Content-Length, Authorization, X-Requested-With"
http.cors.max-age: 1728000

If authentication is disabled I can access elasticsearch but not with authentication enabled (using 'access_by_lua_file' module and user admin).
I have tried different options in server section of nginx config e.g.:

/usr/local/openresty/nginx/sites/es.example.com.conf
...
add_header 'Access-Control-Allow-Origin' 'https://kibana.domain.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Request-Method' 'OPTIONS' always;
add_header 'Access-Control-Allow-Methods' 'DELETE, GET, HEAD, OPTIONS, POST, PUT' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Accept, Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Request-Headers' 'Authorization, X-Requested-With' always;
}
}

or

/usr/local/openresty/nginx/sites/es.example.com.conf
...
proxy_set_header 'Access-Control-Allow-Origin' 'https://kibana.domain.com';
proxy_set_header 'Access-Control-Allow-Credentials' 'true';
proxy_set_header 'Access-Control-Allow-Methods' 'DELETE, GET, HEAD, OPTIONS, POST, PUT';
proxy_set_header 'Access-Control-Allow-Headers' 'Origin,Accept,Content-Length,Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
}
}

and errors i get are:
- CORS header ‘Access-Control-Allow-Origin’ does not match ‘(null)’
- CORS preflight channel did not succeed
- CORS header ‘Access-Control-Allow-Origin’ missing

Is it something that has to be enabled in '/usr/local/openresty/nginx/authorize/elasticsearch/authorize.lua' script or another nginx module has to be involved?

Any help, pointers would be greatly appreciated

Rafal

Sorry Kibana forum is not the place to ask, but also not sure where to ask. Maybe the Elasticsearch forum?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.