Grafana
刘梦凯 Lv3

配置grafana的免密反向代理 访问dashboard & panel

grafana免密

什么叫做免密反向代理?我们在grafana中分享出来的panel的link,是下面样式的

1
http://localhost:3000/gf/d/173XYzd7z/clickhouse-performance-monitor?orgId=1&from=1657692410493&to=1657694210493&viewPanel=30

如果我们在别的机器上打开就需要我们输入账号和密码,如果我做了一个监控页面,内嵌了grafana的页面,我点开我的监控,还需要手动输入grafana的账号密码,这就比较难受,有没有什么办法不用输入呢?

这就需要 grafana 的 API tokens,这个API token 官方给出的使用方法是我们可以通过命令行来操作dashboard 或者 alert预警之类的,但是我们只需要用来认证即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 按照文档在本机上生成key的过程
curl -X POST -H "Content-Type: application/json" -d '{"name":"apiorg"}' http://admin:admin@localhost:3000/api/orgs
{"message":"Organization created","orgId":2}%

curl -X POST -H "Content-Type: application/json" -d '{"loginOrEmail":"admin", "role": "Admin"}' http://admin:admin@localhost:3000/api/orgs/2/users

curl -X POST http://admin:admin@localhost:3000/api/user/using/1

# 上面就是我们生成的key,注意只出现一次,记录下来
curl -X POST -H "Content-Type: application/json" -d '{"name":"apikeycurl", "role": "Admin"}' http://admin:admin@localhost:3000/api/auth/keys
{"id":1,"name":"apikeycurl","key":"eyJrIjoidTJPdm1mbDRBZHlzaVBTNHV1cmZiMjZ6N3l3ZG9VbTQiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjoyfQ=="}%

# 通过key访问我们的share link
curl -H "Authorization: Bearer eyJrIjoidTJPdm1mbDRBZHlzaVBTNHV1cmZiMjZ6N3l3ZG9VbTQiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjoyfQ==" http://localhost:3000/gf/d/173XYzd7z/clickhouse-performance-monitor?

grafana打开反向代理配置

参考 官方文档 设置我们在grafan中的代理配置

1
2
3
4
# vim conf/defaults.ini
domain = localhost
root_url = %(protocol)s://%(domain)s:%(http_port)s/gf/
serve_from_sub_path = true

反向代理的两种方式

nginx配置反向代理

安装nginx这里不再赘述,详细可以参考这里

我的nginx使用的homebrew安装,首先查看nginx相关信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
(base) ➜  brew info nginx
nginx: stable 1.21.3 (bottled), HEAD
HTTP(S) server and reverse proxy, and IMAP/POP3 proxy server
https://nginx.org/
/opt/homebrew/Cellar/nginx/1.21.3 (26 files, 2.2MB) *
Poured from bottle on 2022-06-16 at 17:13:49
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/nginx.rb
License: BSD-2-Clause
==> Dependencies
Required: openssl@1.1 ✔, pcre ✔
==> Options
--HEAD
Install HEAD version
==> Caveats
Docroot is: /opt/homebrew/var/www

The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /opt/homebrew/etc/nginx/servers/.

To restart nginx after an upgrade:
brew services restart nginx
Or, if you don't want/need a background service you can just run:
/opt/homebrew/opt/nginx/bin/nginx -g daemon off;
==> Analytics
install: 38,896 (30 days), 91,488 (90 days), 455,183 (365 days)
install-on-request: 38,823 (30 days), 91,297 (90 days), 454,267 (365 days)
build-error: 48 (30 days)
1
2
3
The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.
这行我们可以了解到默认nginx配置文件是/opt/homebrew/etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
修改我们的nginx.conf文件

#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
worker_connections 1024;
}


http {
include mime.types;
default_type application/octet-stream;

sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 主要是下面的配置
server {
listen 8888; # 源端口
root /opt/homebrew/var/www; # 根 主页目录 保持默认即可
location /gf {
proxy_pass http://localhost:3000; # 目标域名以及端口
proxy_set_header Authorization "Bearer eyJrIjoiRWZOVElUTHRwYkt0VVgwVkNpMmppTElsUUgxOXpxZUIiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjoxfQ=="; # 申请的grafana 组的秘钥
}
}
include servers/*;
}

上面就是我们的nginx配置,主要是其中的server配置,注意秘钥配置中间都是空格没有冒号。

到此为止nginx配置反向代理就完成了,接下来我们看怎么用go语言来实现一个grafana反向代理

go实现反向代理

加入你不想在grafana服务器上再部署一个nginx服务器,那么我们尝试用go来实现一个反向代理服务。

参考这篇文章,我们实现了一个简单的go服务反向代理,下面是主要的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package main

import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
)

// NewProxy takes target host and creates a reverse proxy
func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
url, err := url.Parse(targetHost)
if err != nil {
return nil, err
}

proxy := httputil.NewSingleHostReverseProxy(url)

originalDirector := proxy.Director
proxy.Director = func(req *http.Request) {
originalDirector(req)
modifyRequest(req)
}

//proxy.ModifyResponse = modifyResponse()
proxy.ErrorHandler = errorHandler()
return proxy, nil
}

func modifyRequest(req *http.Request) {

// 需要将请求链接中的Host改为grafana的Host

req.URL.Host = "localhost:3000"
req.Host = "localhost:3000"
fmt.Printf("url: %s \n", req.URL)
fmt.Printf("host: %s \n", req.Host)

// 将grafana api key 设置进请求的header中
req.Header.Set("Authorization", " Bearer eyJrIjoiRWZOVElUTHRwYkt0VVgwVkNpMmppTElsUUgxOXpxZUIiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjoxfQ==")
req.Header.Set("Access-Control-Allow-Origin", "*")
req.Header.Set("Access-Control-Allow-Methods", "*")
req.Header.Set("Access-Control-Allow-Credentials", "true")
}

func errorHandler() func(http.ResponseWriter, *http.Request, error) {
return func(w http.ResponseWriter, req *http.Request, err error) {
fmt.Printf("Got error while modifying response: %v \n", err)
return
}
}

// ProxyRequestHandler handles the http request using proxy
func ProxyRequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
proxy.ServeHTTP(w, r)
}
}

func main() {
// initialize a reverse proxy and pass the actual backend server url here
proxy, err := NewProxy("http://localhost:3000")
//proxy, err := NewProxy("http://localhost:3000")
if err != nil {
panic(err)
}

// handle all requests to your server using the proxy
http.HandleFunc("/", ProxyRequestHandler(proxy))
log.Fatal(http.ListenAndServe(":8888", nil))
}

这样我们访问localhost:8888的时候就会自动跳转到localhost:3000,到此为止两种免密grafana配置就完成了。

  • Post title:Grafana
  • Post author:刘梦凯
  • Create time:2022-07-12 20:53:21
  • Post link:https://liumengkai.github.io/2022/07/12/反向代理Grafana的两种方法/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.