web-dev-qa-db-ja.com

ウェブサイトの管理パネルにグラファナグラフを安全に表示するにはどうすればよいですか?

グラファナにいくつかの素敵な区画を作成しました。ユーザーにグラファナダッシュボードに移動して二重認証を強制するのではなく、それらの一部をWebサイトの管理パネルに直接表示したいと思います(私のWebサイトで1回、グラファナで1回)。

1つのオプションは grafanaで匿名アクセスを有効にする そしてgrafanaのすべてのグラフで利用可能なshare/embed iniframeオプションを使用することです。それは大胆に機能しますが、適切なURLを知っている人がグラファナのデータを見ることができれば、それは大きな脆弱性のように思われます。

次に、grafanaに HTTP API があることを確認しましたが、特定のグラフを表示する可能性はありません。

PHP Proxy を使用してソリューションを試しました。これは、ユーザーが私のWebサイトで正しく認証されている場合に、認証ヘッダーを追加し、grafana埋め込みURLに接続します。ただし、それは機能せず、構成するのは悪夢です。

最後のオプションは、サーバー側のgrafanaからグラフのpngを取得し、私のWebサイトで認証された管理者にのみ提供することです。しかし、そのような場合、時間範囲の拡大/縮小、自動更新など、グラファナがOOTBを提供するすべてのクールなものを失います。

8
fracz

この回答 および この回答 に基づいて、ページ内に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およびnginxdockerコンテナーの構成例を以下に示します。

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 "${cors}o";
    }

    # 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;
  }
}

}

このファイルは提供された ここ に基づいていますが、重要な違いは

add_header'Access-Control-Allow-Headers''Origin、Content-Type、Accept、承認'常に;

これは、Authorizationヘッダーの設定を許可していることを示しています。

2
pt12lol