Nginx Proxy Managerin GeoBlock-liikenteen visualisointi Grafanalla (Loki & Promtail)
Aiemmassa oppaassa kävimme läpi, kuinka asettaa Nginx Proxy Manageriin (NPM) GeoBlocking MaxMindin tietokannan avulla. Se on tehokas tapa estää ei-toivottu liikenne tietyistä maista ja palauttaa niille esimerkiksi kustomoitu 503-virhesivu.
Mutta mistä tiedämme, kuinka paljon liikennettä oikeasti blokataan ja mistä maista sitä tulee? Tässä oppaassa rakennamme seurantapaneelin Grafanan, Lokin ja Promtailin avulla. Näytän, kuinka NPM:n lokit muutetaan JSON-muotoon, lähetetään Lokille ja visualisoidaan upeaksi maailmankartaksi ja top-listaksi.
Vaihe 1: Nginx-lokien muuttaminen JSON-muotoon
Oletuksena Nginx kirjoittaa lokia pelkkänä tekstinä. Jotta Grafana voi suodattaa dataa kätevästi (esimerkiksi maatunnuksen tai eston perusteella), meidän täytyy kertoa Nginxille, että haluamme lokit rakenteellisena JSON-datana.
Avaa aiemmin luomasi Nginxin lisäkonfiguraatiotiedosto (esim. /docker/npm/data/nginx/custom/http_top.conf) ja päivitä se tähän muotoon:
charset utf-8;
geoip2 /data/geoip2/GeoLite2-City.mmdb {
auto_reload 3h;
$geoip2_metadata_country_build metadata build_epoch;
$geoip2_data_country_code default=XX source=$remote_addr country iso_code;
# HUOM: Käytä ehdottomasti "en" (englanti), jotta MaxMind palauttaa maan koko nimen luotettavasti.
# Jos käytät "fi", moni maa palauttaa pelkän viivan (-).
$geoip2_data_country_name default=- country names en;
$geoip2_data_city_name default=- city names en;
$geoip2_data_region_name default=- subdivisions 0 names en;
}
geo $allowed_ip {
default no; # Blokataan kaikki oletuksena
10.10.0.0/24 yes; # Whitelist: Oma lähiverkko
}
map $geoip2_data_country_code $allowed_country {
default $allowed_ip;
DE yes; # Whitelist: Vain Saksa sallittu
}
# Grafanaa varten räätälöity JSON-loki
log_format json_analytics escape=json '{'
'"time_local": "$time_local", '
'"remote_addr": "$remote_addr", '
'"request_uri": "$request_uri", '
'"status": "$status", '
'"server_name": "$server_name", '
'"request_method": "$request_method", '
'"country_code": "$geoip2_data_country_code", '
'"country_name": "$geoip2_data_country_name", '
'"city_name": "$geoip2_data_city_name", '
'"is_allowed": "$allowed_country" '
'}';
Muista myös varmistaa, että kyseistä json_analytics -muotoa käytetään Nginxin access-lokeissa (esim. server_proxy.conf tiedostossa):
access_log /data/logs/all_proxy_access.log json_analytics;
error_log /data/logs/all_proxy_error.log warn;
Lataa Nginx uudelleen: docker exec -it npm-containerin-nimi nginx -s reload
Nimen näet docker ps komennolla.
Vaihe 2: Valmistele Grafana-ympäristön kansiot
Luodaan seurantatyökaluille oma hakemisto. Nykyiset Docker-imaget vaativat tiukat kansion omistajuudet turvallisuussyistä.
mkdir -p /docker/grafana
cd /docker/grafana
# Luodaan tarvittavat alikansiot
mkdir -p config-loki config-promtail loki-data grafana-data
# Asetetaan oikeudet, jotta containerit voivat tallentaa dataa
sudo chown -R 10001:10001 loki-data
sudo chown -R 472:472 grafana-data
Vaihe 3: Konfiguraatiotiedostot Promtailille ja Lokille
Promtail lukee NPM:n lokitiedostoja ja lähettää ne Lokille, joka indeksoi ne Grafanaa varten.
Luo tiedosto config-promtail/config.yaml:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
Luo tiedosto config-loki/local-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
Vaihe 4: Docker Compose
Luo tiedosto compose.yaml /docker/grafana/ -kansioon.Huom: Varmista, että Promtailin volume viittaa oikeaan paikkaan isäntäkoneellasi, jossa Nginx Proxy Managerin lokit sijaitsevat.
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
volumes:
- ./loki-data:/loki
- ./config-loki:/etc/loki
restart: unless-stopped
promtail:
image: grafana/promtail:latest
volumes:
# MUUTA TÄMÄ vastaamaan omaa NPM asennustasi:
- /docker/npm/data/logs:/var/log
- ./config-promtail/config.yaml:/etc/promtail/config.yaml
restart: unless-stopped
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_AUTH_ANONYMOUS_ENABLED=false
volumes:
- ./grafana-data:/var/lib/grafana
restart: unless-stopped
Käynnistä ympäristö: docker compose up -d
Vaihe 5: Grafana Dashboardin rakentaminen
Kirjaudu Grafanaan osoitteessa http://palvelimen-ip:3000 (oletustunnukset: admin / admin). Lisää ensin tietolähde (Data Source): Valitse Loki ja aseta URL-osoitteeksi http://loki:3100.
Luo uusi Dashboard ja lisää siihen kaksi paneelia:
1. Maailmankartta (Geomap) – Näyttää estetyt yhteydet kartalla
Valitse paneelin tyypiksi Geomap (tai Heatmap) ja aseta kyselyksi (LogQL):
sum by (country_code) (
count_over_time({job="varlogs", filename=~".*access.*"} | json | __error__="" | is_allowed="no" | status="503" | country_code != "XX" | country_code != "" [$__range])
)
Miksi nämä filtterit?
filename=~".*access.*"ohittaa Nginxin virhelokit (error.log), jotka ovat puhdasta tekstiä ja rikkovat JSON-parserin.$__rangeskaalautuu Grafanan aikavalitsimen mukaan.is_allowed="no"jastatus="503"poimivat vain oikeasti estetyt yhteydet.
Tärkeät asetukset kartalle (Transform data & Map Layers): Jotta kartta ymmärtää datan oikein, sinun on tehtävä kaksi asiaa:
Mene Transform data -välilehdelle ja lisää: Merge (laita tämä aivan ylimmäksi!) ja sen alle Labels to fields.
Oikean reunan asetuksista valitse Map layers -> Data layer:
Location mode: Lookup
Lookup field:
country_codeGazetteer: Countries
Size / Weight field: Value
2. Estetyt maat Top-lista (Bar Gauge)
Lisää toinen paneeli, tyypiltään Bar Gauge, ja aseta kyselyksi:
sum by (country_name) (
count_over_time({job="varlogs", filename=~".*access.*"} | json | __error__="" | is_allowed="no" | status="503" | country_name != "-" [$__range])
) or vector(0)
Tässä or vector(0) on tärkeä varmistus: jos liikennettä ei ole hetkeen blokattu, Grafana ei kaadu ”No Data” -virheeseen, vaan palauttaa siististi arvon 0.
Siisti asettelu (Transform data): Päästäksesi eroon rumasta Value #A -tekstistä, joka syntyy vector(0) -toiminnosta, käytä jälleen transformaatioita:
Mene Transform data -välilehdelle.
Lisää Labels to fields.
Lisää Filter data by values:
Type: Include / Match: All
Conditions: Field ->
Value-> Is greater than ->0. Tämä piilottaa automaattisesti tyhjät rivit, ja jäljelle jää vain siisti lista estettyjen maiden oikeista nimistä.
Ongelmanratkaisu: Jos kartta ei näy tai lataudu
Joskus Grafanan oletusarvoinen taustakartta ei lataudu oikein verkkorajoitusten tai palvelinongelmien vuoksi, jolloin kartan tilalla näkyy vain tyhjä ruutu. Voit korjata tämän vaihtamalla taustakartaksi vaihtoehtoisen palvelimen, kuten Carton tyylikkään tumman teeman (dark_all).
Näin vaihdat taustakartan:
Paina ”Traffic Map” -paneelin otsikkoa ja valitse Edit.
Etsi oikean reunan valikosta osio Map layers ja avaa Basemap layer -asetukset.
Määritä asetukset seuraavasti:
Layer type:
arcGIS MapServerServer instance:
Custom MapServerURL Template:
[https://basemaps.cartocdn.com/rastertiles/dark_all/](https://basemaps.cartocdn.com/rastertiles/dark_all/){z}/{x}/{y}.png(Huom: Mikäli käytät Carton rekisteröityä tiliä, voit lisätä osoitteen perään?key={YOUR_API_KEY}, mutta julkiset peruskartat toimivat usein myös ilman avainta).Attribution:
© Carto.com
Paina ylhäältä Apply ja tallenna Dashboard. Kartan pitäisi nyt ilmestyä näkyviin välittömästi.
(Vinkki: Jos haluat kokeilla karttaan muita väriteemoja, löydät kaikki tuetut tyylit suoraan Carton GitHub-repositoriosta.)
Yhteenveto
Nyt sinulla on täysin lokaalisti pyörivä, visuaalinen seurantataulu palvelimesi GeoBlock-osumille. Nginx puskee dataa JSON-muodossa, Promtail poimii sen, Loki indeksoi, ja Grafana piirtää sen kauniisti kartalle ilman minkäänlaisia ulkoisia pilvipalveluita tai API-avaimia.









