How can I deny access to certain dashboards in Kibana 6.x with openresty?

30 views
Skip to first unread message

Sacha Yunusic

unread,
Dec 27, 2018, 12:51:57 PM12/27/18
to openresty-en
Hi, 
I'm configuring access to my Kibana Server 6.5.2 with openresty and works almost perfectly.
So far, I'm able to ask for credentials, permit access to Kibana, permit access to URI /app/kibana and deny access to some other URIs (e.g. /app/timelion). How I did it? I'll explain it some lines later.
What I want to do and I'm not able, is to permit access to dashboard A (uri app/kibana#/dashboard/e2972800-800c-11e8-ae57-29049408d6e7), but block access to dashboard B (uri /app/kibana#/dashboard/c33b53c0-f3dc-11e8-b918-8de2ea016f1b).
Any idead on how to do it?
Thanks.

This is what I have so far:

nginx.conf:
user root;
worker_processes
5;
error_log logs
/error.log warn;

pid logs
/nginx.pid;


events
{
worker_connections
768;
}


http
{
 default_type application
/octet-stream;

 client_max_body_size
500M;
 sendfile on
;
 keepalive_timeout
3000;
 server
{
 listen
9999 ssl;
 server_name
_Kibana_IP_;
    ssl_certificate
/etc/ssl/certs/analitica.crt;
    ssl_certificate_key
/etc/ssl/private/analitica.key;
    ssl_dhparam
/etc/ssl/certs/dhparam.pem;


 location
/ {

 proxy_pass http
://_Kibana_IP_:5601/;

 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504
;
 proxy_redirect off
;
 proxy_buffering off
;
 proxy_force_ranges on
;
 proxy_http_version
1.1;
 proxy_set_header
Upgrade $http_upgrade;
 proxy_set_header
Connection "upgrade";
 proxy_set_header
Origin "";
 proxy_set_header X
-Real-IP $remote_addr;
 proxy_set_header X
-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header
Host $http_host;
 proxy_connect_timeout
7d;
 proxy_send_timeout
7d;
 proxy_read_timeout
7d;
        auth_basic            
"Restricted";
        auth_basic_user_file kibana_access
.htpasswd;
        access_by_lua_file
'authorize.lua';
 lua_code_cache off
;
 proxy_set_header  
Authorization  "";
 
}



 
}

 
}



authorize.lua:
-- authorization rules


local restrictions = {
  all  
= {
   
["^/$"]                             = {"GET", "POST", "PUT", "DELETE" }
 
},


 sacha
= {
   
["^/$"]                             = { "GET" },
-- Next line is not working
   
["^/?[^/]*/?[^/]*/?[^/]*/?[^/]*/Dash-Help-Desk"] = {  },
   
["^/?[^/]*/?[^/]*/app/kibana"]     = { "GET" },
   
["^/?[^/]*/?[^/]*/_msearch"]        = { "GET", "POST", "PUT", "DELETE"  },
   
["/bundles"]                        = { "GET", "POST", "PUT", "DELETE"  },
   
["/plugins"]                        = { "GET", "POST", "PUT", "DELETE"  },
   
["/api"]                            = { "GET", "POST", "PUT", "DELETE"  },
   
["/ui"]                             = { "GET", "POST", "PUT", "DELETE"  }
 
}
}

-- get authenticated user as role
local role = ngx.var.remote_user
ngx
.log(ngx.DEBUG, role)


-- exit 403 when no matching role has been found
if restrictions[role] == nil then
  ngx
.header.content_type = 'text/plain'
  ngx
.log(ngx.WARN, "Unknown role ["..role.."]")
  ngx
.status = 403
  ngx
.say("403 Forbidden: You don\'t have access to this resource.")
 
return ngx.exit(403)
end


-- get URL
local uri = ngx.var.uri
ngx
.log(ngx.DEBUG, uri)


-- get method
local method = ngx.req.get_method()
ngx
.log(ngx.DEBUG, method)


local allowed  = false


for path, methods in pairs(restrictions[role]) do


 
-- path matched rules?
 
local p = string.match(uri, path)


 
local m = nil


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


 
if p and m then
    allowed
= true
    ngx
.log(ngx.NOTICE, method.." "..uri.." matched: "..tostring(m).." "..tostring(path).." for "..role)
   
break
 
end
end


if not allowed then
  ngx
.header.content_type = 'text/plain'
  ngx
.log(ngx.WARN, "Role ["..role.."] not allowed to access the resource ["..method.." "..uri.."]")
  ngx
.status = 403
  ngx
.say("You don't have access to this URL: "..uri.."")
 
return ngx.exit(403)
end



In logs/access.log this is that I see when I click on those dashboards:
_client_IP_ - sacha [27/Dec/2018:14:42:36 -0300] "GET /ui/favicons/favicon-32x32.png HTTP/1.1" 200 1140 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
_client_IP_
- sacha [27/Dec/2018:14:42:36 -0300] "GET /ui/favicons/favicon-16x16.png HTTP/1.1" 200 773 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
_client_IP_
- sacha [27/Dec/2018:14:42:36 -0300] "POST /api/saved_objects/_bulk_get HTTP/1.1" 200 890 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
_client_IP_
- sacha [27/Dec/2018:14:42:36 -0300] "GET /ui/favicons/favicon-32x32.png HTTP/1.1" 200 1140 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
_client_IP_
- sacha [27/Dec/2018:14:42:37 -0300] "GET /ui/favicons/favicon-16x16.png HTTP/1.1" 200 773 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
_client_IP_
- sacha [27/Dec/2018:14:42:37 -0300] "POST /api/saved_objects/_bulk_get HTTP/1.1" 200 2315 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
_client_IP_
- sacha [27/Dec/2018:14:42:37 -0300] "POST /elasticsearch/_msearch HTTP/1.1" 200 165 "https://_nginx_server_name_:9999/app/kibana" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"


Same access in kibana.log on the Kibana Server:
{"type":"response","@timestamp":"2018-12-27T17:46:20Z","tags":[],"pid":48452,"method":"get","statusCode":200,"req":{"url":"/ui/favicons/favicon-32x32.png","method":"get","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","accept":"image/webp,image/apng,image/*,*/*;q=0.8","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":3,"contentLength":9},"message":"GET /ui/favicons/favicon-32x32.png 200 3ms - 9.0B"}
{"type":"response","@timestamp":"2018-12-27T17:46:20Z","tags":[],"pid":48452,"method":"get","statusCode":200,"req":{"url":"/ui/favicons/favicon-16x16.png","method":"get","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","accept":"image/webp,image/apng,image/*,*/*;q=0.8","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":2,"contentLength":9},"message":"GET /ui/favicons/favicon-16x16.png 200 2ms - 9.0B"}
{"type":"response","@timestamp":"2018-12-27T17:46:20Z","tags":[],"pid":48452,"method":"post","statusCode":200,"req":{"url":"/api/saved_objects/_bulk_get","method":"post","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","content-length":"66","kbn-version":"6.5.2","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","content-type":"application/json","accept":"*/*","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":5,"contentLength":9},"message":"POST /api/saved_objects/_bulk_get 200 5ms - 9.0B"}
{"type":"response","@timestamp":"2018-12-27T17:46:21Z","tags":[],"pid":48452,"method":"get","statusCode":200,"req":{"url":"/ui/favicons/favicon-32x32.png","method":"get","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","accept":"image/webp,image/apng,image/*,*/*;q=0.8","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":2,"contentLength":9},"message":"GET /ui/favicons/favicon-32x32.png 200 2ms - 9.0B"}
{"type":"response","@timestamp":"2018-12-27T17:46:21Z","tags":[],"pid":48452,"method":"get","statusCode":200,"req":{"url":"/ui/favicons/favicon-16x16.png","method":"get","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","accept":"image/webp,image/apng,image/*,*/*;q=0.8","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":2,"contentLength":9},"message":"GET /ui/favicons/favicon-16x16.png 200 2ms - 9.0B"}
{"type":"response","@timestamp":"2018-12-27T17:46:21Z","tags":[],"pid":48452,"method":"post","statusCode":200,"req":{"url":"/api/saved_objects/_bulk_get","method":"post","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","content-length":"1036","kbn-version":"6.5.2","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","content-type":"application/json","accept":"*/*","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":8,"contentLength":9},"message":"POST /api/saved_objects/_bulk_get 200 8ms - 9.0B"}
{"type":"response","@timestamp":"2018-12-27T17:46:22Z","tags":[],"pid":48452,"method":"post","statusCode":200,"req":{"url":"/elasticsearch/_msearch","method":"post","headers":{"connection":"upgrade","x-real-ip":"_client_IP_","x-forwarded-for":"_client_IP_","host":"_nginx_server_name_:9999","content-length":"7456","accept":"application/json, text/plain, */*","kbn-version":"6.5.2","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36","content-type":"application/x-ndjson","referer":"https://_nginx_server_name_:9999/app/kibana","accept-encoding":"gzip, deflate, br","accept-language":"es-ES,es;q=0.9,en;q=0.8,pt;q=0.7,gl;q=0.6"},"remoteAddress":"_nginx_server_IP_","userAgent":"_nginx_server_IP_","referer":"https://_nginx_server_name_:9999/app/kibana"},"res":{"statusCode":200,"responseTime":5,"contentLength":9},"message":"POST /elasticsearch/_msearch 200 5ms - 9.0B"}


No mention to the Dashboard URI.
Any clues?

Regards, 

Sacha Yunusic
Reply all
Reply to author
Forward
0 new messages