Last active
October 31, 2019 10:47
-
-
Save akhiljalagam/c93b565842a9f9d55aca7652814c5967 to your computer and use it in GitHub Desktop.
grafana proxying dashboard queries based on user account...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
worker_processes 2; | |
events { | |
worker_connections 1024; | |
} | |
http { | |
# access_log off; | |
access_log /var/log/nginx/access.log; | |
keepalive_timeout 65; | |
resolver 8.8.8.8; | |
# leaving here in case we need some lua code as we used to have in here (see git) | |
lua_ssl_trusted_certificate "root-certs.pem"; | |
lua_ssl_verify_depth 2; | |
lua_package_path "$prefix/lualib/?.lua;;"; | |
lua_shared_dict locks 1M; | |
lua_shared_dict cache 10M; | |
# see https://github.com/openresty/lua-resty-core | |
init_by_lua ' | |
require "resty.core" | |
'; | |
# ================================================= | |
# https rewrites | |
# ================================================= | |
# http traffic redirects to HTTPS | |
server { | |
listen 80; | |
server_name www.rhythmon.com; | |
rewrite ^/(.*) https://www.rhythmon.com/$1 permanent; | |
} | |
server { | |
listen 80; | |
server_name forums.rhythmon.com; | |
rewrite ^/(.*) https://forums.rhythmon.com/$1 permanent; | |
} | |
# http apex zone traffic redirects to https on www. | |
server { | |
listen 80; | |
server_name rhythmon.com; | |
rewrite ^/(.*) https://www.rhythmon.com/$1 permanent; | |
} | |
# ================================================= | |
# forums | |
# ================================================= | |
server { | |
listen 443 ssl; | |
server_name forums.rhythmon.com; | |
ssl_certificate /opt/openresty/nginx/certs/forums.rhythmon.crt; | |
ssl_certificate_key /opt/openresty/nginx/certs/forums.key; | |
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
# ssl_ciphers HIGH:!aNULL:!MD5; | |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
ssl_prefer_server_ciphers on; | |
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; | |
root /opt/openresty/nginx/html; | |
index index.html index.htm; | |
# all other traffic to the spring app, which does its own protection with spring security + pac4j | |
location / { | |
proxy_pass http://forums.int.rhythmon.com:5080/; | |
} | |
} | |
# ================================================= | |
# spring and grafana | |
# ================================================= | |
server { | |
listen 443 ssl; | |
server_name www.rhythmon.com; | |
ssl_certificate /opt/openresty/nginx/certs/www.rhythmon.crt; | |
ssl_certificate_key /opt/openresty/nginx/certs/host.key; | |
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
# ssl_ciphers HIGH:!aNULL:!MD5; | |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
ssl_prefer_server_ciphers on; | |
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; | |
root /opt/openresty/nginx/html; | |
index index.html index.htm; | |
# redirect root visitors to home page within web app | |
#location = / { | |
# return 301 https://www.rhythmon.com/a; | |
#} | |
# endpoints that get passed straight through to grafana, no security | |
location /g/dashboard/snapshot/ { | |
proxy_pass http://grafana.int.rhythmon.com:3000/dashboard/snapshot/; | |
} | |
location /g/public/ { | |
proxy_pass http://grafana.int.rhythmon.com:3000/public/; | |
} | |
# It seems nginx needs two entries in this case - if I omit this one, the one below matches /g/api/snapshots, but proxies with | |
# a trailing /, i.e. /g/api/snapshots/, which causes a 404 in grafana | |
# | |
location /g/api/snapshots { | |
auth_request /auth/hard; | |
auth_request_set $email $upstream_http_x_rhythmon_email; | |
auth_request_set $grafanaUser $upstream_http_x_rhythmon_grafanauser; | |
proxy_set_header x-user $grafanaUser; | |
proxy_pass http://grafana.int.rhythmon.com:3000/api/snapshots; | |
} | |
# soft auth is needed here: anyone can GET, but to POST, the user must be logged in. | |
location /g/api/snapshots/ { | |
auth_request /auth/soft; | |
auth_request_set $email $upstream_http_x_rhythmon_email; | |
auth_request_set $grafanaUser $upstream_http_x_rhythmon_grafanauser; | |
proxy_set_header x-user $grafanaUser; | |
proxy_pass http://grafana.int.rhythmon.com:3000/api/snapshots/; | |
} | |
# Endpoint for database queries that grafana proxies straight through to influxdb. We intercept them | |
# and inject our own where clause to filter by account ID for just the logged in user's data, effectively adding user-level security to | |
# grafana and influxdb. Sample query url: | |
# | |
# GET http://influxdb.int.rhythmon.com/api/datasources/proxy/1/query?db=heart&q=SELECT mean("value") FROM "reversalEvent" | |
# WHERE "windowSize" = '5' AND time > 1463187791s and time < 1463360289s GROUP BY time(1m) fill(null)&epoch=ms | |
location /g/api/datasources/proxy/1/query { | |
# this auth service returns user's email, account ID in response headers along | |
# with the original query but with an account filter injected into it | |
auth_request /auth/hard/withQueryMunging/targettingInfluxDB; | |
auth_request_set $email $upstream_http_x_rhythmon_email; | |
auth_request_set $filteredQuery $upstream_http_x_filtered_query; | |
auth_request_set $grafanaUser $upstream_http_x_rhythmon_grafanauser; | |
access_by_lua_block { | |
ngx.log(ngx.STDERR, "setting grafana user to " .. ngx.var.grafanaUser) | |
ngx.log(ngx.STDERR, "filtered query is " .. ngx.var.filteredQuery) | |
} | |
proxy_set_header x-user $grafanaUser; | |
proxy_pass http://grafana.int.rhythmon.com:3000/api/datasources/proxy/1/query?db=heart&epoch=ms&q=$filteredQuery; | |
} | |
# same as above, but for datasource 2 - i.e. a spring endpoint over the mysql instance that emulates the influxdb protocol | |
location /g/api/datasources/proxy/4/query { | |
auth_request /auth/hard/withQueryMunging/targettingMysql; | |
auth_request_set $filteredQuery $upstream_http_x_filtered_query; | |
proxy_pass http://spring.int.rhythmon.com:8080/api/influxDBMysql/query?query=$filteredQuery; | |
} | |
# default for remaining grafana endpoints (as per https://github.com/grafana/grafana/issues/2066) | |
# that don't need any rewriting, just hard security | |
location /g/ { | |
auth_request /auth/hard; | |
auth_request_set $email $upstream_http_x_rhythmon_email; | |
# auth_request_set $userID $upstream_http_x_rhythmon_userid; | |
auth_request_set $grafanaUser $upstream_http_x_rhythmon_grafanauser; | |
access_by_lua_block { | |
ngx.log(ngx.STDERR, "setting grafana user to " .. ngx.var.grafanaUser) | |
} | |
proxy_set_header x-user $grafanaUser; | |
proxy_pass http://grafana.int.rhythmon.com:3000/; | |
} | |
# all other traffic to the spring app, which does its own protection with spring security + pac4j | |
location / { | |
proxy_pass http://spring.int.rhythmon.com:8080/; | |
} | |
#============================ | |
# auth calls against the local spring app | |
#============================ | |
location = /auth/soft { | |
proxy_pass http://spring.int.rhythmon.com:8080/api/authCheck/soft; | |
proxy_pass_request_body off; | |
proxy_set_header Content-Length ""; | |
proxy_set_header X-Original-URI $request_uri; | |
} | |
location = /auth/hard { | |
proxy_pass http://spring.int.rhythmon.com:8080/api/authCheck/hard; | |
proxy_pass_request_body off; | |
proxy_set_header Content-Length ""; | |
proxy_set_header X-Original-URI $request_uri; | |
} | |
location = /auth/hard/withQueryMunging/targettingInfluxDB { | |
proxy_pass http://spring.int.rhythmon.com:8080/api/authCheck/hard/withQueryMunging/targettingInfluxDB; | |
proxy_pass_request_body off; | |
proxy_set_header Content-Length ""; | |
proxy_set_header X-Original-URI $request_uri; | |
} | |
location = /auth/hard/withQueryMunging/targettingMysql { | |
proxy_pass http://spring.int.rhythmon.com:8080/api/authCheck/hard/withQueryMunging/targettingMysql; | |
proxy_pass_request_body off; | |
proxy_set_header Content-Length ""; | |
proxy_set_header X-Original-URI $request_uri; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment