はじめに
GCPのCloud Shell環境(ウェブでプレビュー)でGrafanaの動作確認をしていたら「origin not allowed」というエラーが出るようになってしまった。
原因
同じような状況を調べたところ、CSRF対策の機能が追加されたことで、GCPのCloud Shell環境では正常に動作しなくなったことがわかった。
パケットキャプチャ
tcpdumpコマンドでブラウザからGrafanaへのアクセスを確認したところ、HostヘッダとOriginヘッダの値が異なっている(一致していない)ことを確認できた。
Host: 127.0.0.1:3001
Origin: https://3001-cs-911836254277-default.cs-asia-east1-jnrc.cloudshell.dev
※ Cloud Shell環境でエディタ(Eclipse Theia)を開くとポート:3000が使用されてしまい、Grafanaのデフォルトのポート番号と重複するため、起動時にポート:3001に変更しています。
解決方法
1. ngrokを使用する
Cloud Shell環境のウェブでプレビューを使用しない方法です。
手順
ngrokのホームページへアクセスし、「Sign up for free」を押してアカウントを登録します。
アカウント登録後、「Login」を押してログインします。
ログイン後、アクセストークンを取得します。(ngrokのダウンロードとインストールはコマンドラインから行います)
左側のメニューから「Your Authtoken」を選択します。
アクセストークンの情報を控えます。
ngrokのソフトウェア(バイナリファイル)をダウンロードして解凍します。
$ wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz
$ tar xvzf ngrok-v3-stable-linux-amd64.tgz
アクセストークンの情報を登録します。
$ ./ngrok config add-authtoken [アクセストークンの情報]
ngrokを起動します。
$ ./ngrok http 3001
起動後の画面で、「Forwarding」に表示されるURLへアクセスします。(URLは起動する度に変わります)
ngrok (Ctrl+C to quit)
Hello World! https://ngrok.com/next-generation
Session Status online
Account Ayachika Kitazaki (Plan: Free)
Version 3.0.6
Region United States (us)
Latency -
Web Interface http://127.0.0.1:4040
Forwarding https://78ff-34-81-87-94.ngrok.io -> http://localhost:3001
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
2. Reverse Proxy (Nginx)を使用する
Grafana公式ではReverse Proxy(Nginx または Apache)を使用して回避する方法が提示されています。
手順
NginxとGrafanaのコンフィグファイルに設定を追加する必要があります。
NginxとGrafanaをDockerでインストールする前提で設定例を示します。
Nginxのコンフィグ(default.conf)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location /grafana/ {
rewrite ^/grafana/(.*) /$1 break;
proxy_set_header Host $http_host;
proxy_set_header Origin http://$http_host;
proxy_pass http://host.docker.internal:3001/; }
location /grafana/api/live/ {
rewrite ^/grafana/(.*) /$1 break;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_set_header Origin http://$http_host;
proxy_pass http://host.docker.internal:3001/;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
Grafanaのコンフィグ(grafana.ini)
※ コンフィグファイルのサイズが大きいため、Serverカテゴリの変更箇所だけ記載します。
- ポート番号(http_port)はGCPのCloud Shell環境でエディタ(Eclipse Theia)を開くとポート:3000が使用されてしまうため、ポート:3001に変更しています。
- ドメイン(domain)はDocker環境からホスト環境(別のDocker環境)のGrafanaへアクセスするため、設定しています。
- ルートURL(root_url)はNginxのルート(/)からの相対パス(/grafana)でアクセスするため、設定しています。
- サブパス(serve_from_sub_path)はNginxのルート(/)からの相対パス(/grafana)でアクセスするため、設定しています。
#################################### Server ####################################
[server]
# The http port to use
http_port = 3001
# The public facing domain name used to access grafana from a browser
domain = host.docker.internal
# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
serve_from_sub_path = true
次にdockerコマンドでNginxとGrafanaをインストールします。
コンフィグファイルはホームディレクトリにある前提で実行します。
$ docker run -d -p 8080:80 --name nginx --add-host=host.docker.internal:host-gateway -v `pwd`/default.conf:/etc/nginx/conf.d/default.conf nginx
$ docker run -d -p 3001:3001 --name=grafana -v `pwd`/grafana.ini:/etc/grafana/grafana.ini grafana/grafana:latest
正常に起動しているか確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a6222957eb05 grafana/grafana:latest "/run.sh" 3 minutes ago Up 3 minutes 3000/tcp, 0.0.0.0:3001->3001/tcp grafana
049eb4852b68 nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp nginx
ブラウザでプレビュー(ポート:8080)を実行します。
Nginxの初期画面(index.html)が表示されます。
URLの最後に/grafanaを付けてアクセスします。
https://8080-cs-911836254277-default.cs-asia-east1-jnrc.cloudshell.dev/grafana/
(参考)
デフォルトのコンフィグファイルをDocker環境からコピーしたい場合、次のコマンドを実行します。
$ docker cp nginx:/etc/nginx/conf.d/default.conf .
$ docker cp grafana:/etc/grafana/grafana.ini .