如何在我的网站管理面板中安全地显示 grafana 图表?

Posted

技术标签:

【中文标题】如何在我的网站管理面板中安全地显示 grafana 图表?【英文标题】:How to display grafana graphs in my website's admin panel securely? 【发布时间】:2017-07-07 07:49:48 【问题描述】:

我在 grafana 中创建了一些不错的情节。我想直接在我网站的管理面板中显示其中的一些,而不是强迫用户转到 grafana 仪表板并强制他们进行双重身份验证(一次用于我的网站,一次用于 grafana)。

一个选项是enable anonymous access in grafana 并使用 grafana 中每个图形可用的共享/嵌入 iframe 选项。虽然它工作得很好,但如果知道相应 URL 的任何人都可以看到 grafana 数据,这似乎是一个巨大的漏洞。

然后我看到 grafana 有 HTTP API 但我看不到在那里显示某个图表的可能性。

我尝试了一个带有php Proxy 的解决方案,如果用户在我的网站上通过了正确的身份验证,它将添加一个授权标头并连接到 grafana 嵌入 URL。但是,它不起作用,配置起来简直就是一场噩梦。

最后一个选项是从服务器端的 grafana 中获取图形的 png,并仅为我网站中经过身份验证的管理员提供它们。但是,在这种情况下,我会放弃 grafana 提供的所有 OOTB 很酷的东西,例如扩展/折叠时间范围、自动刷新等。

【问题讨论】:

您在这方面取得了进展吗? 我放弃了直接嵌入grafana图。相反,在我的应用程序中,我公开了Graphite API 的有趣部分。它们以 json 格式返回指标数据。在应用程序的管理面板中,我使用chart.js 将该数据呈现为图形。有点乏味,因为 grafana 已经使用相同的 Graphite API 做了同样的事情,但我发现没有办法在适当的限制下重用它。 谢谢。希望能解决这个问题... 显然 grafana 可以共享快照,剥离敏感信息。 grafana.com/docs/grafana/latest/sharing 【参考方案1】:

基于this answer 和this answer,我能够在我的页面中嵌入 Grafana 仪表板。

把你的iframe:

<iframe id="dashboard"></iframe>

然后使用这样的 AJAX 请求将 Grafana 的内容提供给它:

<script type="text/javascript">
  $.ajax(
    
      type: 'GET',
      url: 'http://localhost:3000/dashboard/db/your-dashboard-here',
      contentType: 'application/json',
      beforeSend: function(xhr, settings) 
        xhr.setRequestHeader(
          'Authorization', 'Basic ' + window.btoa('admin:admin')
        );
      ,
      success: function(data) 
        $('#dashboard').attr('src', 'http://localhost:3000/dashboard/db/your-dashboard-here');
        $('#dashboard').contents().find('html').html(data);
      
    
  );
</script>

AJAX 请求是强制性的,因为它使您能够使用您的凭据设置标头。

此时,由于 CORS,您从 Grafana 服务器收到空响应。您需要做的是为 Grafana 启用一些代理。下面是使用 docker-compose 配置 Grafana 和 nginx docker 容器的示例:

version: '2.1'
services:
  grafana:
    image: grafana/grafana
  nginx:
    image: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 3000:80

您要做的最后一件事是提供您的 nginx.conf 文件:

events 
    worker_connections  1024;


http 
#
# Acts as a nginx HTTPS proxy server
# enabling CORS only to domains matched by regex
# /https?://.*\.mckinsey\.com(:[0-9]+)?)/
#
# Based on:
# * http://blog.themillhousegroup.com/2013/05/nginx-as-cors-enabled-https-proxy.html
# * http://enable-cors.org/server_nginx.html
#
server 
  listen 80;

  location / 
    #if ($http_origin ~* (https?://.*\.tarunlalwani\.com(:[0-9]+)?$)) 
    #   set $cors "1";
    #
    set $cors "1";

    # OPTIONS indicates a CORS pre-flight request
    if ($request_method = 'OPTIONS') 
       set $cors "$corso";
    

    # Append CORS headers to any request from
    # allowed CORS domain, except OPTIONS
    if ($cors = "1") 
       add_header Access-Control-Allow-Origin $http_origin always;
       add_header Access-Control-Allow-Credentials  true always;
       proxy_pass      http://grafana:3000;
    

    # OPTIONS (pre-flight) request from allowed
    # CORS domain. return response directly
    if ($cors = "1o") 
       add_header 'Access-Control-Allow-Origin' '$http_origin' always;
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
       add_header 'Access-Control-Allow-Credentials' 'true' always;
       add_header 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept,Authorization' always;
       add_header Content-Length 0;
       add_header Content-Type text/plain;
       return 204;
    

    # Requests from non-allowed CORS domains
       proxy_pass      http://grafana:3000;
  



此文件基于提供的here,但重要的区别是

add_header 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept,Authorization' 总是;

这表示您允许设置Authorization 标头。

【讨论】:

将凭据放入页面的源代码是一个非常糟糕的主意 这不是问题的问题。我没有告诉您此代码已准备好推送到您的存储库。

以上是关于如何在我的网站管理面板中安全地显示 grafana 图表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中显示相对值?

如何通过 REST API 更新 Grafana 面板中的指标值

如何在 grafana 世界地图面板中显示来自石墨的坐标

php会话变量的安全性如何[重复]

如何在我的 Gatsby 博客网站中有效地显示 GIF 图像?

如何在我的 iphone 中为我的网站添加有效且受信任的安全证书?