CORS configuration for authenticated users through access_by_lua_file


(Rafal Bialek) #1

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


(Bill McConaghy) #2

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


(system) #3

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