diff --git a/Dockerfile.grafana b/Dockerfile.grafana new file mode 100644 index 0000000..d84e56b --- /dev/null +++ b/Dockerfile.grafana @@ -0,0 +1,12 @@ +FROM grafana/grafana:latest + +ENV GF_AUTH_ANONYMOUS_ENABLED=true +ENV GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + +EXPOSE 3000 + +ADD grafana-data/provisioning /etc/grafana/provisioning +ADD grafana-data/dashboards /var/lib/grafana/dashboards + + +CMD [ "grafana-reporter" ] \ No newline at end of file diff --git a/README.md b/README.md index cafb570..32eb09e 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,37 @@ For a more detail view on how to customize your images, see: - [Producer](https://github.com/stefanDeveloper/heiDPI/blob/main/README.producer.md) - [Consumer](https://github.com/stefanDeveloper/heiDPI/blob/main/README.consumer.md) +## Dashboarding + +Das Dashboard-Modul bietet eine visuelle Oberfläche zur Analyse und Überwachung von Netzwerk-Flow-Events, die durch `heiDPI` generiert und mittels `Loki` in `Grafana` bereitgestellt werden. + +### Dashboard + +Das Dashboard gliedert sich in zwei Hauptbereiche: + +1. **Übersichtspanels**: + - *Count Flows by Breed Type*: Balkendiagramm zur Darstellung der Anzahl von Flow-Events nach Klassifizierung (`ndpi_breed`). + - *Flow Events Time Plot*: Zeitreihenvisualisierung der Flow-Rate zur Erkennung zeitlicher Trends. + - *Unsafe & Tracking Flows*: Tabelle mit Flows klassifiziert als `Unsafe` oder `Tracker/Ads`. + - *Potentially Dangerous & Dangerous Flows*: Flows mit erhöhtem Sicherheitsrisiko. + - *Unrated Flows*: Flows ohne Bewertung zur weiteren Untersuchung. + +2. **Detailansicht pro Flow-ID**: + - Selektierbare Variable `Flow ID` erlaubt das gezielte Anzeigen und Analysieren einzelner Flows in dedizierten Panels. + +### Alerts + +Das System beinhaltet eine Alert-Regel zur Erkennung gefährlicher Flows: + +- **Dangerous Flow Events Alert**: Überwacht Flows mit `ndpi_breed="Dangerous"` und löst eine Warnung bei erkennung aus. Die Benachrichtigung verweist auf das Dashboard zur detaillierten Analyse. + +> Hinweis: Die URL des Webhooks muss vor dem produktiven Einsatz in der Datei `./grafana-data/provisioning/alerting/contact-points.yml` angepasst werden. + +### Provisionierung + +Die Dashboard Funktionalität wird über `docker compose` gesteuert und startet zusammen mit heiDPI. +Grafana ist unter `localhost:3000` erreichbar. + ## License This project is licensed under the GPL-3.0 license - see the [LICENSE.md](https://github.com/stefanDeveloper/heiDPI/blob/main/LICENSE) file for details. diff --git a/config-files/config.alloy b/config-files/config.alloy new file mode 100755 index 0000000..2204c3b --- /dev/null +++ b/config-files/config.alloy @@ -0,0 +1,30 @@ +loki.write "local_loki" { + endpoint { + url = "http://loki:3100/loki/api/v1/push" + } +} + +local.file_match "testing_logging" { + path_targets = [{"__path__" = "/tmp/heidpi-logs/*.json"}] + sync_period = "5s" +} + +loki.source.file "local_files2" { + targets = local.file_match.testing_logging.targets + //forward_to = [loki.write.local_loki.receiver] + forward_to = [loki.process.add_labels.receiver] +} + +loki.process "add_labels" { + stage.json { + expressions = {flow_id = "flow_id"} + } + + stage.labels { + values = { + flow_id = "flow_id", + } + } + + forward_to = [loki.write.local_loki.receiver] +} \ No newline at end of file diff --git a/config-files/loki-config.yaml b/config-files/loki-config.yaml new file mode 100644 index 0000000..e640b9d --- /dev/null +++ b/config-files/loki-config.yaml @@ -0,0 +1,52 @@ +auth_enabled: false + +server: + http_listen_port: 3100 + +distributor: + ring: + kvstore: + store: inmemory + +ingester: + wal: + dir: /loki/wal # <-- Add this line to specify the WAL directory + lifecycler: + ring: + kvstore: + store: inmemory + replication_factor: 1 + chunk_idle_period: 3m + chunk_retain_period: 1m + max_chunk_age: 1h + chunk_target_size: 1048576 + +schema_config: + configs: + - from: 2023-01-01 + store: boltdb-shipper + object_store: filesystem + schema: v11 + index: + prefix: index_ + period: 24h + +storage_config: + boltdb_shipper: + active_index_directory: /loki/index + shared_store: filesystem + cache_location: /loki/cache + filesystem: + directory: /loki/chunks + +limits_config: + enforce_metric_name: false + reject_old_samples: true + reject_old_samples_max_age: 168h + ingestion_rate_mb: 8 + ingestion_burst_size_mb: 16 + +compactor: + working_directory: /loki/compactor + shared_store: filesystem + diff --git a/config.yml b/config.yml index 7d63f43..684976e 100644 --- a/config.yml +++ b/config.yml @@ -19,7 +19,7 @@ flow_event: - detection-update filename: flow_event geoip2_city: - enabled: True + enabled: False filepath: /tmp/city.mmdb keys: - country.names.en diff --git a/docker-compose.yml b/docker-compose.yml index aed9dfe..f0c26ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,11 @@ version: "3.9" +networks: + loki: + +volumes: + grafana-data: + services: producer: image: stefan96/heidpi-producer:latest @@ -7,13 +13,13 @@ services: network_mode: host security_opt: - no-new-privileges - pids_limit: 8192 +# pids_limit: 8192 restart: on-failure:5 - deploy: - resources: - limits: - cpus: '5' - memory: 32G +# deploy: +# resources: +# limits: +# cpus: '5' +# memory: 32G environment: - HOSTNAME=test - TUNE_PARAM=max-reader-threads=4,max-flows-per-thread=65536,max-idle-flows-per-thread=2048,daemon-status-interval=15000000,flow-scan-interval=15000000,generic-max-idle-time=15000001,icmp-max-idle-time=15000001,udp-max-idle-time=15000001,tcp-max-idle-time=15000001,tcp-max-post-end-flow-time=5000000 @@ -30,14 +36,53 @@ services: network_mode: host security_opt: - no-new-privileges - pids_limit: 8192 +# pids_limit: 8192 restart: on-failure:5 - deploy: - resources: - limits: - cpus: '1' - memory: 2G +# deploy: +# resources: +# limits: +# cpus: '1' +# memory: 2G depends_on: - producer environment: - SHOW_DAEMON_EVENTS=1 + + loki: + image: grafana/loki:2.9.2 + ports: + - "3100:3100" + volumes: + - ./config-files/loki-config.yaml:/etc/loki/local-config.yaml # Correct relative path + - ./loki/rules:/loki/rules:rw # Correct relative path + - ./loki/index:/loki/index:rw # Added volume for index directory + - ./loki/cache:/loki/cache:rw # Added volume for cache directory + - ./loki/chunks:/loki/chunks:rw # Added volume for chunks directory + - ./loki/compactor:/loki/compactor:rw # Added volume for compactor directory + - ./loki/wal:/loki/wal:rw + command: -config.file=/etc/loki/local-config.yaml + networks: + - loki + + alloy: + image: grafana/alloy:latest + ports: + - "12345:12345" + volumes: + - ./config-files/config.alloy:/etc/alloy/config.alloy + - ./heidpi-logs:/tmp/heidpi-logs + command: run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy --stability.level experimental + networks: + - loki + depends_on: + - loki + + grafana: + build: + dockerfile: ./Dockerfile.grafana + volumes: + - grafana-data:/var/lib/grafana + ports: + - "3000:3000" + networks: + - loki diff --git a/grafana-data/dashboards/default.json b/grafana-data/dashboards/default.json new file mode 100644 index 0000000..10c5c6a --- /dev/null +++ b/grafana-data/dashboards/default.json @@ -0,0 +1,1124 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 274, + "options": { + "displayMode": "gradient", + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "maxVizHeight": 300, + "minVizHeight": 16, + "minVizWidth": 8, + "namePlacement": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "distinctCount" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "valueMode": "color" + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "direction": "backward", + "editorMode": "code", + "expr": "sum by (ndpi_breed) (rate({filename=\"/tmp/heidpi-logs/flow_event.json\"} |= `` | json | ndpi_breed != \"\" [1h]))", + "queryType": "range", + "refId": "A" + } + ], + "title": "Count Flows by Breed Type", + "type": "bargauge" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 270, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "direction": "backward", + "editorMode": "code", + "expr": "sum by (ndpi_breed) (rate({filename=\"/tmp/heidpi-logs/flow_event.json\"} |= `` | json | ndpi_breed != \"\" [1h]))", + "queryType": "range", + "refId": "A" + } + ], + "title": "Flow Events TIme Plot", + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 16, + "w": 8, + "x": 0, + "y": 8 + }, + "id": 272, + "options": { + "dedupStrategy": "exact", + "enableInfiniteScrolling": false, + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "direction": "backward", + "editorMode": "code", + "expr": "{filename=\"/tmp/heidpi-logs/flow_event.json\"} |= `` | json | label_format flow_id=\"{{.flow_id}}\" | ndpi_breed=\"Tracker/Ads\" or ndpi_breed=\"Unsafe\" | line_format \"{{.flow_id}}\"", + "queryType": "range", + "refId": "A" + } + ], + "title": "Unsafe & Tracking Flows", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 16, + "w": 8, + "x": 8, + "y": 8 + }, + "id": 269, + "options": { + "dedupStrategy": "exact", + "enableInfiniteScrolling": false, + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "direction": "backward", + "editorMode": "code", + "expr": "{filename=\"/tmp/heidpi-logs/flow_event.json\"} |= `` | json | label_format flow_id=\"{{.flow_id}}\" | ndpi_breed=\"Dangerous\" or ndpi_breed=\"Potentially Dangerous\" | line_format \"{{.flow_id}}\"", + "queryType": "range", + "refId": "A" + } + ], + "title": "Potentially Dangerous & Dangerous Flows", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 16, + "w": 8, + "x": 16, + "y": 8 + }, + "id": 273, + "options": { + "dedupStrategy": "exact", + "enableInfiniteScrolling": false, + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "direction": "backward", + "editorMode": "code", + "expr": "{filename=\"/tmp/heidpi-logs/flow_event.json\"} |= `` | json | label_format flow_id=\"{{.flow_id}}\" | ndpi_breed=\"Unrated\" | line_format \"{{.flow_id}}\"", + "queryType": "range", + "refId": "A" + } + ], + "title": "Unrated Flows", + "type": "logs" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 271, + "panels": [], + "title": " Flow Informations (Choose FlowID)", + "type": "row" + }, + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 19, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": false, + "displayName": "15" + } + ] + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P8E80F9AEF21F6940" + }, + "direction": "backward", + "editorMode": "builder", + "expr": "{filename=\"/tmp/heidpi-logs/flow_event.json\"} | json | flow_id = `$flow_id`", + "queryType": "range", + "refId": "A" + } + ], + "title": "Flow Events Json", + "transformations": [ + { + "id": "extractFields", + "options": { + "delimiter": ",", + "keepTime": false, + "replace": true, + "source": "labels" + } + } + ], + "type": "table" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 31 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^flow_id$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Flow ID", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 31 + }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "uniqueValues" + ], + "fields": "/^l4_proto$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "L4-Proto", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 31 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "uniqueValues" + ], + "fields": "/^flow_state$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Current Flow State", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "dateTimeAsSystem" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 31 + }, + "id": 9, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^timestamp$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Last Seen", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 12, + "y": 31 + }, + "id": 268, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^ndpi_category$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Category", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 15, + "y": 31 + }, + "id": 11, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^ndpi_breed$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Breed", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 31 + }, + "id": 18, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^ndpi_confidence_6$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Risk Confidence", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 35 + }, + "id": 275, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^dst_ip$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Destination IP", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 35 + }, + "id": 276, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^dst_port$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Destination Port", + "type": "stat" + }, + { + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 35 + }, + "id": 277, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^src_ip$/", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 19, + "refId": "A", + "withTransforms": true + } + ], + "title": "Source IP", + "type": "stat" + } + ], + "preload": false, + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "1", + "value": "1" + }, + "definition": "", + "label": "Flow ID", + "name": "flow_id", + "options": [], + "query": { + "label": "flow_id", + "refId": "LokiVariableQueryEditor-VariableQuery", + "stream": "", + "type": 1 + }, + "refresh": 1, + "regex": "", + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "heiDPI", + "uid": "ce7a6ariolcb2", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/grafana-data/provisioning/alerting/alert-rules.yml b/grafana-data/provisioning/alerting/alert-rules.yml new file mode 100644 index 0000000..bf3297c --- /dev/null +++ b/grafana-data/provisioning/alerting/alert-rules.yml @@ -0,0 +1,61 @@ +apiVersion: 1 +groups: + - orgId: 1 + name: heiDPI + folder: heiDPI + interval: 1m + rules: + - uid: cegl3u0mh0wzkb + title: Altert Dangerous Flow Events + condition: B + data: + - refId: A + queryType: instant + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: P8E80F9AEF21F6940 + model: + editorMode: code + expr: rate({filename="/tmp/heidpi-logs/flow_event.json"} |= `` | json | ndpi_breed="Dangerous"[1m]) + instant: true + intervalMs: 1000 + maxDataPoints: 43200 + queryType: instant + refId: A + - refId: B + datasourceUid: __expr__ + model: + conditions: + - evaluator: + params: + - 0 + - 0 + type: gt + operator: + type: and + query: + params: + - A + reducer: + params: [] + type: count + type: query + datasource: + name: Expression + type: __expr__ + uid: __expr__ + expression: "" + hide: false + intervalMs: 1000 + maxDataPoints: 43200 + refId: B + type: classic_conditions + noDataState: NoData + execErrState: Error + for: 1m + annotations: + summary: 'Dangerous Flow erkannt! Details zu betroffenen Flow-ID(s) im Dashboard: http://localhost:3000/d/heiDPI' + isPaused: false + notification_settings: + receiver: heiDPI-webhook diff --git a/grafana-data/provisioning/alerting/contact-points.yml b/grafana-data/provisioning/alerting/contact-points.yml new file mode 100644 index 0000000..2d33b11 --- /dev/null +++ b/grafana-data/provisioning/alerting/contact-points.yml @@ -0,0 +1,10 @@ +apiVersion: 1 +contactPoints: + - orgId: 1 + name: heiDPI-webhook + receivers: + - uid: fegls0yjnqhvkb + type: webhook + settings: + url: PLACEHOLDER + disableResolveMessage: false diff --git a/grafana-data/provisioning/dashboards/dashboards.yml b/grafana-data/provisioning/dashboards/dashboards.yml new file mode 100644 index 0000000..2d2266d --- /dev/null +++ b/grafana-data/provisioning/dashboards/dashboards.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: + - name: "default" + orgId: 1 + folder: "" + type: file + disableDeletion: false + updateIntervalSeconds: 10 + options: + path: /var/lib/grafana/dashboards \ No newline at end of file diff --git a/grafana-data/provisioning/datasources/loki.yml b/grafana-data/provisioning/datasources/loki.yml new file mode 100644 index 0000000..d4b52c4 --- /dev/null +++ b/grafana-data/provisioning/datasources/loki.yml @@ -0,0 +1,11 @@ +apiVersion: 1 +datasources: + - name: Loki + type: loki + access: proxy + orgId: 1 + url: http://loki:3100 + basicAuth: false + isDefault: true + version: 1 + editable: false