Grant access to the Internet only for certain requests from Grafana with reverse proxy

I have two machines:

Machine A: Grafana installed / No access to the Internet / Need to send notifications to Telegram

Machine B Nginx installed / Access to the Internet

I would like to send those Telegram notifications, but the machine A does not have Internet, so I have to use the B to do that.

I created this configuration in the machine B (in /etc/nginx/sites-available):

server {

listen 443;

location / {

proxy_pass http://mygrafana.example.com;

}

I saw that Machine A uses port 443 to send Telegram notifications, so I used that port for listening ---> Here are the logs where I saw port 443 lvl=eror msg="failed to send notification" logger=alerting.notifier uid= error="Post https://api.telegram.org/XXXXXXXXXXXX/sendMessage: dial tcp XX.XX.XX.XX:443: connect: network is unreachable".

But it does not work,seems like that configuration is not working.

Here in the grafana logs it seems like there is no connection to machine B lvl=eror msg="failed to send notification" connect: network is unreachable"


Using Nginx as Reverse-Proxy to Access Grafana everywhere

The Constellation:

Server A is a server without Internet (i.e., a Dedicated Server, NAS, etc...)
server B is a server with Internet AND access to LAN (Second Ethernet Card i.e.)

In this case, myself assumes, that Both servers are being on the same LAN or is allowed by Owner or Firewall Rules to do that :-)

Start on Server A

We have to verify the point,

  • if graphana listen to its default port on 3000
  • if graphana listen only to localhost or open to anywhere

Doings on Server A:

In case it is unknown, we can use

lsof -Pi :3000

This will tell you, if its only listen to Localhost or not.

Grafana has a nice Documentation, which can be found here https://grafana.com/docs/grafana/latest/administration/configuration/

The Lazy Administrator from Server A

skips the manual, in case, its listen to localhost and dislikes touching or change grafana.
We can also use nginx for this step by using either the default because nothing else is running in my assumption:


#Original from https://grafana.com/tutorials/run-grafana-behind-a-proxy/
map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}

server {
  #Allow only my LAN's to access this
  allow 10.0.0.0/8;
  allow 192.168.0.0/16;
  allow 172.16.0.0/16;
  #Finally, disallow the rest
  deny all;
 
  server_name _;
  listen 80;
  root /usr/share/nginx/html;
  index index.html index.htm;

  location / {
    proxy_pass http://localhost:3000/;
  }

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

What does the above config?

I want to avoid touching Grafana and just use NGINX to handle that. Moreover, I can now access by IP from LAN to this instance.

  • Server A -- DONE.

Startover to Server B

The easy one!

Install nginx with your Package manager

apt-get install nginx apt install nginx

Etc.. Depending on your distribution.

Config for NGINX

server {
# https redirect
        server_name grafana.mydoma.in;
        listen 80;
        return 301 https://$host$request_uri;


}

server {
        proxy_read_timeout 3600;
# *if you need plain http uncomment the port 80*
# *remind, that you will comment out the above, else it wont work*
        #listen 80;
        listen 443 ssl http2;
        server_name grafana.mydoma.in;
        
                location / {
                        proxy_pass              http://10.0.0.1:3000;
                        proxy_set_header        Host $http_host;
                        
}
    ssl_certificate /etc/letsencrypt/live/grafana.mydoma.in/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/grafana.mydoma.in/privkey.pem; # managed by Certbot

}

I assume in here you use lets encrypt as an SSL Provider.

10.0.0.1 is the IP of Server A, since its listen to Port 80 with a invalid (_) name it will always use this, if you removed any other default configuration of course :-)

the end // Conclusions

You can, when everything works fine, access grafana from everywhere. Short Reminder:

  • You WONT need NGINX on Server A when it listen to LAN or ALL devices.
    • In this case, you can Skip the Installation of NGINX on Server A
    • And go directly to the second part.

Have fun ;-)

Update:

  • OP claims that the config would fail. Nope, works fine.
root@nginx-verify:/etc/nginx/sites-enabled# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

the full config works. Dont know what you have copied.