Kibana 4代理仪表板嵌入

时间:2015-06-15 15:56:59

标签: proxy httprequest kibana kibana-4

上下文

我正在使用Node.js和Express在Web应用程序中的几个位置嵌入Kibana 4仪表板。嵌入是依赖于上下文的,这意味着根据嵌入仪表板的位置,对Elasticsearch的查询会发生变化。

此外,嵌入仪表板的某些页面仅限于拥有正确权限的某些用户。

由于Kibana 4中尚未实施身份验证,通过更改信息中心嵌入网址中的查询,任何用户都可以显示他们无法访问的网页的信息中心。

我们的解决方案

我们的想法是阻止与Kibana(端口5601)的任何外部连接,并通过我们的Web应用程序访问自定义URL并检查用户权限(代理类型)。如果用户拥有该权限,那么我们的Web应用程序会将HTTP查询转发给Kibana。由于我们的网络应用程序和Kibana位于同一台服务器上,因此不会阻止这些查询。

要路由自定义网址并检查权限,我们提供以下信息:

app.route('/items/:itemId/analytics/*')
   .all(api.requiresAccess('user'),
        api.requiresPermissions('item', 'modify'),
        items.getAnalytics);

然后我们在getAnalytics函数中使用Request

exports.getAnalytics = function (req, res) {
  var itemId = req.item.id;
  var kibanaParamsRegexp = /analytics\/(.*)/;
  var kibanaParamsMatch = kibanaParamsRegexp.exec(req.originalUrl);
  var kibanaParams = kibanaParamsMatch[1];
  var method = req.method;
  var dashboardId = 'Standard-Dashboard';

  var kibanaDashboardURL = 'http://localhost:5601';


  if (kibanaParams === '') { // First request to get the dashboard
    kibanaDashboardURL += '/#/dashboard/' + dashboardId + '?embed' +
    '&_a=(query:(query_string:(analyze_wildcard:!t,query:\'path:' + itemId + '\')))' +
    '&_g=(time:(from:now-1y,mode:quick,to:now))';
  } else { // Following requests to get the dashboard
    kibanaDashboardURL += '/' + kibanaParams;
  }

  app.logger.info('Received from the dashboard: ' + req.originalUrl);
  app.logger.info('Requesting to Kibana: ' + kibanaDashboardURL);
  app.logger.info('Query body: ' + JSON.stringify(req.body));

  if (method === 'POST') {
    var options = {
      url: kibanaDashboardURL,
      json: true,
      body: req.body
    };

    request.post(options,
      function (err, httpResponse, body) {
        if (err) {
          return console.log('POST failed: ', err);
        }
        console.log('POST successful. Sever response: ', body);
      }).pipe(res);
  } else if (method === 'GET' || method === 'HEAD') {
    request.get(kibanaDashboardURL).pipe(res);
  }
};

因此,而不是http://localhost:5601/#/dashboard/Standard-dashboard?embed&_a=(query:(query_string:(analyze_wildcard:!t,query:'path: 5539e831b5b79bf9f4b06a3c')))&_g=(time:(from:now-1y,mode:quick,to:now))
我必须使用http://localhost:8000/items/5539e831b5b79bf9f4b06a3c/analytics/检查权限。

问题

第一个请求,主要是GET和几个POST,正在顺利通过。但是在某些时候我有一个POST请求,它会收到500个内部服务器错误以响应请求,这会停止仪表板加载。

为了尝试找到问题,我将仪表板的负载与原始Kibana URL和通过Web应用程序重定向的URL之间的网络流量(在Web检查器中)进行了比较。开头是相同的,但在某些时候(在请求收到500错误之前),通过原始URL加载的仪表板会产生一个未使用重定向URL的请求。该请求为POSThttp://localhost:5601/elasticsearch/_mget?timeout=0&ignore_unavailable=true&preference=1434374357241,具有以下正文:
{"docs":[{"_index":".kibana","_type":"dashboard","_id":"Standard-Dashboard"}]}

这个请求似乎非常重要,因为它包含仪表板ID,我想它的缺席是后来产生500错误的原因。但是,当我通过网络应用程序重定向查询时,我不知道为什么不发送此请求。

我也尝试使用模块http-proxy和express-http-proxy,但我遇到了同样的问题。

2 个答案:

答案 0 :(得分:2)

对于那些正在寻找这类问题答案的人。我启用了一个位于我的Elasticsearch和Kibana之间的Nginx代理,用于配置对仪表板和图表的授权访问。在这里查看我的帖子:https://udaysagars.wordpress.com/2016/04/04/how-i-configured-authorized-access-to-kibana-dashboards/

答案 1 :(得分:1)

为了回答您的问题,Elastic Co开发了一种名为Shield的产品,该产品提供了访问控制功能。您可以为每个群集提供访问权限,为用户提供索引以及用户名&访问密码。

此外,您还可以使用用户制作的Kibana身份验证代理,该代理与Kibana完美配合,可在此处查看:

https://github.com/fangli/kibana-authentication-proxyhttps://github.com/fangli/kibana-authentication-proxy