首页 文章

Kibana 4 代理仪表板嵌入

提问于
浏览
4

上下文

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

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

由于 Kibana 4 中尚未实施身份验证,因此通过更改仪表板嵌入 URL 中的查询,任何用户都可以显示他们无权访问的页面的仪表板。

我们的方案

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

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

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

然后我们在getAnalytics函数中使用请求

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 错误的原因。但我不知道为什么在通过 Web 应用程序重定向查询时不会发送此请求。

我也试过模块 http-proxy 和 express-http-proxy,但我面临同样的问题。

2 回答

相关问题