Menu Zamknij

Grafana bez logowania wystawiona na świat, ale z filtrowaniem IP

Podczas tworzenia strony z metrykami w Grafanie którą chciałem wyświetlać w kilku miejscach w mojej sieci (m.in. na „stronie admina” która oprócz linków do wewnętrznych systemów ma też kilka wykresów) dotarłem do problemu niezbyt popularnego ale mimo wszystko występującego. Grafana sama z siebie posiada tryb auth.anonymous, który tworzy możliwość podglądu danych bez zalogowania, ale wystawienie takowego na świat ma 2 problemy – ujawniamy dane i umożliwiamy zajechanie serwera przez złych ludzi w Internecie – od prymitywnego ładowania maksymalnie długich zakresów na dashboardach po wykonywanie własnych kwerend na naszych datasource’ach – a więc nawet Postgresie.

Żeby tego uniknąć chciałoby się do auth.anonymous dodać jakiś filtr adresów IP. Ale Grafana nie ma takiej możliwości. Skorzystamy zatem z zaawansowanych funkcji reverse proxy w Caddym. Cały setup wykorzystuje poza tym ZeroTiera (którego jakiś czas temu opisywałem) do dostarczenia prywatnej sieci dostępowej. Całość wygląda tak:

  • Grafana stoi na lokalnym porcie, niedostępnym z internetu
  • Caddy robi standardowe reverse proxy (transparent) na domenę dostępną z internetu – powiedzmy grafana.example.org
  • Poza tym mamy drugą instancję domeny z reverse proxy która dodaje nagłówki do obsługi proxy level auth na innej domenie – np. grafana.intranet.example.com; ta domena powinna być rozwiązywalna do adresu prywatnego!
  • Grafana ma użytkownika z rolą viewer który jest „autoryzowany” i „logowany” przez reverse proxy dla prywatnej sieci, w przykładzie poniżej jest to readonly

Caddyfile potrzebuje zatem takiej sekcji:

grafana.intranet.example.com:80 {
  proxy / http://localhost:3333 {
    transparent
    header_upstream X-GrafanaUser readonly
  }
  ipfilter / {
    rule allow
    ip 192.168.88.1/24
  }
}
  • Niestety certyfikatu z Let’s Encrypt nie uzyskamy – domena musi być routowalna z całego internetu
  • Port 3333 to port na którym słucha serwer Grafany
  • 192.168.88.1/24 to nasz prywatny subnet
  • X-GrafanaUser to header autoryzacyjny, który musi matchować z grafana.ini; w najprostszej wersji może tam być zahardkodowany nasz użytkownik z rolą viewer

Natomiast w pliku grafana.ini potrzeba takiej modyfikacji sekcji:

grafana.intranet.example.com:80 {
  proxy / http://localhost:3333 {
    transparent
    header_upstream X-GrafanaUser readonly
  }
  ipfilter / {
    rule allow
    ip 192.168.88.1/24
  }
}

Gdzie header_name musi matchować z header_upstream z Caddyfile, a whitelist pozwalać tylko na adres IP serwera Caddy który łączy się z Grafaną (a więc loopback).

Przy założeniu że nasza sieć prywatna jest naprawdę prywatna, jej użytkownicy naprawdę zaufani (możemy to być na przykład tylko my jako jej właściciele) oraz że Grafana nie zawiera naprawdę poufnych danych setup można uznać za względnie bezpieczny.

1 Komentarz

  1. pm7

    Względem certyfikatu z Let’s Encrypt to wydaje mi się, że powinno się dać go uzyskać.
    Jeżeli filtrowanie IP jest po ścieżce, wystarczy się upewnić, że ścieżka testowa ACME HTTP-01 jest dostępna publicznie:
    http:///.well-known/acme-challenge/

    Alternatywnie, są też inne protokoły niż HTTP-01, czyli DNS-01 (dobra konfiguracja jest niestety skomplikowana, ale umożliwia uzyskanie wildcard, czyli np. *.intranet.example.com) i TLS-ALPN-01 (nieobsługiwane przez typowe serwery jak Apache/nginx, ale obsługiwane przez Caddy).

    W załączonych fragmentach konfiguracji nie występuje „grafana.example.org” – czy to było celowe?

Dodaj komentarz