利用Grafana的API Key+Nginx反向代理实现Grafana免登录访问
需求背景:
- 1、无需提供密码给用户,可以让用户直接浏览器免登录访问Grafana大屏
- 2、并且用户只有浏览的权限,无法配置Grafana及修改配置
- 3、直接80端口访问grafana,无需访问grafana默认的3000端口
基于以上几个要求,通过搜索引擎查询相关文章,总结出具体的实现步骤
一、修改/etc/grafana/grafana.ini
/etc/grafana/grafana.ini配置文件修改,允许嵌入
cat /etc/grafana/grafana.ini | grep allow_embedding sed -i "s/;allow_embedding = false/allow_embedding = true/g" /etc/grafana/grafana.ini cat /etc/grafana/grafana.ini | grep allow_embedding systemctl restart grafana-server
(图片点击放大查看)
二、Granfana添加API Key
拷贝一下生成的API Key
eyJrIjoiRnJjVmNURW1vdnlxQkdOTExqM29DcnJJV3g4TnQ0SEwiLCJuIjoid2Vidmlld2VyIiwiaWQiOjF9 curl -H "Authorization: Bearer eyJrIjoiRnJjVmNURW1vdnlxQkdOTExqM29DcnJJV3g4TnQ0SEwiLCJuIjoid2Vidmlld2VyIiwiaWQiOjF9" http://192.168.31.170:3000/api/dashboards/home
(图片点击放大查看)
(图片点击放大查看)
(图片点击放大查看)
三、配置nginx的yum源并安装配置nginx
1、配置nginx的yum源并安装nginx
cat > /etc/yum.repos.d/nginx.repo << \EOF [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF yum install nginx -y
(图片点击放大查看)
2、【可选】修改默认的nginx配置文件nginx.conf
可以自行修改为json格式的格式日志数据输出
[root@centos nginx]# cat nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; # log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; # access_log /var/log/nginx/access.log main; log_format json_analytics escape=json '{' '"msec": "$msec", ' # request unixtime in seconds with a milliseconds resolution '"connection": "$connection", ' # connection serial number '"connection_requests": "$connection_requests", ' # number of requests made in connection '"pid": "$pid", ' # process pid '"host": "$host", ' '"remote_addr": "$remote_addr", ' # client IP '"remote_user": "$remote_user", ' # client HTTP username '"remote_port": "$remote_port", ' # client port '"time_local": "$time_local", ' '"time_iso8601": "$time_iso8601", ' # local time in the ISO 8601 standard format '"request_method": "$request_method", ' # request method '"request": "$request", ' # full path no arguments if the request '"request_uri": "$request_uri", ' # full path and arguments if the request '"request_id": "$request_id", ' # the unique request id '"request_length": "$request_length", ' # request length (including headers and body) '"request_time": $request_time, ' '"args": "$args", ' # args '"response_status": "$status", ' # response status code '"body_bytes_sent": "$body_bytes_sent", ' # the number of body bytes exclude headers sent to a client '"bytes_sent": "$bytes_sent", ' # the number of bytes sent to a client '"http_version": "$server_protocol", ' '"http_referer": "$http_referer", ' # HTTP referer '"http_user_agent": "$http_user_agent", ' # user agent '"http_x_forwarded_for": "$http_x_forwarded_for", ' # http_x_forwarded_for '"http_x_forwarded_proto": "$http_x_forwarded_proto", ' '"http_host": "$http_host", ' # the request Host: header '"server_name": "$server_name", ' # the name of the vhost serving the request '"request_time": "$request_time", ' # request processing time in seconds with msec resolution '"upstream": "$upstream_addr", ' # upstream backend server for proxied requests '"upstream_connect_time": "$upstream_connect_time", ' # upstream handshake time incl. TLS '"upstream_header_time": "$upstream_header_time", ' # time spent receiving upstream headers '"upstream_response_time": "$upstream_response_time", ' # time spend receiving upstream body '"upstream_response_length": "$upstream_response_length", ' # upstream response length '"upstream_cache_status": "$upstream_cache_status", ' # cache HIT/MISS where applicable '"ssl_protocol": "$ssl_protocol", ' # TLS protocol '"ssl_cipher": "$ssl_cipher", ' # TLS cipher '"scheme": "$scheme", ' # http or https '"server_protocol": "$server_protocol", ' # request protocol, like HTTP/1.1 or HTTP/2.0 '"pipe": "$pipe", ' # "p" if request was pipelined, "." otherwise '"gzip_ratio": "$gzip_ratio", ' '"http_cf_ray": "$http_cf_ray"' '}'; access_log /var/log/nginx/access.log json_analytics; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
输出的json日志美化后的效果如下
(图片点击放大查看)
3、添加grafana反向代理配置
cd /etc/nginx/conf.d/ mv default.conf /opt/ vim backend_grafana.conf # 添加如下配置,其中API Key为上一步中的grafana api_key upstream grafana_server { server 127.0.0.1:3000; } server { listen 80; server_name localhost; location / { proxy_buffer_size 128k; proxy_buffers 32 128k; proxy_busy_buffers_size 128k; add_header Access-Control-Allow-Origin '*'; add_header Access-Control-Allow-Methods '*'; add_header Access-Control-Allow-Credentials true; #add_header Access-Control-Allow-Headers Authorization; set $auth 'Bearer eyJrIjoiRnJjVmNURW1vdnlxQkdOTExqM29DcnJJV3g4TnQ0SEwiLCJuIjoid2Vidmlld2VyIiwiaWQiOjF9'; proxy_set_header Host $host; proxy_set_header Authorization $auth; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://grafana_server/; } }
systemctl enable nginx systemctl start nginx firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --reload
(图片点击放大查看)
四、测试免登录效果
直接80端口访问grafana且无需输入账号密码
(图片点击放大查看)
(图片点击放大查看)
五、Tips
1、当然你也可以使用firewalld的rich-rule来控制访问80端口的来源IP
具体步骤
firewall-cmd --permanent --zone=public --remove-port=80/tcp firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address='192.168.31.100' port port="80" protocol="tcp" accept' firewall-cmd --reload
(图片点击放大查看)
例如192.168.31.60 访问grafana 80端口直接拒绝
curl -H "Authorization: Bearer eyJrIjoiRnJjVmNURW1vdnlxQkdOTExqM29DcnJJV3g4TnQ0SEwiLCJuIjoid2Vidmlld2VyIiwiaWQiOjF9" http://192.168.31.170/api/dashboards/home
(图片点击放大查看)