Skip to main content

Improve Grafana Security

Once your Grafana Server is installed, up and running, you can drasticaly improve its security and accessibility by installing an SSL Reverse Proxy, and enabling 2-Factor Authentication with Google OAuth.

Prerequisites

NGINX Reverse Proxy :

  • You must have a proper domain name; and FQDN set to your grafana’s public IP address
  • You can buy a domain name basically on any hosting site like namecheap.

2FA Google OAuth :

  • You need to have your own domain mail address (and of course a secure mail server). For example, you could have "grafana@yourdomain.com"
  • You need to create a Google account with this mail address.

Nginx Reverse Proxy

The main issue if you want to access your Grafana Dashboard from anywhere, out-of-the-box, is that you have to expose the application port (http:3000 by default) on the public address of your server. To avoid that, a popular solution is to simply create an SSH tunnel with a port forwarding option to your Grafana Server. A more elegant and still secure solution is to configure a reverse proxy, with an SSL certificate.

Nginx installation

Install nginx

sudo apt install nginx

Check nginx status

sudo systemctl status nginx

Create Firewall Rules on your server

Ports 80 and 443 need to be opened on your Grafana server. Nginx will automatically forward any HTTP requests to HTTPS, but it’s important to have both open, in order for Certbot to renew your SSL certificate every 3 month. Here is an example with UFW : deny any incoming connections, except SSH, HTTP and HTTPS, an allow any outgoing connections. Modify to suit your needs, especially if you are running Grafana on a Stake Pool Relay server, you'll need to add Cardano Port.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Now you should be able to visit your server's public IP address : http://your-ip-address which should lead to the default Nginx page.

Create and edit an nginx config file for your Grafana server

(change with your actual FQDN like grafana.yourdomain.com)

cd /etc/nginx/sites-enabled
sudo nano <your FQDN>.conf

Add this block

server { 
listen 80;
server_name <your FQDN>;

location / {
proxy_set_header Host $http_host;
proxy_pass http://localhost:3000/;
}
}

Save your file and restart Nginx

sudo systemctl restart nginx

Now access your monitoring server http://your-FQDN : you should see the Grafana login page.

Nginx cleanup : remove the default enabled site

rm /etc/nginx/sites-enabled/default

SSL certificate installation

Now that we have a working Reverse Proxy on our monitoring server, we are going to add SSL layer to encrypt properly access to your Cardano Stakepool Grafana dashboard. To do this, we are going to use a free SSL certificate provider, Let’s Encrypt, with Certbot.

Use snap to install certbot

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot

Make a sym link so you can use certbot command anywhere

sudo ln -s /snap/bin/certbot /usr/bin/certbot

Start the installation and follow the instructions

sudo certbot --nginx

Respond to prompts to configure your HTTPS settings (FQDN,email..). At the end of installation, you should be able to access your Grafana Server with HTTPS :

https://your-FQDN

Post install nginx hardening

Block any unwanted HTTP method, except PUT POST GET and HEAD and configure websocket

sudo nano /etc/nginx/sites-enabled/<your FQDN.conf>

Paste this line inside your "location /" block :

limit_except PUT GET HEAD POST { deny all; }

Paste this sub-block inside the first "server {" block

# Proxy Grafana Live WebSocket connections.
location /api/live/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_pass http://grafana;
}

Save and close.

Nginx configuration file hardening

sudo nano /etc/nginx/nginx.conf

Remove old cipher suites TLSv1.0 and TLSv1.1 : the SSL Settings should look like this :

##
# SSL Settings
##

ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

Prevent DoS and Buffer Oversized attacks : add this lines inside "http" block :

## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size 3K;
client_header_buffer_size 3k;
client_max_body_size 80k;
large_client_header_buffers 2 10k;
## END: Size Limits & Buffer Overflows ##

### Directive describes the zone, in which the session states are stored i.e. store in slimits. ###
### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ###
limit_conn_zone $binary_remote_addr zone=addr:5m;

### Control maximum number of simultaneous connections for one session i.e. ###
### restricts the amount of connections from a single ip address ###
limit_conn addr 10;

Save and close.

Restart Nginx server

sudo systemctl restart nginx

Google OAuth setup

We are going to replace the local login/password access to Grafana server, by a much more robust authentication : Google OAuth. Remember : you must have your mail address on your own domain (see Pre-Requisites), and create a Google acocunt with that address.

Activate 2FA on your Google Account

Connect to the Google account you created with your own mail address, and activate 2FA Authentication :

1- In the navigation panel, select Security.

2- Under “Signing in to Google,” select 2-Step Verification. Get started.

3- Follow the on-screen steps.

Create Google API credentials

1- Go to https://console.developers.google.com/apis/credentials and log in with the Google account you created with your own mail address.

2- Click on "Create Credentials" on top of the page, and then click OAuth Client ID . (You may have to setup a “Consent page” first. Use defaults, it’s not very important in our case).

3- Enter these settings :

  • Application Type: Web Application
  • Name: Grafana
  • Authorized JavaScript Origins: https://your-FQDN-used-to-access-your-grafana-server
  • Authorized Redirect URLs: https://your-FQDN-used-to-access-your-grafana-server/login/google

4- Click on Create

5- You’ll get a Client ID and Client Secret. Copy them.

Edit Grafana config file

Open grafana.ini

sudo nano /etc/grafana/grafana.ini

In the Server section, find this setting and modify it

root_url = https://your-FQDN-used-to-access-your-grafana-server/

Next, go to the Google Auth section and modify these settings

[auth.google] enabled = true
client_id = <copy your Google API client id>
client_secret = <copy your Google API clien secret>
scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
auth_url = https://accounts.google.com/o/oauth2/auth
token_url = https://accounts.google.com/o/oauth2/token
allowed_domains = <your domain, like "yourdomain.com">
allow_sign_up =false

Save and close the file

Restart grafana server

sudo systemctl restart grafana-server.service

Access to your Grafana FQDN : https://your-FQDN-used-to-access-your-grafana-server

You should now have a “Sign-in with Google” option on the login page. You can now use the account you created with your own domain name to access your Grafana Cardano dashboards.

Optional: Admin configuration

Give the Google Account the administrator role, and then remove the local Admin/Password account

1- Access your Grafana UI with your local Admin account

2- Go to "Users", and make your Google Account "Admin" by changing its role

3- Log in with your Google Account, go to "Users", and remove the local Admin account.

Disable login form to allow only Google OAuth

sudo nano /etc/grafana/grafana.ini

In the [auth] section :

disable_login_form = true

Save and close the file