├── Grafana-OPNsense-Suricata.png ├── Grafana-OPNsense.png ├── OPNsense-Grafana-Dashboard-Suricata.json ├── OPNsense-Grafana-Dashboard.json ├── README.md ├── ansible ├── README.md ├── inventory.yml └── playbook.yml ├── config ├── OPNsense-pack.json ├── custom.conf └── suricata │ ├── custom.yaml │ └── suricata.conf ├── configure.md ├── docker-compose.yaml └── plugins ├── README.md ├── telegraf_pfifgw.php └── telegraf_temperature.sh /Grafana-OPNsense-Suricata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/48119ee5914d0b591f48ff98b125146ff7df75a1/Grafana-OPNsense-Suricata.png -------------------------------------------------------------------------------- /Grafana-OPNsense.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/48119ee5914d0b591f48ff98b125146ff7df75a1/Grafana-OPNsense.png -------------------------------------------------------------------------------- /OPNsense-Grafana-Dashboard-Suricata.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": "-- Grafana --", 7 | "enable": true, 8 | "hide": true, 9 | "iconColor": "rgba(0, 211, 255, 1)", 10 | "name": "Annotations & Alerts", 11 | "target": { 12 | "limit": 100, 13 | "matchAny": false, 14 | "tags": [], 15 | "type": "dashboard" 16 | }, 17 | "type": "dashboard" 18 | } 19 | ] 20 | }, 21 | "editable": true, 22 | "fiscalYearStartMonth": 0, 23 | "graphTooltip": 0, 24 | "id": 23, 25 | "iteration": 1644864155168, 26 | "links": [], 27 | "liveNow": false, 28 | "panels": [ 29 | { 30 | "collapsed": false, 31 | "gridPos": { 32 | "h": 1, 33 | "w": 24, 34 | "x": 0, 35 | "y": 0 36 | }, 37 | "id": 155, 38 | "panels": [], 39 | "title": "Suricata", 40 | "type": "row" 41 | }, 42 | { 43 | "fieldConfig": { 44 | "defaults": { 45 | "color": { 46 | "mode": "thresholds" 47 | }, 48 | "mappings": [], 49 | "thresholds": { 50 | "mode": "absolute", 51 | "steps": [ 52 | { 53 | "color": "green" 54 | } 55 | ] 56 | } 57 | }, 58 | "overrides": [] 59 | }, 60 | "gridPos": { 61 | "h": 5, 62 | "w": 7, 63 | "x": 0, 64 | "y": 1 65 | }, 66 | "id": 373, 67 | "options": { 68 | "colorMode": "value", 69 | "graphMode": "none", 70 | "justifyMode": "auto", 71 | "orientation": "auto", 72 | "reduceOptions": { 73 | "calcs": [ 74 | "lastNotNull" 75 | ], 76 | "fields": "/^_value$/", 77 | "values": false 78 | }, 79 | "text": {}, 80 | "textMode": "auto" 81 | }, 82 | "pluginVersion": "8.3.3", 83 | "targets": [ 84 | { 85 | "datasource": { 86 | "type": "influxdb", 87 | "uid": "${dataSource}" 88 | }, 89 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_category\")\r\n |> map(fn: (r) => ({ r with _count: r[\"_value\"]}))\r\n |> group(columns: [\"_value\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n:1)", 90 | "refId": "A" 91 | } 92 | ], 93 | "title": "Top Alert Category", 94 | "type": "stat" 95 | }, 96 | { 97 | "fieldConfig": { 98 | "defaults": { 99 | "color": { 100 | "mode": "thresholds" 101 | }, 102 | "mappings": [], 103 | "thresholds": { 104 | "mode": "absolute", 105 | "steps": [ 106 | { 107 | "color": "green" 108 | }, 109 | { 110 | "color": "red", 111 | "value": 80 112 | } 113 | ] 114 | } 115 | }, 116 | "overrides": [] 117 | }, 118 | "gridPos": { 119 | "h": 5, 120 | "w": 3, 121 | "x": 7, 122 | "y": 1 123 | }, 124 | "id": 463, 125 | "options": { 126 | "colorMode": "value", 127 | "graphMode": "none", 128 | "justifyMode": "auto", 129 | "orientation": "auto", 130 | "reduceOptions": { 131 | "calcs": [ 132 | "lastNotNull" 133 | ], 134 | "fields": "/^src_ip$/", 135 | "limit": 1, 136 | "values": true 137 | }, 138 | "textMode": "auto" 139 | }, 140 | "pluginVersion": "8.3.3", 141 | "targets": [ 142 | { 143 | "datasource": { 144 | "type": "influxdb", 145 | "uid": "${dataSource}" 146 | }, 147 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_category\")\r\n |> map(fn: (r) => ({ r with _count: r[\"src_ip\"]}))\r\n |> group(columns: [\"src_ip\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n:1)", 148 | "refId": "A" 149 | } 150 | ], 151 | "title": "Top Source IP", 152 | "type": "stat" 153 | }, 154 | { 155 | "fieldConfig": { 156 | "defaults": { 157 | "color": { 158 | "mode": "palette-classic" 159 | }, 160 | "custom": { 161 | "hideFrom": { 162 | "legend": false, 163 | "tooltip": false, 164 | "viz": false 165 | } 166 | }, 167 | "mappings": [] 168 | }, 169 | "overrides": [] 170 | }, 171 | "gridPos": { 172 | "h": 9, 173 | "w": 7, 174 | "x": 10, 175 | "y": 1 176 | }, 177 | "id": 419, 178 | "options": { 179 | "legend": { 180 | "displayMode": "table", 181 | "placement": "right", 182 | "values": [ 183 | "value" 184 | ] 185 | }, 186 | "pieType": "pie", 187 | "reduceOptions": { 188 | "calcs": [ 189 | "lastNotNull" 190 | ], 191 | "fields": "", 192 | "values": true 193 | }, 194 | "tooltip": { 195 | "mode": "single" 196 | } 197 | }, 198 | "pluginVersion": "8.3.3", 199 | "targets": [ 200 | { 201 | "datasource": { 202 | "type": "influxdb", 203 | "uid": "${dataSource}" 204 | }, 205 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_category\")\r\n |> map(fn: (r) => ({ r with _count: r[\"dest_port\"]}))\r\n |> group(columns: [\"dest_port\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n: 10)", 206 | "refId": "A" 207 | } 208 | ], 209 | "title": "Top 10 Destination Ports", 210 | "type": "piechart" 211 | }, 212 | { 213 | "fieldConfig": { 214 | "defaults": { 215 | "color": { 216 | "mode": "palette-classic" 217 | }, 218 | "custom": { 219 | "hideFrom": { 220 | "legend": false, 221 | "tooltip": false, 222 | "viz": false 223 | } 224 | }, 225 | "mappings": [] 226 | }, 227 | "overrides": [] 228 | }, 229 | "gridPos": { 230 | "h": 9, 231 | "w": 7, 232 | "x": 17, 233 | "y": 1 234 | }, 235 | "id": 507, 236 | "options": { 237 | "displayLabels": [], 238 | "legend": { 239 | "displayMode": "table", 240 | "placement": "right", 241 | "sortBy": "Value", 242 | "sortDesc": true, 243 | "values": [ 244 | "value" 245 | ] 246 | }, 247 | "pieType": "pie", 248 | "reduceOptions": { 249 | "calcs": [ 250 | "lastNotNull" 251 | ], 252 | "fields": "", 253 | "values": true 254 | }, 255 | "tooltip": { 256 | "mode": "single" 257 | } 258 | }, 259 | "targets": [ 260 | { 261 | "datasource": { 262 | "type": "influxdb", 263 | "uid": "${dataSource}" 264 | }, 265 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"proto\")\r\n |> map(fn: (r) => ({ r with _count: r[\"_value\"]}))\r\n |> group(columns: [\"_value\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])", 266 | "refId": "A" 267 | } 268 | ], 269 | "title": "Protocols", 270 | "type": "piechart" 271 | }, 272 | { 273 | "fieldConfig": { 274 | "defaults": { 275 | "color": { 276 | "mode": "thresholds" 277 | }, 278 | "mappings": [], 279 | "thresholds": { 280 | "mode": "absolute", 281 | "steps": [ 282 | { 283 | "color": "green" 284 | }, 285 | { 286 | "color": "red", 287 | "value": 80 288 | } 289 | ] 290 | } 291 | }, 292 | "overrides": [] 293 | }, 294 | "gridPos": { 295 | "h": 4, 296 | "w": 7, 297 | "x": 0, 298 | "y": 6 299 | }, 300 | "id": 375, 301 | "options": { 302 | "colorMode": "value", 303 | "graphMode": "none", 304 | "justifyMode": "auto", 305 | "orientation": "auto", 306 | "reduceOptions": { 307 | "calcs": [ 308 | "lastNotNull" 309 | ], 310 | "fields": "/^_value$/", 311 | "values": true 312 | }, 313 | "textMode": "auto" 314 | }, 315 | "pluginVersion": "8.3.3", 316 | "targets": [ 317 | { 318 | "datasource": { 319 | "type": "influxdb", 320 | "uid": "${dataSource}" 321 | }, 322 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_signature\")\r\n |> map(fn: (r) => ({ r with _count: r[\"_value\"]}))\r\n |> group(columns: [\"_value\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n:1)", 323 | "refId": "A" 324 | } 325 | ], 326 | "title": "Top Alert Signature", 327 | "type": "stat" 328 | }, 329 | { 330 | "fieldConfig": { 331 | "defaults": { 332 | "color": { 333 | "mode": "thresholds" 334 | }, 335 | "mappings": [], 336 | "thresholds": { 337 | "mode": "absolute", 338 | "steps": [ 339 | { 340 | "color": "green" 341 | }, 342 | { 343 | "color": "red", 344 | "value": 80 345 | } 346 | ] 347 | } 348 | }, 349 | "overrides": [] 350 | }, 351 | "gridPos": { 352 | "h": 4, 353 | "w": 3, 354 | "x": 7, 355 | "y": 6 356 | }, 357 | "id": 551, 358 | "options": { 359 | "colorMode": "value", 360 | "graphMode": "none", 361 | "justifyMode": "auto", 362 | "orientation": "auto", 363 | "reduceOptions": { 364 | "calcs": [ 365 | "lastNotNull" 366 | ], 367 | "fields": "/^dest_ip$/", 368 | "values": false 369 | }, 370 | "textMode": "auto" 371 | }, 372 | "pluginVersion": "8.3.3", 373 | "targets": [ 374 | { 375 | "datasource": { 376 | "type": "influxdb", 377 | "uid": "${dataSource}" 378 | }, 379 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_category\")\r\n |> map(fn: (r) => ({ r with _count: r[\"dest_ip\"]}))\r\n |> group(columns: [\"dest_ip\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n:1)", 380 | "refId": "A" 381 | } 382 | ], 383 | "title": "Top Destination IP", 384 | "type": "stat" 385 | }, 386 | { 387 | "description": "", 388 | "fieldConfig": { 389 | "defaults": { 390 | "color": { 391 | "mode": "palette-classic" 392 | }, 393 | "custom": { 394 | "hideFrom": { 395 | "legend": false, 396 | "tooltip": false, 397 | "viz": false 398 | } 399 | }, 400 | "displayName": "${__field.labels.__values}", 401 | "mappings": [] 402 | }, 403 | "overrides": [] 404 | }, 405 | "gridPos": { 406 | "h": 9, 407 | "w": 10, 408 | "x": 0, 409 | "y": 10 410 | }, 411 | "id": 285, 412 | "options": { 413 | "displayLabels": [], 414 | "legend": { 415 | "displayMode": "table", 416 | "placement": "right", 417 | "values": [ 418 | "value" 419 | ] 420 | }, 421 | "pieType": "pie", 422 | "reduceOptions": { 423 | "calcs": [ 424 | "lastNotNull" 425 | ], 426 | "fields": "", 427 | "values": true 428 | }, 429 | "tooltip": { 430 | "mode": "single" 431 | } 432 | }, 433 | "targets": [ 434 | { 435 | "datasource": { 436 | "type": "influxdb", 437 | "uid": "${dataSource}" 438 | }, 439 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_category\")\r\n |> map(fn: (r) => ({ r with _count: r[\"_value\"]}))\r\n |> group(columns: [\"_value\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n:10)", 440 | "refId": "A" 441 | } 442 | ], 443 | "title": "Top 10 Alert Categories", 444 | "transformations": [], 445 | "type": "piechart" 446 | }, 447 | { 448 | "description": "", 449 | "fieldConfig": { 450 | "defaults": { 451 | "color": { 452 | "mode": "palette-classic" 453 | }, 454 | "custom": { 455 | "hideFrom": { 456 | "legend": false, 457 | "tooltip": false, 458 | "viz": false 459 | } 460 | }, 461 | "displayName": "${__field.labels.__values}", 462 | "mappings": [] 463 | }, 464 | "overrides": [ 465 | { 466 | "__systemRef": "hideSeriesFrom", 467 | "matcher": { 468 | "id": "byNames", 469 | "options": { 470 | "mode": "exclude", 471 | "names": [ 472 | "_count", 473 | "ET INFO Session Traversal Utilities for NAT (STUN Binding Response)" 474 | ], 475 | "prefix": "All except:", 476 | "readOnly": true 477 | } 478 | }, 479 | "properties": [ 480 | { 481 | "id": "custom.hideFrom", 482 | "value": { 483 | "legend": false, 484 | "tooltip": false, 485 | "viz": true 486 | } 487 | } 488 | ] 489 | } 490 | ] 491 | }, 492 | "gridPos": { 493 | "h": 9, 494 | "w": 14, 495 | "x": 10, 496 | "y": 10 497 | }, 498 | "id": 329, 499 | "options": { 500 | "displayLabels": [], 501 | "legend": { 502 | "displayMode": "table", 503 | "placement": "right", 504 | "values": [ 505 | "value" 506 | ] 507 | }, 508 | "pieType": "pie", 509 | "reduceOptions": { 510 | "calcs": [ 511 | "lastNotNull" 512 | ], 513 | "fields": "/^_count$/", 514 | "values": true 515 | }, 516 | "tooltip": { 517 | "mode": "single" 518 | } 519 | }, 520 | "targets": [ 521 | { 522 | "datasource": { 523 | "type": "influxdb", 524 | "uid": "${dataSource}" 525 | }, 526 | "query": "from(bucket: \"opnsense\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_signature\")\r\n |> map(fn: (r) => ({ r with _count: r[\"_value\"]}))\r\n |> group(columns: [\"_value\"])\r\n |> count(column: \"_count\")\r\n |> group()\r\n |> sort(desc:true, columns: [\"_count\"])\r\n |> limit(n:10)", 527 | "refId": "A" 528 | } 529 | ], 530 | "title": "Top 10 Alert Signatures", 531 | "transformations": [], 532 | "type": "piechart" 533 | }, 534 | { 535 | "description": "Last 100 events, newest on top", 536 | "fieldConfig": { 537 | "defaults": { 538 | "color": { 539 | "mode": "thresholds" 540 | }, 541 | "custom": { 542 | "align": "left", 543 | "displayMode": "auto" 544 | }, 545 | "mappings": [], 546 | "thresholds": { 547 | "mode": "absolute", 548 | "steps": [ 549 | { 550 | "color": "green" 551 | } 552 | ] 553 | } 554 | }, 555 | "overrides": [ 556 | { 557 | "matcher": { 558 | "id": "byName", 559 | "options": "Metric" 560 | }, 561 | "properties": [ 562 | { 563 | "id": "custom.width", 564 | "value": 192 565 | } 566 | ] 567 | }, 568 | { 569 | "matcher": { 570 | "id": "byName", 571 | "options": "Time" 572 | }, 573 | "properties": [ 574 | { 575 | "id": "custom.width", 576 | "value": 205 577 | } 578 | ] 579 | }, 580 | { 581 | "matcher": { 582 | "id": "byName", 583 | "options": "Signature" 584 | }, 585 | "properties": [ 586 | { 587 | "id": "custom.width", 588 | "value": 432 589 | } 590 | ] 591 | }, 592 | { 593 | "matcher": { 594 | "id": "byName", 595 | "options": "Source IP" 596 | }, 597 | "properties": [ 598 | { 599 | "id": "custom.width", 600 | "value": 203 601 | } 602 | ] 603 | }, 604 | { 605 | "matcher": { 606 | "id": "byName", 607 | "options": "Source Port" 608 | }, 609 | "properties": [ 610 | { 611 | "id": "custom.width", 612 | "value": 242 613 | } 614 | ] 615 | }, 616 | { 617 | "matcher": { 618 | "id": "byName", 619 | "options": "Destination IP" 620 | }, 621 | "properties": [ 622 | { 623 | "id": "custom.width", 624 | "value": 394 625 | } 626 | ] 627 | } 628 | ] 629 | }, 630 | "gridPos": { 631 | "h": 8, 632 | "w": 24, 633 | "x": 0, 634 | "y": 19 635 | }, 636 | "id": 241, 637 | "options": { 638 | "footer": { 639 | "fields": "", 640 | "reducer": [ 641 | "sum" 642 | ], 643 | "show": false 644 | }, 645 | "frameIndex": 0, 646 | "showHeader": true, 647 | "sortBy": [] 648 | }, 649 | "pluginVersion": "8.3.3", 650 | "targets": [ 651 | { 652 | "datasource": { 653 | "type": "influxdb", 654 | "uid": "${dataSource}" 655 | }, 656 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"suricata\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"alert_signature\")\r\n |> group()\r\n |> sort(columns: [\"_time\"], desc: true)\r\n |> limit(n:100)", 657 | "refId": "A" 658 | } 659 | ], 660 | "title": "Alert Logs", 661 | "transformations": [ 662 | { 663 | "id": "labelsToFields", 664 | "options": { 665 | "keepLabels": [ 666 | "dest_ip", 667 | "dest_port", 668 | "src_ip", 669 | "src_port" 670 | ] 671 | } 672 | }, 673 | { 674 | "id": "organize", 675 | "options": { 676 | "excludeByName": { 677 | "_field": true, 678 | "_measurement": true, 679 | "event_type": true, 680 | "host": true, 681 | "path": true 682 | }, 683 | "indexByName": { 684 | "_field": 6, 685 | "_measurement": 7, 686 | "_time": 0, 687 | "_value": 1, 688 | "dest_ip": 4, 689 | "dest_port": 5, 690 | "event_type": 8, 691 | "host": 9, 692 | "path": 10, 693 | "src_ip": 2, 694 | "src_port": 3 695 | }, 696 | "renameByName": { 697 | "_time": "Time", 698 | "_value": "Alert Signature", 699 | "alert_signature": "Signature", 700 | "dest_ip": "Destination IP", 701 | "dest_port": "Destination Port", 702 | "src_ip": "Source IP", 703 | "src_port": "Source Port" 704 | } 705 | } 706 | }, 707 | { 708 | "id": "sortBy", 709 | "options": { 710 | "fields": {}, 711 | "sort": [ 712 | { 713 | "desc": true, 714 | "field": "Time" 715 | } 716 | ] 717 | } 718 | } 719 | ], 720 | "type": "table" 721 | } 722 | ], 723 | "schemaVersion": 34, 724 | "style": "dark", 725 | "tags": [], 726 | "templating": { 727 | "list": [ 728 | { 729 | "current": { 730 | "selected": false, 731 | "text": "InfluxDB", 732 | "value": "InfluxDB" 733 | }, 734 | "hide": 0, 735 | "includeAll": false, 736 | "label": "InfluxDB", 737 | "multi": false, 738 | "name": "dataSource", 739 | "options": [], 740 | "query": "influxdb", 741 | "refresh": 1, 742 | "regex": "", 743 | "skipUrlSync": false, 744 | "type": "datasource" 745 | } 746 | ] 747 | }, 748 | "time": { 749 | "from": "now-5m", 750 | "to": "now" 751 | }, 752 | "timepicker": {}, 753 | "timezone": "", 754 | "title": "OPNsense Suricata", 755 | "uid": "94raP_-7z", 756 | "version": 5, 757 | "weekStart": "" 758 | } 759 | -------------------------------------------------------------------------------- /OPNsense-Grafana-Dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "datasource", 8 | "uid": "grafana" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "target": { 15 | "limit": 100, 16 | "matchAny": false, 17 | "tags": [], 18 | "type": "dashboard" 19 | }, 20 | "type": "dashboard" 21 | } 22 | ] 23 | }, 24 | "editable": true, 25 | "fiscalYearStartMonth": 0, 26 | "graphTooltip": 0, 27 | "id": 1, 28 | "links": [], 29 | "liveNow": true, 30 | "panels": [ 31 | { 32 | "collapsed": false, 33 | "datasource": { 34 | "type": "influxdb", 35 | "uid": "${dataSource}" 36 | }, 37 | "gridPos": { 38 | "h": 1, 39 | "w": 24, 40 | "x": 0, 41 | "y": 0 42 | }, 43 | "id": 22, 44 | "panels": [], 45 | "targets": [ 46 | { 47 | "datasource": { 48 | "type": "influxdb", 49 | "uid": "${dataSource}" 50 | }, 51 | "refId": "A" 52 | } 53 | ], 54 | "title": "Hardware", 55 | "type": "row" 56 | }, 57 | { 58 | "datasource": { 59 | "type": "influxdb", 60 | "uid": "${dataSource}" 61 | }, 62 | "fieldConfig": { 63 | "defaults": { 64 | "color": { 65 | "mode": "thresholds" 66 | }, 67 | "mappings": [ 68 | { 69 | "options": { 70 | "match": "null", 71 | "result": { 72 | "index": 0, 73 | "text": "N/A" 74 | } 75 | }, 76 | "type": "special" 77 | } 78 | ], 79 | "thresholds": { 80 | "mode": "absolute", 81 | "steps": [ 82 | { 83 | "color": "green", 84 | "value": null 85 | } 86 | ] 87 | }, 88 | "unit": "none" 89 | }, 90 | "overrides": [] 91 | }, 92 | "gridPos": { 93 | "h": 3, 94 | "w": 2, 95 | "x": 0, 96 | "y": 1 97 | }, 98 | "id": 20, 99 | "options": { 100 | "colorMode": "none", 101 | "graphMode": "none", 102 | "justifyMode": "auto", 103 | "orientation": "horizontal", 104 | "reduceOptions": { 105 | "calcs": [ 106 | "lastNotNull" 107 | ], 108 | "fields": "", 109 | "values": false 110 | }, 111 | "text": {}, 112 | "textMode": "auto" 113 | }, 114 | "pluginVersion": "9.2.10", 115 | "targets": [ 116 | { 117 | "datasource": { 118 | "type": "influxdb", 119 | "uid": "${dataSource}" 120 | }, 121 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -20s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"system\" and\r\n r._field == \"n_users\"\r\n )\r\n |> keep(columns: [\"_value\"])\r\n |> last()", 122 | "refId": "A" 123 | } 124 | ], 125 | "title": "Active Users", 126 | "type": "stat" 127 | }, 128 | { 129 | "datasource": { 130 | "type": "influxdb", 131 | "uid": "${dataSource}" 132 | }, 133 | "fieldConfig": { 134 | "defaults": { 135 | "color": { 136 | "mode": "thresholds" 137 | }, 138 | "displayName": "CPU", 139 | "mappings": [], 140 | "max": 100, 141 | "min": 0, 142 | "thresholds": { 143 | "mode": "absolute", 144 | "steps": [ 145 | { 146 | "color": "green", 147 | "value": null 148 | }, 149 | { 150 | "color": "#EAB839", 151 | "value": 70 152 | }, 153 | { 154 | "color": "red", 155 | "value": 85 156 | } 157 | ] 158 | }, 159 | "unit": "percent" 160 | }, 161 | "overrides": [] 162 | }, 163 | "gridPos": { 164 | "h": 6, 165 | "w": 3, 166 | "x": 2, 167 | "y": 1 168 | }, 169 | "id": 4, 170 | "maxDataPoints": 9000, 171 | "options": { 172 | "orientation": "auto", 173 | "reduceOptions": { 174 | "calcs": [ 175 | "last" 176 | ], 177 | "fields": "", 178 | "values": false 179 | }, 180 | "showThresholdLabels": false, 181 | "showThresholdMarkers": true, 182 | "text": {} 183 | }, 184 | "pluginVersion": "9.2.10", 185 | "targets": [ 186 | { 187 | "datasource": { 188 | "type": "influxdb", 189 | "uid": "${dataSource}" 190 | }, 191 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -20s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"cpu\" and\r\n r._field == \"usage_idle\" and\r\n r.cpu == \"cpu-total\"\r\n )\r\n |> map(fn: (r) => ({\r\n r with\r\n _value: r._value * -1.0 + 100.0\r\n })\r\n )\r\n |> keep(columns: [\"_value\"])\r\n |> last()", 192 | "refId": "A" 193 | } 194 | ], 195 | "title": "CPU Total", 196 | "type": "gauge" 197 | }, 198 | { 199 | "aliasColors": {}, 200 | "bars": false, 201 | "dashLength": 10, 202 | "dashes": false, 203 | "datasource": { 204 | "uid": "${dataSource}" 205 | }, 206 | "fill": 1, 207 | "fillGradient": 0, 208 | "gridPos": { 209 | "h": 6, 210 | "w": 6, 211 | "x": 5, 212 | "y": 1 213 | }, 214 | "hiddenSeries": false, 215 | "id": 2, 216 | "legend": { 217 | "alignAsTable": true, 218 | "avg": true, 219 | "current": true, 220 | "max": true, 221 | "min": false, 222 | "rightSide": true, 223 | "show": true, 224 | "total": false, 225 | "values": true 226 | }, 227 | "lines": true, 228 | "linewidth": 1, 229 | "maxDataPoints": 9000, 230 | "nullPointMode": "null", 231 | "options": { 232 | "alertThreshold": true 233 | }, 234 | "percentage": false, 235 | "pluginVersion": "9.2.10", 236 | "pointradius": 2, 237 | "points": false, 238 | "renderer": "flot", 239 | "seriesOverrides": [], 240 | "spaceLength": 10, 241 | "stack": false, 242 | "steppedLine": false, 243 | "targets": [ 244 | { 245 | "datasource": { 246 | "uid": "${dataSource}" 247 | }, 248 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"cpu\" and\r\n r._field == \"usage_idle\")\r\n |> map(fn: (r) => ({\r\n r with\r\n _value: r._value * -1.0 + 100.0\r\n })\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> drop(columns: [\"host\"])", 249 | "refId": "A" 250 | } 251 | ], 252 | "thresholds": [], 253 | "timeRegions": [], 254 | "title": "CPU", 255 | "tooltip": { 256 | "shared": true, 257 | "sort": 2, 258 | "value_type": "individual" 259 | }, 260 | "transformations": [ 261 | { 262 | "id": "labelsToFields", 263 | "options": { 264 | "valueLabel": "cpu" 265 | } 266 | }, 267 | { 268 | "id": "concatenate", 269 | "options": { 270 | "frameNameLabel": "frame", 271 | "frameNameMode": "drop" 272 | } 273 | }, 274 | { 275 | "id": "organize", 276 | "options": { 277 | "excludeByName": { 278 | "cpu-total": true 279 | }, 280 | "indexByName": {}, 281 | "renameByName": {} 282 | } 283 | } 284 | ], 285 | "type": "graph", 286 | "xaxis": { 287 | "mode": "time", 288 | "show": true, 289 | "values": [] 290 | }, 291 | "yaxes": [ 292 | { 293 | "$$hashKey": "object:39", 294 | "decimals": 0, 295 | "format": "percent", 296 | "logBase": 1, 297 | "max": "100", 298 | "min": "0", 299 | "show": true 300 | }, 301 | { 302 | "$$hashKey": "object:40", 303 | "decimals": 2, 304 | "format": "short", 305 | "logBase": 1, 306 | "show": true 307 | } 308 | ], 309 | "yaxis": { 310 | "align": false 311 | } 312 | }, 313 | { 314 | "datasource": { 315 | "uid": "${dataSource}" 316 | }, 317 | "fieldConfig": { 318 | "defaults": { 319 | "color": { 320 | "mode": "thresholds" 321 | }, 322 | "custom": { 323 | "align": "center", 324 | "displayMode": "auto", 325 | "filterable": false, 326 | "inspect": false, 327 | "minWidth": 1 328 | }, 329 | "decimals": 0, 330 | "mappings": [], 331 | "thresholds": { 332 | "mode": "absolute", 333 | "steps": [ 334 | { 335 | "color": "green", 336 | "value": null 337 | } 338 | ] 339 | }, 340 | "unit": "short" 341 | }, 342 | "overrides": [] 343 | }, 344 | "gridPos": { 345 | "h": 3, 346 | "w": 7, 347 | "x": 11, 348 | "y": 1 349 | }, 350 | "id": 8, 351 | "options": { 352 | "footer": { 353 | "fields": "", 354 | "reducer": [ 355 | "sum" 356 | ], 357 | "show": false 358 | }, 359 | "frameIndex": 0, 360 | "showHeader": true, 361 | "sortBy": [] 362 | }, 363 | "pluginVersion": "9.2.10", 364 | "targets": [ 365 | { 366 | "datasource": { 367 | "uid": "${dataSource}" 368 | }, 369 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"processes\" and\r\n r._field =~ /running|idle|sleeping|wait|blocked|zombies/\r\n )\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))\r\n |> last()", 370 | "refId": "A" 371 | } 372 | ], 373 | "title": "Process Information", 374 | "transformations": [ 375 | { 376 | "id": "concatenate", 377 | "options": { 378 | "frameNameLabel": "frame", 379 | "frameNameMode": "drop" 380 | } 381 | }, 382 | { 383 | "id": "filterFieldsByName", 384 | "options": { 385 | "include": { 386 | "pattern": "/blocked|idle|running|sleeping|wait|zombies/" 387 | } 388 | } 389 | }, 390 | { 391 | "id": "organize", 392 | "options": { 393 | "excludeByName": {}, 394 | "indexByName": { 395 | "blocked": 4, 396 | "idle": 1, 397 | "running": 0, 398 | "sleeping": 2, 399 | "wait": 3, 400 | "zombies": 5 401 | }, 402 | "renameByName": { 403 | "blocked": "Blocked", 404 | "idle": "Idle", 405 | "running": "Running", 406 | "sleeping": "Sleeping", 407 | "wait": "Wait", 408 | "zombies": "Zombies" 409 | } 410 | } 411 | } 412 | ], 413 | "type": "table" 414 | }, 415 | { 416 | "aliasColors": {}, 417 | "bars": false, 418 | "dashLength": 10, 419 | "dashes": false, 420 | "datasource": { 421 | "uid": "${dataSource}" 422 | }, 423 | "fill": 1, 424 | "fillGradient": 0, 425 | "gridPos": { 426 | "h": 6, 427 | "w": 6, 428 | "x": 18, 429 | "y": 1 430 | }, 431 | "hiddenSeries": false, 432 | "id": 10, 433 | "legend": { 434 | "alignAsTable": true, 435 | "avg": true, 436 | "current": true, 437 | "max": true, 438 | "min": false, 439 | "rightSide": true, 440 | "show": true, 441 | "total": false, 442 | "values": true 443 | }, 444 | "lines": true, 445 | "linewidth": 1, 446 | "maxDataPoints": 9000, 447 | "nullPointMode": "null", 448 | "options": { 449 | "alertThreshold": true 450 | }, 451 | "percentage": false, 452 | "pluginVersion": "9.2.10", 453 | "pointradius": 2, 454 | "points": false, 455 | "renderer": "flot", 456 | "seriesOverrides": [], 457 | "spaceLength": 10, 458 | "stack": false, 459 | "steppedLine": false, 460 | "targets": [ 461 | { 462 | "datasource": { 463 | "uid": "${dataSource}" 464 | }, 465 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"system\" and\r\n r._field =~ /load1|load5|load15/\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 466 | "refId": "A" 467 | } 468 | ], 469 | "thresholds": [], 470 | "timeRegions": [], 471 | "title": "Load", 472 | "tooltip": { 473 | "shared": true, 474 | "sort": 0, 475 | "value_type": "individual" 476 | }, 477 | "type": "graph", 478 | "xaxis": { 479 | "mode": "time", 480 | "show": true, 481 | "values": [] 482 | }, 483 | "yaxes": [ 484 | { 485 | "$$hashKey": "object:112", 486 | "decimals": 1, 487 | "format": "none", 488 | "logBase": 1, 489 | "show": true 490 | }, 491 | { 492 | "$$hashKey": "object:113", 493 | "format": "short", 494 | "logBase": 1, 495 | "show": true 496 | } 497 | ], 498 | "yaxis": { 499 | "align": false 500 | } 501 | }, 502 | { 503 | "datasource": { 504 | "type": "influxdb", 505 | "uid": "${dataSource}" 506 | }, 507 | "fieldConfig": { 508 | "defaults": { 509 | "color": { 510 | "mode": "thresholds" 511 | }, 512 | "mappings": [ 513 | { 514 | "options": { 515 | "match": "null", 516 | "result": { 517 | "index": 0, 518 | "text": "N/A" 519 | } 520 | }, 521 | "type": "special" 522 | } 523 | ], 524 | "thresholds": { 525 | "mode": "absolute", 526 | "steps": [ 527 | { 528 | "color": "green", 529 | "value": null 530 | }, 531 | { 532 | "color": "red", 533 | "value": 80 534 | } 535 | ] 536 | } 537 | }, 538 | "overrides": [] 539 | }, 540 | "gridPos": { 541 | "h": 3, 542 | "w": 2, 543 | "x": 0, 544 | "y": 4 545 | }, 546 | "id": 6, 547 | "options": { 548 | "colorMode": "value", 549 | "graphMode": "area", 550 | "justifyMode": "auto", 551 | "orientation": "auto", 552 | "reduceOptions": { 553 | "calcs": [ 554 | "last" 555 | ], 556 | "fields": "/.*/", 557 | "values": false 558 | }, 559 | "text": {}, 560 | "textMode": "auto" 561 | }, 562 | "pluginVersion": "9.2.10", 563 | "targets": [ 564 | { 565 | "datasource": { 566 | "type": "influxdb", 567 | "uid": "${dataSource}" 568 | }, 569 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -20s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"system\" and\r\n r._field == \"uptime_format\"\r\n )\r\n |> keep(columns: [\"_value\"])\r\n |> last()\r\n", 570 | "refId": "A" 571 | } 572 | ], 573 | "title": "Uptime", 574 | "type": "stat" 575 | }, 576 | { 577 | "datasource": { 578 | "uid": "${dataSource}" 579 | }, 580 | "fieldConfig": { 581 | "defaults": { 582 | "color": { 583 | "mode": "thresholds" 584 | }, 585 | "custom": { 586 | "align": "center", 587 | "displayMode": "auto", 588 | "inspect": false, 589 | "minWidth": 1 590 | }, 591 | "decimals": 1, 592 | "mappings": [], 593 | "thresholds": { 594 | "mode": "absolute", 595 | "steps": [ 596 | { 597 | "color": "green", 598 | "value": null 599 | }, 600 | { 601 | "color": "red", 602 | "value": 80 603 | } 604 | ] 605 | }, 606 | "unit": "locale" 607 | }, 608 | "overrides": [] 609 | }, 610 | "gridPos": { 611 | "h": 3, 612 | "w": 7, 613 | "x": 11, 614 | "y": 4 615 | }, 616 | "id": 16, 617 | "options": { 618 | "footer": { 619 | "fields": "", 620 | "reducer": [ 621 | "sum" 622 | ], 623 | "show": false 624 | }, 625 | "showHeader": true 626 | }, 627 | "pluginVersion": "9.2.10", 628 | "targets": [ 629 | { 630 | "datasource": { 631 | "uid": "${dataSource}" 632 | }, 633 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"pf\" and\r\n r._field =~ /match|state-mismatch|state-insert/\r\n )\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))\r\n |> last()", 634 | "refId": "A" 635 | } 636 | ], 637 | "title": "PF Information", 638 | "transformations": [ 639 | { 640 | "id": "concatenate", 641 | "options": { 642 | "frameNameLabel": "frame", 643 | "frameNameMode": "drop" 644 | } 645 | }, 646 | { 647 | "id": "organize", 648 | "options": { 649 | "excludeByName": { 650 | "Time": false 651 | }, 652 | "indexByName": {}, 653 | "renameByName": { 654 | "Time": "", 655 | "match": "Match", 656 | "state-insert": "State Insert", 657 | "state-mismatch": "State Mismatch" 658 | } 659 | } 660 | }, 661 | { 662 | "id": "filterFieldsByName", 663 | "options": { 664 | "include": { 665 | "pattern": "/Match|State Insert|State Mismatch/" 666 | } 667 | } 668 | } 669 | ], 670 | "type": "table" 671 | }, 672 | { 673 | "aliasColors": {}, 674 | "bars": false, 675 | "dashLength": 10, 676 | "dashes": false, 677 | "datasource": { 678 | "type": "influxdb", 679 | "uid": "${dataSource}" 680 | }, 681 | "decimals": 2, 682 | "fieldConfig": { 683 | "defaults": { 684 | "unit": "percent" 685 | }, 686 | "overrides": [] 687 | }, 688 | "fill": 1, 689 | "fillGradient": 0, 690 | "gridPos": { 691 | "h": 5, 692 | "w": 7, 693 | "x": 0, 694 | "y": 7 695 | }, 696 | "hiddenSeries": false, 697 | "id": 12, 698 | "legend": { 699 | "alignAsTable": true, 700 | "avg": true, 701 | "current": true, 702 | "max": true, 703 | "min": false, 704 | "rightSide": true, 705 | "show": true, 706 | "total": false, 707 | "values": true 708 | }, 709 | "lines": true, 710 | "linewidth": 1, 711 | "maxDataPoints": 9000, 712 | "nullPointMode": "null", 713 | "options": { 714 | "alertThreshold": true 715 | }, 716 | "percentage": false, 717 | "pluginVersion": "9.2.10", 718 | "pointradius": 2, 719 | "points": false, 720 | "renderer": "flot", 721 | "seriesOverrides": [], 722 | "spaceLength": 10, 723 | "stack": false, 724 | "steppedLine": false, 725 | "targets": [ 726 | { 727 | "datasource": { 728 | "type": "influxdb", 729 | "uid": "${dataSource}" 730 | }, 731 | "hide": false, 732 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r.device != \"devfs\" and\r\n r.device =~ /^${Disk:regex}$/ and\r\n r._measurement == \"disk\" and\r\n r._field == \"used_percent\" \r\n )", 733 | "refId": "A" 734 | } 735 | ], 736 | "thresholds": [], 737 | "timeRegions": [], 738 | "title": "Disk Utilization", 739 | "tooltip": { 740 | "shared": true, 741 | "sort": 0, 742 | "value_type": "individual" 743 | }, 744 | "transformations": [ 745 | { 746 | "id": "labelsToFields", 747 | "options": { 748 | "valueLabel": "path" 749 | } 750 | } 751 | ], 752 | "type": "graph", 753 | "xaxis": { 754 | "mode": "time", 755 | "show": true, 756 | "values": [] 757 | }, 758 | "yaxes": [ 759 | { 760 | "$$hashKey": "object:206", 761 | "format": "percent", 762 | "logBase": 1, 763 | "max": "100", 764 | "min": "0", 765 | "show": true 766 | }, 767 | { 768 | "$$hashKey": "object:207", 769 | "format": "short", 770 | "logBase": 1, 771 | "show": true 772 | } 773 | ], 774 | "yaxis": { 775 | "align": false 776 | } 777 | }, 778 | { 779 | "aliasColors": {}, 780 | "bars": false, 781 | "dashLength": 10, 782 | "dashes": false, 783 | "datasource": { 784 | "uid": "${dataSource}" 785 | }, 786 | "fieldConfig": { 787 | "defaults": { 788 | "unit": "percent" 789 | }, 790 | "overrides": [] 791 | }, 792 | "fill": 1, 793 | "fillGradient": 0, 794 | "gridPos": { 795 | "h": 5, 796 | "w": 9, 797 | "x": 7, 798 | "y": 7 799 | }, 800 | "hiddenSeries": false, 801 | "id": 14, 802 | "legend": { 803 | "alignAsTable": true, 804 | "avg": true, 805 | "current": true, 806 | "max": true, 807 | "min": true, 808 | "rightSide": true, 809 | "show": true, 810 | "total": false, 811 | "values": true 812 | }, 813 | "lines": true, 814 | "linewidth": 1, 815 | "maxDataPoints": 9000, 816 | "nullPointMode": "null", 817 | "options": { 818 | "alertThreshold": true 819 | }, 820 | "percentage": false, 821 | "pluginVersion": "9.2.10", 822 | "pointradius": 2, 823 | "points": false, 824 | "renderer": "flot", 825 | "seriesOverrides": [], 826 | "spaceLength": 10, 827 | "stack": false, 828 | "steppedLine": false, 829 | "targets": [ 830 | { 831 | "datasource": { 832 | "uid": "${dataSource}" 833 | }, 834 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"mem\" and\r\n r._field == \"used_percent\"\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))\r\n ", 835 | "refId": "A" 836 | } 837 | ], 838 | "thresholds": [], 839 | "timeRegions": [], 840 | "title": "Ram", 841 | "tooltip": { 842 | "shared": true, 843 | "sort": 0, 844 | "value_type": "individual" 845 | }, 846 | "transformations": [ 847 | { 848 | "id": "organize", 849 | "options": { 850 | "excludeByName": {}, 851 | "indexByName": {}, 852 | "renameByName": { 853 | "used_percent": "Ram Used" 854 | } 855 | } 856 | } 857 | ], 858 | "type": "graph", 859 | "xaxis": { 860 | "mode": "time", 861 | "show": true, 862 | "values": [] 863 | }, 864 | "yaxes": [ 865 | { 866 | "$$hashKey": "object:416", 867 | "format": "percent", 868 | "logBase": 1, 869 | "max": "100", 870 | "min": "0", 871 | "show": true 872 | }, 873 | { 874 | "$$hashKey": "object:417", 875 | "format": "short", 876 | "logBase": 1, 877 | "show": true 878 | } 879 | ], 880 | "yaxis": { 881 | "align": false 882 | } 883 | }, 884 | { 885 | "aliasColors": {}, 886 | "bars": false, 887 | "dashLength": 10, 888 | "dashes": false, 889 | "datasource": { 890 | "uid": "${dataSource}" 891 | }, 892 | "fill": 1, 893 | "fillGradient": 0, 894 | "gridPos": { 895 | "h": 5, 896 | "w": 8, 897 | "x": 16, 898 | "y": 7 899 | }, 900 | "hiddenSeries": false, 901 | "id": 18, 902 | "legend": { 903 | "alignAsTable": true, 904 | "avg": true, 905 | "current": true, 906 | "max": true, 907 | "min": true, 908 | "rightSide": true, 909 | "show": true, 910 | "total": false, 911 | "values": true 912 | }, 913 | "lines": true, 914 | "linewidth": 1, 915 | "maxDataPoints": 9000, 916 | "nullPointMode": "null", 917 | "options": { 918 | "alertThreshold": true 919 | }, 920 | "percentage": false, 921 | "pluginVersion": "9.2.10", 922 | "pointradius": 2, 923 | "points": false, 924 | "renderer": "flot", 925 | "seriesOverrides": [], 926 | "spaceLength": 10, 927 | "stack": false, 928 | "steppedLine": false, 929 | "targets": [ 930 | { 931 | "datasource": { 932 | "uid": "${dataSource}" 933 | }, 934 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r.sensor =~ /^${Sensor:regex}$/ and\r\n r._measurement == \"temperature\" and\r\n r._field == \"degrees\"\r\n )\r\n |> aggregateWindow(every:10s, fn: last)", 935 | "refId": "A" 936 | } 937 | ], 938 | "thresholds": [], 939 | "timeRegions": [], 940 | "title": "Temperature Sensors", 941 | "tooltip": { 942 | "shared": true, 943 | "sort": 0, 944 | "value_type": "individual" 945 | }, 946 | "transformations": [ 947 | { 948 | "id": "labelsToFields", 949 | "options": { 950 | "valueLabel": "sensor" 951 | } 952 | } 953 | ], 954 | "type": "graph", 955 | "xaxis": { 956 | "mode": "time", 957 | "show": true, 958 | "values": [] 959 | }, 960 | "yaxes": [ 961 | { 962 | "$$hashKey": "object:33", 963 | "format": "celsius", 964 | "logBase": 1, 965 | "show": true 966 | }, 967 | { 968 | "$$hashKey": "object:34", 969 | "format": "short", 970 | "logBase": 1, 971 | "show": true 972 | } 973 | ], 974 | "yaxis": { 975 | "align": false 976 | } 977 | }, 978 | { 979 | "collapsed": false, 980 | "datasource": { 981 | "type": "influxdb", 982 | "uid": "${dataSource}" 983 | }, 984 | "gridPos": { 985 | "h": 1, 986 | "w": 24, 987 | "x": 0, 988 | "y": 12 989 | }, 990 | "id": 55, 991 | "panels": [], 992 | "targets": [ 993 | { 994 | "datasource": { 995 | "type": "influxdb", 996 | "uid": "${dataSource}" 997 | }, 998 | "refId": "A" 999 | } 1000 | ], 1001 | "title": "Firewall", 1002 | "type": "row" 1003 | }, 1004 | { 1005 | "datasource": { 1006 | "type": "elasticsearch", 1007 | "uid": "${ESdataSource}" 1008 | }, 1009 | "fieldConfig": { 1010 | "defaults": { 1011 | "mappings": [ 1012 | { 1013 | "options": { 1014 | "match": "null", 1015 | "result": { 1016 | "text": "N/A" 1017 | } 1018 | }, 1019 | "type": "special" 1020 | } 1021 | ], 1022 | "thresholds": { 1023 | "mode": "absolute", 1024 | "steps": [ 1025 | { 1026 | "color": "green", 1027 | "value": null 1028 | } 1029 | ] 1030 | }, 1031 | "unit": "none" 1032 | }, 1033 | "overrides": [] 1034 | }, 1035 | "gridPos": { 1036 | "h": 3, 1037 | "w": 6, 1038 | "x": 0, 1039 | "y": 13 1040 | }, 1041 | "id": 111, 1042 | "links": [], 1043 | "options": { 1044 | "colorMode": "value", 1045 | "fieldOptions": { 1046 | "calcs": [ 1047 | "sum" 1048 | ] 1049 | }, 1050 | "graphMode": "area", 1051 | "justifyMode": "auto", 1052 | "orientation": "horizontal", 1053 | "reduceOptions": { 1054 | "calcs": [ 1055 | "sum" 1056 | ], 1057 | "fields": "", 1058 | "values": false 1059 | }, 1060 | "text": {}, 1061 | "textMode": "auto" 1062 | }, 1063 | "pluginVersion": "9.2.10", 1064 | "targets": [ 1065 | { 1066 | "bucketAggs": [ 1067 | { 1068 | "$$hashKey": "object:14", 1069 | "field": "timestamp", 1070 | "id": "2", 1071 | "settings": { 1072 | "interval": "auto", 1073 | "min_doc_count": 0, 1074 | "trimEdges": 0 1075 | }, 1076 | "type": "date_histogram" 1077 | } 1078 | ], 1079 | "datasource": { 1080 | "type": "elasticsearch", 1081 | "uid": "${ESdataSource}" 1082 | }, 1083 | "metrics": [ 1084 | { 1085 | "$$hashKey": "object:12", 1086 | "field": "select field", 1087 | "id": "1", 1088 | "type": "count" 1089 | } 1090 | ], 1091 | "query": "interface:$iface AND action:\"block\"", 1092 | "refId": "A", 1093 | "target": "", 1094 | "timeField": "timestamp" 1095 | } 1096 | ], 1097 | "title": "Firewall Blocked Events on $iface", 1098 | "type": "stat" 1099 | }, 1100 | { 1101 | "circleMaxSize": "", 1102 | "circleMinSize": "", 1103 | "colors": [ 1104 | "#37872D", 1105 | "#E0B400", 1106 | "#C4162A", 1107 | "#8F3BB8" 1108 | ], 1109 | "datasource": { 1110 | "type": "elasticsearch", 1111 | "uid": "${ESdataSource}" 1112 | }, 1113 | "decimals": 0, 1114 | "esGeoPoint": "src_location", 1115 | "esLocationName": "src_ip", 1116 | "esMetric": "Count", 1117 | "gridPos": { 1118 | "h": 11, 1119 | "w": 13, 1120 | "x": 6, 1121 | "y": 13 1122 | }, 1123 | "height": "", 1124 | "hideEmpty": false, 1125 | "hideZero": false, 1126 | "id": 59, 1127 | "initialZoom": "1", 1128 | "links": [], 1129 | "locationData": "countries", 1130 | "mapCenter": "(0°, 0°)", 1131 | "mapCenterLatitude": 0, 1132 | "mapCenterLongitude": 0, 1133 | "maxDataPoints": 1, 1134 | "mouseWheelZoom": false, 1135 | "showLegend": true, 1136 | "stickyLabels": false, 1137 | "tableQueryOptions": { 1138 | "geohashField": "geohash", 1139 | "labelField": "src_ip_geo_country", 1140 | "latitudeField": "src_ip_lat", 1141 | "longitudeField": "src_ip_long", 1142 | "metricField": "Count", 1143 | "queryType": "coordinates" 1144 | }, 1145 | "targets": [ 1146 | { 1147 | "alias": "", 1148 | "bucketAggs": [ 1149 | { 1150 | "field": "src-ip-geo-country", 1151 | "id": "2", 1152 | "settings": { 1153 | "min_doc_count": "1", 1154 | "order": "desc", 1155 | "orderBy": "_term", 1156 | "size": "0" 1157 | }, 1158 | "type": "terms" 1159 | }, 1160 | { 1161 | "field": "timestamp", 1162 | "id": "3", 1163 | "settings": { 1164 | "interval": "auto", 1165 | "min_doc_count": "0", 1166 | "timeZone": "utc", 1167 | "trimEdges": "0" 1168 | }, 1169 | "type": "date_histogram" 1170 | } 1171 | ], 1172 | "datasource": { 1173 | "type": "elasticsearch", 1174 | "uid": "${ESdataSource}" 1175 | }, 1176 | "dsType": "elasticsearch", 1177 | "hide": false, 1178 | "metrics": [ 1179 | { 1180 | "hide": false, 1181 | "id": "1", 1182 | "type": "count" 1183 | } 1184 | ], 1185 | "query": "interface:$iface AND src-ip:$src_ip AND action:\"block\" AND source:$Host", 1186 | "refId": "A", 1187 | "timeField": "timestamp" 1188 | } 1189 | ], 1190 | "thresholds": "10,100,500", 1191 | "title": "Firewall Blocked Event Locations on $iface", 1192 | "type": "grafana-worldmap-panel", 1193 | "unitPlural": "", 1194 | "unitSingle": "", 1195 | "valueName": "total" 1196 | }, 1197 | { 1198 | "datasource": { 1199 | "type": "elasticsearch", 1200 | "uid": "${ESdataSource}" 1201 | }, 1202 | "fieldConfig": { 1203 | "defaults": { 1204 | "mappings": [], 1205 | "thresholds": { 1206 | "mode": "absolute", 1207 | "steps": [ 1208 | { 1209 | "color": "green", 1210 | "value": null 1211 | } 1212 | ] 1213 | }, 1214 | "unit": "none" 1215 | }, 1216 | "overrides": [] 1217 | }, 1218 | "gridPos": { 1219 | "h": 3, 1220 | "w": 5, 1221 | "x": 19, 1222 | "y": 13 1223 | }, 1224 | "id": 67, 1225 | "links": [], 1226 | "maxDataPoints": 100, 1227 | "options": { 1228 | "colorMode": "value", 1229 | "fieldOptions": { 1230 | "calcs": [ 1231 | "first" 1232 | ] 1233 | }, 1234 | "graphMode": "none", 1235 | "justifyMode": "center", 1236 | "orientation": "horizontal", 1237 | "reduceOptions": { 1238 | "calcs": [ 1239 | "first" 1240 | ], 1241 | "fields": "/^src\\-ip$/", 1242 | "values": true 1243 | }, 1244 | "text": {}, 1245 | "textMode": "value" 1246 | }, 1247 | "pluginVersion": "9.2.10", 1248 | "targets": [ 1249 | { 1250 | "bucketAggs": [ 1251 | { 1252 | "$$hashKey": "object:120", 1253 | "fake": true, 1254 | "field": "src-ip", 1255 | "id": "3", 1256 | "settings": { 1257 | "min_doc_count": 1, 1258 | "order": "desc", 1259 | "orderBy": "_count", 1260 | "size": "1" 1261 | }, 1262 | "type": "terms" 1263 | } 1264 | ], 1265 | "datasource": { 1266 | "type": "elasticsearch", 1267 | "uid": "${ESdataSource}" 1268 | }, 1269 | "dsType": "elasticsearch", 1270 | "metrics": [ 1271 | { 1272 | "$$hashKey": "object:118", 1273 | "field": "select field", 1274 | "id": "1", 1275 | "type": "count" 1276 | } 1277 | ], 1278 | "query": "action:\"block\" AND interface:$iface AND src-ip:$src_ip AND dst-port:$dst_port and source:$Host", 1279 | "refId": "A", 1280 | "target": "", 1281 | "timeField": "timestamp" 1282 | } 1283 | ], 1284 | "title": "Top IP Blocked on $iface", 1285 | "transformations": [], 1286 | "type": "stat" 1287 | }, 1288 | { 1289 | "datasource": { 1290 | "type": "elasticsearch", 1291 | "uid": "${ESdataSource}" 1292 | }, 1293 | "fieldConfig": { 1294 | "defaults": { 1295 | "color": { 1296 | "mode": "palette-classic" 1297 | }, 1298 | "custom": { 1299 | "hideFrom": { 1300 | "legend": false, 1301 | "tooltip": false, 1302 | "viz": false 1303 | } 1304 | }, 1305 | "decimals": 0, 1306 | "mappings": [], 1307 | "unit": "none" 1308 | }, 1309 | "overrides": [] 1310 | }, 1311 | "gridPos": { 1312 | "h": 8, 1313 | "w": 6, 1314 | "x": 0, 1315 | "y": 16 1316 | }, 1317 | "id": 61, 1318 | "links": [], 1319 | "maxDataPoints": 1, 1320 | "options": { 1321 | "legend": { 1322 | "calcs": [], 1323 | "displayMode": "table", 1324 | "placement": "right", 1325 | "showLegend": true, 1326 | "values": [ 1327 | "value" 1328 | ] 1329 | }, 1330 | "pieType": "pie", 1331 | "reduceOptions": { 1332 | "calcs": [ 1333 | "sum" 1334 | ], 1335 | "fields": "", 1336 | "values": false 1337 | }, 1338 | "tooltip": { 1339 | "mode": "single", 1340 | "sort": "none" 1341 | } 1342 | }, 1343 | "targets": [ 1344 | { 1345 | "alias": "", 1346 | "bucketAggs": [ 1347 | { 1348 | "$$hashKey": "object:1775", 1349 | "fake": true, 1350 | "field": "dst-port", 1351 | "id": "3", 1352 | "settings": { 1353 | "min_doc_count": 1, 1354 | "order": "desc", 1355 | "orderBy": "_count", 1356 | "size": "5" 1357 | }, 1358 | "type": "terms" 1359 | }, 1360 | { 1361 | "$$hashKey": "object:1776", 1362 | "field": "timestamp", 1363 | "id": "2", 1364 | "settings": { 1365 | "interval": "auto", 1366 | "min_doc_count": 0, 1367 | "trimEdges": 0 1368 | }, 1369 | "type": "date_histogram" 1370 | } 1371 | ], 1372 | "datasource": { 1373 | "type": "elasticsearch", 1374 | "uid": "${ESdataSource}" 1375 | }, 1376 | "dsType": "elasticsearch", 1377 | "metrics": [ 1378 | { 1379 | "$$hashKey": "object:1773", 1380 | "field": "select field", 1381 | "id": "1", 1382 | "type": "count" 1383 | } 1384 | ], 1385 | "query": "interface:$iface AND src-ip:$src_ip AND dst-port:$dst_port AND action:\"block\" AND source:$Host", 1386 | "refId": "A", 1387 | "target": "", 1388 | "timeField": "timestamp" 1389 | } 1390 | ], 1391 | "title": "Firewall Blocked Destination Ports on $iface", 1392 | "type": "piechart" 1393 | }, 1394 | { 1395 | "datasource": { 1396 | "type": "elasticsearch", 1397 | "uid": "${ESdataSource}" 1398 | }, 1399 | "fieldConfig": { 1400 | "defaults": { 1401 | "color": { 1402 | "mode": "palette-classic" 1403 | }, 1404 | "custom": { 1405 | "hideFrom": { 1406 | "legend": false, 1407 | "tooltip": false, 1408 | "viz": false 1409 | } 1410 | }, 1411 | "decimals": 0, 1412 | "mappings": [], 1413 | "unit": "none" 1414 | }, 1415 | "overrides": [] 1416 | }, 1417 | "gridPos": { 1418 | "h": 8, 1419 | "w": 5, 1420 | "x": 19, 1421 | "y": 16 1422 | }, 1423 | "id": 65, 1424 | "links": [], 1425 | "maxDataPoints": 1, 1426 | "options": { 1427 | "legend": { 1428 | "calcs": [], 1429 | "displayMode": "table", 1430 | "placement": "right", 1431 | "showLegend": true, 1432 | "values": [ 1433 | "value" 1434 | ] 1435 | }, 1436 | "pieType": "pie", 1437 | "reduceOptions": { 1438 | "calcs": [ 1439 | "sum" 1440 | ], 1441 | "fields": "", 1442 | "values": false 1443 | }, 1444 | "tooltip": { 1445 | "mode": "single", 1446 | "sort": "none" 1447 | } 1448 | }, 1449 | "targets": [ 1450 | { 1451 | "bucketAggs": [ 1452 | { 1453 | "$$hashKey": "object:1049", 1454 | "fake": true, 1455 | "field": "protocol-name", 1456 | "id": "3", 1457 | "settings": { 1458 | "min_doc_count": 1, 1459 | "order": "desc", 1460 | "orderBy": "_term", 1461 | "size": "0" 1462 | }, 1463 | "type": "terms" 1464 | }, 1465 | { 1466 | "$$hashKey": "object:1050", 1467 | "field": "timestamp", 1468 | "id": "2", 1469 | "settings": { 1470 | "interval": "auto", 1471 | "min_doc_count": 0, 1472 | "trimEdges": 0 1473 | }, 1474 | "type": "date_histogram" 1475 | } 1476 | ], 1477 | "datasource": { 1478 | "type": "elasticsearch", 1479 | "uid": "${ESdataSource}" 1480 | }, 1481 | "dsType": "elasticsearch", 1482 | "metrics": [ 1483 | { 1484 | "$$hashKey": "object:1047", 1485 | "field": "select field", 1486 | "id": "1", 1487 | "type": "count" 1488 | } 1489 | ], 1490 | "query": "interface:$iface AND src-ip:$src_ip AND action:\"block\" AND source:$Host", 1491 | "refId": "A", 1492 | "timeField": "timestamp" 1493 | } 1494 | ], 1495 | "title": "Firewall Blocked Protocols on $iface", 1496 | "type": "piechart" 1497 | }, 1498 | { 1499 | "collapsed": false, 1500 | "datasource": { 1501 | "type": "influxdb", 1502 | "uid": "${dataSource}" 1503 | }, 1504 | "gridPos": { 1505 | "h": 1, 1506 | "w": 24, 1507 | "x": 0, 1508 | "y": 24 1509 | }, 1510 | "id": 24, 1511 | "panels": [], 1512 | "targets": [ 1513 | { 1514 | "datasource": { 1515 | "type": "influxdb", 1516 | "uid": "${dataSource}" 1517 | }, 1518 | "refId": "A" 1519 | } 1520 | ], 1521 | "title": "Network Stats", 1522 | "type": "row" 1523 | }, 1524 | { 1525 | "aliasColors": {}, 1526 | "bars": false, 1527 | "dashLength": 10, 1528 | "dashes": false, 1529 | "datasource": { 1530 | "type": "influxdb", 1531 | "uid": "${dataSource}" 1532 | }, 1533 | "fill": 1, 1534 | "fillGradient": 0, 1535 | "gridPos": { 1536 | "h": 8, 1537 | "w": 8, 1538 | "x": 0, 1539 | "y": 25 1540 | }, 1541 | "hiddenSeries": false, 1542 | "id": 26, 1543 | "legend": { 1544 | "alignAsTable": true, 1545 | "avg": true, 1546 | "current": true, 1547 | "max": true, 1548 | "min": true, 1549 | "show": true, 1550 | "total": false, 1551 | "values": true 1552 | }, 1553 | "lines": true, 1554 | "linewidth": 1, 1555 | "maxDataPoints": 9000, 1556 | "nullPointMode": "null", 1557 | "options": { 1558 | "alertThreshold": true 1559 | }, 1560 | "percentage": false, 1561 | "pluginVersion": "9.2.10", 1562 | "pointradius": 2, 1563 | "points": false, 1564 | "renderer": "flot", 1565 | "seriesOverrides": [], 1566 | "spaceLength": 10, 1567 | "stack": false, 1568 | "steppedLine": false, 1569 | "targets": [ 1570 | { 1571 | "datasource": { 1572 | "type": "influxdb", 1573 | "uid": "${dataSource}" 1574 | }, 1575 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r.gateway_name =~ /^${Gateway:regex}$/ and\r\n r._measurement == \"gateways\" and\r\n r._field == \"delay\"\r\n )", 1576 | "refId": "A" 1577 | } 1578 | ], 1579 | "thresholds": [], 1580 | "timeRegions": [], 1581 | "title": "Gateway RTT - $Gateway ", 1582 | "tooltip": { 1583 | "shared": true, 1584 | "sort": 0, 1585 | "value_type": "individual" 1586 | }, 1587 | "transformations": [ 1588 | { 1589 | "id": "labelsToFields", 1590 | "options": { 1591 | "valueLabel": "gateway_name" 1592 | } 1593 | } 1594 | ], 1595 | "type": "graph", 1596 | "xaxis": { 1597 | "mode": "time", 1598 | "show": true, 1599 | "values": [] 1600 | }, 1601 | "yaxes": [ 1602 | { 1603 | "$$hashKey": "object:164", 1604 | "format": "ms", 1605 | "logBase": 10, 1606 | "show": true 1607 | }, 1608 | { 1609 | "$$hashKey": "object:165", 1610 | "format": "short", 1611 | "logBase": 1, 1612 | "show": true 1613 | } 1614 | ], 1615 | "yaxis": { 1616 | "align": false 1617 | } 1618 | }, 1619 | { 1620 | "datasource": { 1621 | "type": "influxdb", 1622 | "uid": "${dataSource}" 1623 | }, 1624 | "fieldConfig": { 1625 | "defaults": { 1626 | "color": { 1627 | "mode": "thresholds" 1628 | }, 1629 | "custom": { 1630 | "align": "center", 1631 | "displayMode": "color-text", 1632 | "filterable": true, 1633 | "inspect": false, 1634 | "minWidth": 1 1635 | }, 1636 | "mappings": [ 1637 | { 1638 | "options": { 1639 | "0": { 1640 | "index": 2, 1641 | "text": "DOWN" 1642 | }, 1643 | "1": { 1644 | "index": 1, 1645 | "text": "UP" 1646 | }, 1647 | "2": { 1648 | "index": 0, 1649 | "text": "UNKNOWN" 1650 | } 1651 | }, 1652 | "type": "value" 1653 | } 1654 | ], 1655 | "thresholds": { 1656 | "mode": "absolute", 1657 | "steps": [ 1658 | { 1659 | "color": "text", 1660 | "value": null 1661 | } 1662 | ] 1663 | } 1664 | }, 1665 | "overrides": [ 1666 | { 1667 | "matcher": { 1668 | "id": "byName", 1669 | "options": "Status" 1670 | }, 1671 | "properties": [ 1672 | { 1673 | "id": "thresholds", 1674 | "value": { 1675 | "mode": "absolute", 1676 | "steps": [ 1677 | { 1678 | "color": "transparent", 1679 | "value": null 1680 | }, 1681 | { 1682 | "color": "red", 1683 | "value": 0 1684 | }, 1685 | { 1686 | "color": "green", 1687 | "value": 1 1688 | }, 1689 | { 1690 | "color": "orange", 1691 | "value": 2 1692 | } 1693 | ] 1694 | } 1695 | } 1696 | ] 1697 | } 1698 | ] 1699 | }, 1700 | "gridPos": { 1701 | "h": 10, 1702 | "w": 16, 1703 | "x": 8, 1704 | "y": 25 1705 | }, 1706 | "id": 32, 1707 | "options": { 1708 | "footer": { 1709 | "fields": "", 1710 | "reducer": [ 1711 | "sum" 1712 | ], 1713 | "show": false 1714 | }, 1715 | "frameIndex": 0, 1716 | "showHeader": true, 1717 | "sortBy": [] 1718 | }, 1719 | "pluginVersion": "9.2.10", 1720 | "targets": [ 1721 | { 1722 | "datasource": { 1723 | "type": "influxdb", 1724 | "uid": "${dataSource}" 1725 | }, 1726 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"interface\"\r\n )\r\n |> last()\r\n |> group()\r\n |> keep(columns: [\"friendlyname\", \"ip4_address\", \"ip4_subnet\", \"mac_address\", \"name\", \"_value\"])\r\n |> sort(columns:[\"name\"])", 1727 | "refId": "A" 1728 | } 1729 | ], 1730 | "title": "Interface Summary", 1731 | "transformations": [ 1732 | { 1733 | "id": "organize", 1734 | "options": { 1735 | "excludeByName": {}, 1736 | "indexByName": { 1737 | "_value": 5, 1738 | "friendlyname": 1, 1739 | "ip4_address": 2, 1740 | "ip4_subnet": 3, 1741 | "mac_address": 4, 1742 | "name": 0 1743 | }, 1744 | "renameByName": { 1745 | "_value": "Status", 1746 | "friendlyname": "Friendly Name", 1747 | "ip4_address": "IPv4 Address", 1748 | "ip4_subnet": "Subnet", 1749 | "mac_address": "Physical Address", 1750 | "name": "Interface" 1751 | } 1752 | } 1753 | } 1754 | ], 1755 | "type": "table" 1756 | }, 1757 | { 1758 | "aliasColors": {}, 1759 | "bars": false, 1760 | "dashLength": 10, 1761 | "dashes": false, 1762 | "datasource": { 1763 | "uid": "${dataSource}" 1764 | }, 1765 | "fill": 1, 1766 | "fillGradient": 0, 1767 | "gridPos": { 1768 | "h": 8, 1769 | "w": 8, 1770 | "x": 0, 1771 | "y": 33 1772 | }, 1773 | "hiddenSeries": false, 1774 | "id": 38, 1775 | "legend": { 1776 | "alignAsTable": true, 1777 | "avg": true, 1778 | "current": true, 1779 | "max": true, 1780 | "min": false, 1781 | "show": true, 1782 | "total": false, 1783 | "values": true 1784 | }, 1785 | "lines": true, 1786 | "linewidth": 1, 1787 | "maxDataPoints": 9000, 1788 | "nullPointMode": "null", 1789 | "options": { 1790 | "alertThreshold": true 1791 | }, 1792 | "percentage": false, 1793 | "pluginVersion": "9.2.10", 1794 | "pointradius": 2, 1795 | "points": false, 1796 | "renderer": "flot", 1797 | "seriesOverrides": [], 1798 | "spaceLength": 10, 1799 | "stack": false, 1800 | "steppedLine": false, 1801 | "targets": [ 1802 | { 1803 | "datasource": { 1804 | "uid": "${dataSource}" 1805 | }, 1806 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r.gateway_name =~ /^${Gateway:regex}$/ and\r\n r._measurement == \"gateways\" and\r\n r._field == \"loss\"\r\n )", 1807 | "refId": "A" 1808 | } 1809 | ], 1810 | "thresholds": [], 1811 | "timeRegions": [], 1812 | "title": "Gateway Loss - $Gateway ", 1813 | "tooltip": { 1814 | "shared": true, 1815 | "sort": 0, 1816 | "value_type": "individual" 1817 | }, 1818 | "transformations": [ 1819 | { 1820 | "id": "labelsToFields", 1821 | "options": { 1822 | "valueLabel": "gateway_name" 1823 | } 1824 | } 1825 | ], 1826 | "type": "graph", 1827 | "xaxis": { 1828 | "mode": "time", 1829 | "show": true, 1830 | "values": [] 1831 | }, 1832 | "yaxes": [ 1833 | { 1834 | "$$hashKey": "object:97", 1835 | "decimals": 0, 1836 | "format": "percent", 1837 | "logBase": 1, 1838 | "max": "100", 1839 | "min": "0", 1840 | "show": true 1841 | }, 1842 | { 1843 | "$$hashKey": "object:98", 1844 | "format": "short", 1845 | "logBase": 1, 1846 | "show": true 1847 | } 1848 | ], 1849 | "yaxis": { 1850 | "align": false 1851 | } 1852 | }, 1853 | { 1854 | "datasource": { 1855 | "type": "influxdb", 1856 | "uid": "${dataSource}" 1857 | }, 1858 | "fieldConfig": { 1859 | "defaults": { 1860 | "color": { 1861 | "mode": "thresholds" 1862 | }, 1863 | "custom": { 1864 | "align": "center", 1865 | "displayMode": "color-text", 1866 | "filterable": true, 1867 | "inspect": false, 1868 | "minWidth": 1 1869 | }, 1870 | "mappings": [ 1871 | { 1872 | "options": { 1873 | "0": { 1874 | "color": "red", 1875 | "index": 0, 1876 | "text": "OFFLINE" 1877 | }, 1878 | "1": { 1879 | "color": "green", 1880 | "index": 1, 1881 | "text": "ONLINE" 1882 | } 1883 | }, 1884 | "type": "value" 1885 | } 1886 | ], 1887 | "thresholds": { 1888 | "mode": "absolute", 1889 | "steps": [ 1890 | { 1891 | "color": "text", 1892 | "value": null 1893 | } 1894 | ] 1895 | } 1896 | }, 1897 | "overrides": [] 1898 | }, 1899 | "gridPos": { 1900 | "h": 6, 1901 | "w": 16, 1902 | "x": 8, 1903 | "y": 35 1904 | }, 1905 | "id": 46, 1906 | "options": { 1907 | "footer": { 1908 | "fields": "", 1909 | "reducer": [ 1910 | "sum" 1911 | ], 1912 | "show": false 1913 | }, 1914 | "frameIndex": 3, 1915 | "showHeader": true, 1916 | "sortBy": [ 1917 | { 1918 | "desc": false 1919 | } 1920 | ] 1921 | }, 1922 | "pluginVersion": "9.2.10", 1923 | "targets": [ 1924 | { 1925 | "datasource": { 1926 | "type": "influxdb", 1927 | "uid": "${dataSource}" 1928 | }, 1929 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) =>\r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"gateways\" and\r\n r._field =~ /gwdescr|source|monitor|status|gateway_name|interface/\r\n )\r\n |> last()\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 1930 | "refId": "A" 1931 | } 1932 | ], 1933 | "title": "Gateway Summary - $Gateway", 1934 | "transformations": [ 1935 | { 1936 | "id": "filterFieldsByName", 1937 | "options": { 1938 | "include": { 1939 | "names": [ 1940 | "gwdescr", 1941 | "monitor", 1942 | "source", 1943 | "status" 1944 | ] 1945 | } 1946 | } 1947 | }, 1948 | { 1949 | "id": "concatenate", 1950 | "options": { 1951 | "frameNameLabel": "frame", 1952 | "frameNameMode": "drop" 1953 | } 1954 | }, 1955 | { 1956 | "id": "organize", 1957 | "options": { 1958 | "excludeByName": {}, 1959 | "indexByName": {}, 1960 | "renameByName": { 1961 | "gwdescr": "Gateway Description", 1962 | "monitor": "Monitor IP", 1963 | "source": "Source IP", 1964 | "status": "Status" 1965 | } 1966 | } 1967 | } 1968 | ], 1969 | "type": "table" 1970 | }, 1971 | { 1972 | "collapsed": false, 1973 | "datasource": { 1974 | "type": "influxdb", 1975 | "uid": "${dataSource}" 1976 | }, 1977 | "gridPos": { 1978 | "h": 1, 1979 | "w": 24, 1980 | "x": 0, 1981 | "y": 41 1982 | }, 1983 | "id": 30, 1984 | "panels": [], 1985 | "repeat": "WAN", 1986 | "targets": [ 1987 | { 1988 | "datasource": { 1989 | "type": "influxdb", 1990 | "uid": "${dataSource}" 1991 | }, 1992 | "refId": "A" 1993 | } 1994 | ], 1995 | "title": "WAN Interface - $WAN", 1996 | "type": "row" 1997 | }, 1998 | { 1999 | "datasource": { 2000 | "type": "influxdb", 2001 | "uid": "${dataSource}" 2002 | }, 2003 | "fieldConfig": { 2004 | "defaults": { 2005 | "color": { 2006 | "mode": "thresholds" 2007 | }, 2008 | "custom": { 2009 | "align": "center", 2010 | "displayMode": "color-text", 2011 | "filterable": true, 2012 | "inspect": false, 2013 | "minWidth": 1 2014 | }, 2015 | "mappings": [ 2016 | { 2017 | "options": { 2018 | "0": { 2019 | "index": 2, 2020 | "text": "DOWN" 2021 | }, 2022 | "1": { 2023 | "index": 1, 2024 | "text": "UP" 2025 | }, 2026 | "2": { 2027 | "index": 0, 2028 | "text": "UNKNOWN" 2029 | } 2030 | }, 2031 | "type": "value" 2032 | } 2033 | ], 2034 | "thresholds": { 2035 | "mode": "absolute", 2036 | "steps": [ 2037 | { 2038 | "color": "text", 2039 | "value": null 2040 | }, 2041 | { 2042 | "color": "red", 2043 | "value": 0 2044 | }, 2045 | { 2046 | "color": "green", 2047 | "value": 1 2048 | }, 2049 | { 2050 | "color": "orange", 2051 | "value": 2 2052 | } 2053 | ] 2054 | } 2055 | }, 2056 | "overrides": [] 2057 | }, 2058 | "gridPos": { 2059 | "h": 3, 2060 | "w": 24, 2061 | "x": 0, 2062 | "y": 42 2063 | }, 2064 | "id": 28, 2065 | "options": { 2066 | "footer": { 2067 | "fields": "", 2068 | "reducer": [ 2069 | "sum" 2070 | ], 2071 | "show": false 2072 | }, 2073 | "frameIndex": 7, 2074 | "showHeader": true, 2075 | "sortBy": [] 2076 | }, 2077 | "pluginVersion": "9.2.10", 2078 | "targets": [ 2079 | { 2080 | "datasource": { 2081 | "type": "influxdb", 2082 | "uid": "${dataSource}" 2083 | }, 2084 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.name =~ /^${WAN:regex}$/ and\r\n r._measurement == \"interface\" and\r\n r._field == \"status\")\r\n |> group()\r\n |> last()\r\n |> keep(columns: [\"friendlyname\", \"ip4_address\", \"name\", \"ip4_subnet\" \"mac_address\", \"_value\"])", 2085 | "refId": "A" 2086 | } 2087 | ], 2088 | "title": "Interface Summary", 2089 | "transformations": [ 2090 | { 2091 | "id": "organize", 2092 | "options": { 2093 | "excludeByName": {}, 2094 | "indexByName": { 2095 | "_value": 5, 2096 | "friendlyname": 1, 2097 | "ip4_address": 2, 2098 | "ip4_subnet": 3, 2099 | "mac_address": 4, 2100 | "name": 0 2101 | }, 2102 | "renameByName": { 2103 | "_value": "Status", 2104 | "friendlyname": "Friendly Name", 2105 | "ip4_address": "IPV4 Address", 2106 | "ip4_subnet": "Subnet", 2107 | "mac_address": "Physical Address", 2108 | "name": "Interface" 2109 | } 2110 | } 2111 | } 2112 | ], 2113 | "type": "table" 2114 | }, 2115 | { 2116 | "aliasColors": {}, 2117 | "bars": false, 2118 | "dashLength": 10, 2119 | "dashes": false, 2120 | "datasource": { 2121 | "uid": "${dataSource}" 2122 | }, 2123 | "decimals": 2, 2124 | "description": "", 2125 | "fill": 1, 2126 | "fillGradient": 0, 2127 | "gridPos": { 2128 | "h": 7, 2129 | "w": 6, 2130 | "x": 0, 2131 | "y": 45 2132 | }, 2133 | "hiddenSeries": false, 2134 | "id": 34, 2135 | "legend": { 2136 | "alignAsTable": true, 2137 | "avg": true, 2138 | "current": true, 2139 | "max": true, 2140 | "min": false, 2141 | "show": true, 2142 | "total": false, 2143 | "values": true 2144 | }, 2145 | "lines": true, 2146 | "linewidth": 1, 2147 | "maxDataPoints": 9000, 2148 | "nullPointMode": "null", 2149 | "options": { 2150 | "alertThreshold": true 2151 | }, 2152 | "percentage": false, 2153 | "pluginVersion": "9.2.10", 2154 | "pointradius": 2, 2155 | "points": false, 2156 | "renderer": "flot", 2157 | "seriesOverrides": [], 2158 | "spaceLength": 10, 2159 | "stack": false, 2160 | "steppedLine": false, 2161 | "targets": [ 2162 | { 2163 | "datasource": { 2164 | "uid": "${dataSource}" 2165 | }, 2166 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.interface =~ /^${WAN:regex}$/ and \r\n r._measurement == \"net\" and\r\n r._field =~ /bytes_recv|bytes_sent/\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> derivative(unit:1s)\r\n |> map(fn: (r) => ({\r\n r with\r\n _value: r._value * 8.0\r\n })\r\n )\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 2167 | "refId": "A" 2168 | } 2169 | ], 2170 | "thresholds": [], 2171 | "timeRegions": [], 2172 | "title": "WAN Traffic - Bits/sec", 2173 | "tooltip": { 2174 | "shared": true, 2175 | "sort": 0, 2176 | "value_type": "individual" 2177 | }, 2178 | "transformations": [ 2179 | { 2180 | "id": "concatenate", 2181 | "options": { 2182 | "frameNameLabel": "frame", 2183 | "frameNameMode": "drop" 2184 | } 2185 | }, 2186 | { 2187 | "id": "organize", 2188 | "options": { 2189 | "excludeByName": {}, 2190 | "indexByName": {}, 2191 | "renameByName": { 2192 | "Time": "", 2193 | "bytes_recv": "Bits Recv", 2194 | "bytes_sent": "Bits Sent" 2195 | } 2196 | } 2197 | } 2198 | ], 2199 | "type": "graph", 2200 | "xaxis": { 2201 | "mode": "time", 2202 | "show": true, 2203 | "values": [] 2204 | }, 2205 | "yaxes": [ 2206 | { 2207 | "$$hashKey": "object:63", 2208 | "decimals": 2, 2209 | "format": "bps", 2210 | "logBase": 2, 2211 | "show": true 2212 | }, 2213 | { 2214 | "$$hashKey": "object:64", 2215 | "decimals": 2, 2216 | "format": "short", 2217 | "logBase": 1, 2218 | "show": true 2219 | } 2220 | ], 2221 | "yaxis": { 2222 | "align": false 2223 | } 2224 | }, 2225 | { 2226 | "datasource": { 2227 | "uid": "${dataSource}" 2228 | }, 2229 | "fieldConfig": { 2230 | "defaults": { 2231 | "color": { 2232 | "mode": "thresholds" 2233 | }, 2234 | "decimals": 2, 2235 | "mappings": [ 2236 | { 2237 | "options": { 2238 | "match": "null", 2239 | "result": { 2240 | "index": 0, 2241 | "text": "N/A" 2242 | } 2243 | }, 2244 | "type": "special" 2245 | } 2246 | ], 2247 | "thresholds": { 2248 | "mode": "absolute", 2249 | "steps": [ 2250 | { 2251 | "color": "green", 2252 | "value": null 2253 | } 2254 | ] 2255 | }, 2256 | "unit": "bps" 2257 | }, 2258 | "overrides": [] 2259 | }, 2260 | "gridPos": { 2261 | "h": 7, 2262 | "w": 5, 2263 | "x": 6, 2264 | "y": 45 2265 | }, 2266 | "id": 36, 2267 | "maxDataPoints": 9000, 2268 | "options": { 2269 | "colorMode": "value", 2270 | "graphMode": "area", 2271 | "justifyMode": "auto", 2272 | "orientation": "horizontal", 2273 | "reduceOptions": { 2274 | "calcs": [ 2275 | "lastNotNull" 2276 | ], 2277 | "fields": "", 2278 | "values": false 2279 | }, 2280 | "text": {}, 2281 | "textMode": "auto" 2282 | }, 2283 | "pluginVersion": "9.2.10", 2284 | "targets": [ 2285 | { 2286 | "datasource": { 2287 | "uid": "${dataSource}" 2288 | }, 2289 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.interface =~ /^${WAN:regex}$/ and\r\n r._measurement == \"net\" and\r\n r._field =~ /bytes_recv|bytes_sent/\r\n )\r\n |> derivative(unit:1s)\r\n |> map(fn: (r) => ({\r\n r with\r\n _value: r._value * 8.0\r\n })\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))\r\n |> last()", 2290 | "refId": "A" 2291 | } 2292 | ], 2293 | "title": "WAN Traffic - Bits/sec", 2294 | "transformations": [ 2295 | { 2296 | "id": "concatenate", 2297 | "options": { 2298 | "frameNameLabel": "frame", 2299 | "frameNameMode": "drop" 2300 | } 2301 | }, 2302 | { 2303 | "id": "organize", 2304 | "options": { 2305 | "excludeByName": { 2306 | "Time": true 2307 | }, 2308 | "indexByName": {}, 2309 | "renameByName": { 2310 | "bytes_recv": "Bits Recv", 2311 | "bytes_sent": "Bits Sent" 2312 | } 2313 | } 2314 | } 2315 | ], 2316 | "type": "stat" 2317 | }, 2318 | { 2319 | "datasource": { 2320 | "uid": "${dataSource}" 2321 | }, 2322 | "fieldConfig": { 2323 | "defaults": { 2324 | "color": { 2325 | "mode": "thresholds" 2326 | }, 2327 | "decimals": 2, 2328 | "mappings": [ 2329 | { 2330 | "options": { 2331 | "match": "null", 2332 | "result": { 2333 | "index": 0, 2334 | "text": "N/A" 2335 | } 2336 | }, 2337 | "type": "special" 2338 | } 2339 | ], 2340 | "thresholds": { 2341 | "mode": "absolute", 2342 | "steps": [ 2343 | { 2344 | "color": "green", 2345 | "value": null 2346 | } 2347 | ] 2348 | }, 2349 | "unit": "bytes" 2350 | }, 2351 | "overrides": [] 2352 | }, 2353 | "gridPos": { 2354 | "h": 7, 2355 | "w": 5, 2356 | "x": 11, 2357 | "y": 45 2358 | }, 2359 | "hideTimeOverride": true, 2360 | "id": 40, 2361 | "maxDataPoints": 9000, 2362 | "options": { 2363 | "colorMode": "value", 2364 | "graphMode": "area", 2365 | "justifyMode": "auto", 2366 | "orientation": "horizontal", 2367 | "reduceOptions": { 2368 | "calcs": [ 2369 | "sum" 2370 | ], 2371 | "fields": "", 2372 | "values": false 2373 | }, 2374 | "text": {}, 2375 | "textMode": "auto" 2376 | }, 2377 | "pluginVersion": "9.2.10", 2378 | "targets": [ 2379 | { 2380 | "datasource": { 2381 | "uid": "${dataSource}" 2382 | }, 2383 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30d)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.interface =~ /^${WAN:regex}$/ and\r\n r._measurement == \"net\" and\r\n r._field =~ /bytes_recv|bytes_sent/\r\n )\r\n |> aggregateWindow(every: 1h, fn: last)\r\n |> difference(nonNegative: true)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 2384 | "refId": "A" 2385 | } 2386 | ], 2387 | "timeFrom": "now/M", 2388 | "title": "WAN - Bandwidth", 2389 | "transformations": [ 2390 | { 2391 | "id": "concatenate", 2392 | "options": { 2393 | "frameNameLabel": "frame", 2394 | "frameNameMode": "drop" 2395 | } 2396 | }, 2397 | { 2398 | "id": "organize", 2399 | "options": { 2400 | "excludeByName": {}, 2401 | "indexByName": {}, 2402 | "renameByName": { 2403 | "bytes_recv": "Bytes Recv - This Month", 2404 | "bytes_sent": "Bytes Sent - This Month" 2405 | } 2406 | } 2407 | } 2408 | ], 2409 | "type": "stat" 2410 | }, 2411 | { 2412 | "aliasColors": {}, 2413 | "bars": false, 2414 | "dashLength": 10, 2415 | "dashes": false, 2416 | "datasource": { 2417 | "uid": "${dataSource}" 2418 | }, 2419 | "fieldConfig": { 2420 | "defaults": { 2421 | "unit": "short" 2422 | }, 2423 | "overrides": [] 2424 | }, 2425 | "fill": 0, 2426 | "fillGradient": 0, 2427 | "gridPos": { 2428 | "h": 7, 2429 | "w": 8, 2430 | "x": 16, 2431 | "y": 45 2432 | }, 2433 | "hiddenSeries": false, 2434 | "id": 42, 2435 | "legend": { 2436 | "alignAsTable": true, 2437 | "avg": true, 2438 | "current": true, 2439 | "max": true, 2440 | "min": true, 2441 | "show": true, 2442 | "total": false, 2443 | "values": true 2444 | }, 2445 | "lines": true, 2446 | "linewidth": 1, 2447 | "maxDataPoints": 9000, 2448 | "nullPointMode": "null", 2449 | "options": { 2450 | "alertThreshold": true 2451 | }, 2452 | "percentage": false, 2453 | "pluginVersion": "9.2.10", 2454 | "pointradius": 2, 2455 | "points": false, 2456 | "renderer": "flot", 2457 | "seriesOverrides": [], 2458 | "spaceLength": 10, 2459 | "stack": false, 2460 | "steppedLine": false, 2461 | "targets": [ 2462 | { 2463 | "datasource": { 2464 | "uid": "${dataSource}" 2465 | }, 2466 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.interface =~ /^${WAN:regex}$/ and \r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"net\" and\r\n r._field =~ /packets_recv|packets_sent/\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> derivative(unit:1s)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 2467 | "refId": "A" 2468 | } 2469 | ], 2470 | "thresholds": [], 2471 | "timeRegions": [], 2472 | "title": "WAN - Throughput", 2473 | "tooltip": { 2474 | "shared": true, 2475 | "sort": 0, 2476 | "value_type": "individual" 2477 | }, 2478 | "transformations": [ 2479 | { 2480 | "id": "concatenate", 2481 | "options": { 2482 | "frameNameLabel": "frame", 2483 | "frameNameMode": "drop" 2484 | } 2485 | }, 2486 | { 2487 | "id": "organize", 2488 | "options": { 2489 | "excludeByName": {}, 2490 | "indexByName": {}, 2491 | "renameByName": { 2492 | "packets_recv": "Packets Recv", 2493 | "packets_sent": "Packets Sent" 2494 | } 2495 | } 2496 | } 2497 | ], 2498 | "type": "graph", 2499 | "xaxis": { 2500 | "mode": "time", 2501 | "show": true, 2502 | "values": [] 2503 | }, 2504 | "yaxes": [ 2505 | { 2506 | "$$hashKey": "object:191", 2507 | "decimals": 2, 2508 | "format": "short", 2509 | "logBase": 2, 2510 | "show": true 2511 | }, 2512 | { 2513 | "$$hashKey": "object:192", 2514 | "format": "short", 2515 | "logBase": 1, 2516 | "show": true 2517 | } 2518 | ], 2519 | "yaxis": { 2520 | "align": false 2521 | } 2522 | }, 2523 | { 2524 | "collapsed": false, 2525 | "datasource": { 2526 | "type": "influxdb", 2527 | "uid": "${dataSource}" 2528 | }, 2529 | "gridPos": { 2530 | "h": 1, 2531 | "w": 24, 2532 | "x": 0, 2533 | "y": 52 2534 | }, 2535 | "id": 48, 2536 | "panels": [], 2537 | "repeat": "LAN", 2538 | "targets": [ 2539 | { 2540 | "datasource": { 2541 | "type": "influxdb", 2542 | "uid": "${dataSource}" 2543 | }, 2544 | "refId": "A" 2545 | } 2546 | ], 2547 | "title": "LAN Interface - $LAN", 2548 | "type": "row" 2549 | }, 2550 | { 2551 | "datasource": { 2552 | "type": "influxdb", 2553 | "uid": "${dataSource}" 2554 | }, 2555 | "fieldConfig": { 2556 | "defaults": { 2557 | "color": { 2558 | "mode": "thresholds" 2559 | }, 2560 | "custom": { 2561 | "align": "center", 2562 | "displayMode": "color-text", 2563 | "filterable": true, 2564 | "minWidth": 1 2565 | }, 2566 | "mappings": [ 2567 | { 2568 | "options": { 2569 | "0": { 2570 | "index": 2, 2571 | "text": "DOWN" 2572 | }, 2573 | "1": { 2574 | "index": 1, 2575 | "text": "UP" 2576 | }, 2577 | "2": { 2578 | "index": 0, 2579 | "text": "UNKNOWN" 2580 | } 2581 | }, 2582 | "type": "value" 2583 | } 2584 | ], 2585 | "thresholds": { 2586 | "mode": "absolute", 2587 | "steps": [ 2588 | { 2589 | "color": "text" 2590 | }, 2591 | { 2592 | "color": "red", 2593 | "value": 0 2594 | }, 2595 | { 2596 | "color": "green", 2597 | "value": 1 2598 | }, 2599 | { 2600 | "color": "orange", 2601 | "value": 2 2602 | } 2603 | ] 2604 | } 2605 | }, 2606 | "overrides": [] 2607 | }, 2608 | "gridPos": { 2609 | "h": 3, 2610 | "w": 24, 2611 | "x": 0, 2612 | "y": 53 2613 | }, 2614 | "id": 52, 2615 | "options": { 2616 | "footer": { 2617 | "fields": "", 2618 | "reducer": [ 2619 | "sum" 2620 | ], 2621 | "show": false 2622 | }, 2623 | "frameIndex": 7, 2624 | "showHeader": true 2625 | }, 2626 | "pluginVersion": "8.3.3", 2627 | "targets": [ 2628 | { 2629 | "datasource": { 2630 | "type": "influxdb", 2631 | "uid": "${dataSource}" 2632 | }, 2633 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30s)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.name =~ /^${LAN:regex}$/ and\r\n r._measurement == \"interface\" and\r\n r._field == \"status\")\r\n |> group()\r\n |> last()\r\n |> keep(columns: [\"friendlyname\", \"ip4_address\", \"name\", \"ip4_subnet\" \"mac_address\", \"_value\"])", 2634 | "refId": "A" 2635 | } 2636 | ], 2637 | "title": "Interface Summary", 2638 | "transformations": [ 2639 | { 2640 | "id": "organize", 2641 | "options": { 2642 | "excludeByName": {}, 2643 | "indexByName": { 2644 | "_value": 5, 2645 | "friendlyname": 1, 2646 | "ip4_address": 2, 2647 | "ip4_subnet": 3, 2648 | "mac_address": 4, 2649 | "name": 0 2650 | }, 2651 | "renameByName": { 2652 | "_value": "Status", 2653 | "friendlyname": "Friendly Name", 2654 | "ip4_address": "IPV4 Address", 2655 | "ip4_subnet": "Subnet", 2656 | "mac_address": "Physical Address", 2657 | "name": "Interface" 2658 | } 2659 | } 2660 | } 2661 | ], 2662 | "type": "table" 2663 | }, 2664 | { 2665 | "aliasColors": {}, 2666 | "bars": false, 2667 | "dashLength": 10, 2668 | "dashes": false, 2669 | "datasource": { 2670 | "uid": "${dataSource}" 2671 | }, 2672 | "decimals": 2, 2673 | "description": "", 2674 | "fill": 1, 2675 | "fillGradient": 0, 2676 | "gridPos": { 2677 | "h": 7, 2678 | "w": 6, 2679 | "x": 0, 2680 | "y": 56 2681 | }, 2682 | "hiddenSeries": false, 2683 | "id": 49, 2684 | "legend": { 2685 | "alignAsTable": true, 2686 | "avg": true, 2687 | "current": true, 2688 | "max": true, 2689 | "min": false, 2690 | "show": true, 2691 | "total": false, 2692 | "values": true 2693 | }, 2694 | "lines": true, 2695 | "linewidth": 1, 2696 | "maxDataPoints": 9000, 2697 | "nullPointMode": "null", 2698 | "options": { 2699 | "alertThreshold": true 2700 | }, 2701 | "percentage": false, 2702 | "pluginVersion": "8.3.3", 2703 | "pointradius": 2, 2704 | "points": false, 2705 | "renderer": "flot", 2706 | "seriesOverrides": [], 2707 | "spaceLength": 10, 2708 | "stack": false, 2709 | "steppedLine": false, 2710 | "targets": [ 2711 | { 2712 | "datasource": { 2713 | "uid": "${dataSource}" 2714 | }, 2715 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.interface =~ /^${LAN:regex}$/ and \r\n r._measurement == \"net\" and\r\n r._field =~ /bytes_recv|bytes_sent/\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> derivative(unit:1s)\r\n |> map(fn: (r) => ({\r\n r with\r\n _value: r._value * 8.0\r\n })\r\n )\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 2716 | "refId": "A" 2717 | } 2718 | ], 2719 | "thresholds": [], 2720 | "timeRegions": [], 2721 | "title": "${LAN} Traffic - Bits/sec", 2722 | "tooltip": { 2723 | "shared": true, 2724 | "sort": 0, 2725 | "value_type": "individual" 2726 | }, 2727 | "transformations": [ 2728 | { 2729 | "id": "concatenate", 2730 | "options": { 2731 | "frameNameLabel": "frame", 2732 | "frameNameMode": "drop" 2733 | } 2734 | }, 2735 | { 2736 | "id": "organize", 2737 | "options": { 2738 | "excludeByName": {}, 2739 | "indexByName": { 2740 | "Time": 0, 2741 | "bytes_recv": 1, 2742 | "bytes_sent": 2 2743 | }, 2744 | "renameByName": { 2745 | "bytes_recv": "Bits Recv", 2746 | "bytes_sent": "Bits Sent" 2747 | } 2748 | } 2749 | } 2750 | ], 2751 | "type": "graph", 2752 | "xaxis": { 2753 | "mode": "time", 2754 | "show": true, 2755 | "values": [] 2756 | }, 2757 | "yaxes": [ 2758 | { 2759 | "$$hashKey": "object:63", 2760 | "decimals": 2, 2761 | "format": "bps", 2762 | "logBase": 2, 2763 | "show": true 2764 | }, 2765 | { 2766 | "$$hashKey": "object:64", 2767 | "decimals": 2, 2768 | "format": "short", 2769 | "logBase": 1, 2770 | "show": true 2771 | } 2772 | ], 2773 | "yaxis": { 2774 | "align": false 2775 | } 2776 | }, 2777 | { 2778 | "datasource": { 2779 | "uid": "${dataSource}" 2780 | }, 2781 | "fieldConfig": { 2782 | "defaults": { 2783 | "color": { 2784 | "mode": "thresholds" 2785 | }, 2786 | "decimals": 2, 2787 | "mappings": [ 2788 | { 2789 | "options": { 2790 | "match": "null", 2791 | "result": { 2792 | "index": 0, 2793 | "text": "N/A" 2794 | } 2795 | }, 2796 | "type": "special" 2797 | } 2798 | ], 2799 | "thresholds": { 2800 | "mode": "absolute", 2801 | "steps": [ 2802 | { 2803 | "color": "green" 2804 | } 2805 | ] 2806 | }, 2807 | "unit": "bps" 2808 | }, 2809 | "overrides": [] 2810 | }, 2811 | "gridPos": { 2812 | "h": 7, 2813 | "w": 5, 2814 | "x": 6, 2815 | "y": 56 2816 | }, 2817 | "id": 51, 2818 | "maxDataPoints": 9000, 2819 | "options": { 2820 | "colorMode": "value", 2821 | "graphMode": "area", 2822 | "justifyMode": "auto", 2823 | "orientation": "horizontal", 2824 | "reduceOptions": { 2825 | "calcs": [ 2826 | "lastNotNull" 2827 | ], 2828 | "fields": "", 2829 | "values": false 2830 | }, 2831 | "text": {}, 2832 | "textMode": "auto" 2833 | }, 2834 | "pluginVersion": "8.3.3", 2835 | "targets": [ 2836 | { 2837 | "datasource": { 2838 | "uid": "${dataSource}" 2839 | }, 2840 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -1m)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.interface =~ /^${LAN:regex}$/ and\r\n r._measurement == \"net\" and\r\n r._field =~ /bytes_recv|bytes_sent/\r\n )\r\n |> derivative(unit:1s)\r\n |> map(fn: (r) => ({\r\n r with\r\n _value: r._value * 8.0\r\n })\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))\r\n |> last()", 2841 | "refId": "A" 2842 | } 2843 | ], 2844 | "title": "${LAN} Traffic - Bits/sec", 2845 | "transformations": [ 2846 | { 2847 | "id": "concatenate", 2848 | "options": { 2849 | "frameNameLabel": "frame", 2850 | "frameNameMode": "drop" 2851 | } 2852 | }, 2853 | { 2854 | "id": "organize", 2855 | "options": { 2856 | "excludeByName": { 2857 | "Time": true 2858 | }, 2859 | "indexByName": { 2860 | "Time": 0, 2861 | "bytes_recv": 1, 2862 | "bytes_sent": 2 2863 | }, 2864 | "renameByName": { 2865 | "bytes_recv": "Bits Recv", 2866 | "bytes_sent": "Bits Sent" 2867 | } 2868 | } 2869 | } 2870 | ], 2871 | "type": "stat" 2872 | }, 2873 | { 2874 | "datasource": { 2875 | "uid": "${dataSource}" 2876 | }, 2877 | "fieldConfig": { 2878 | "defaults": { 2879 | "color": { 2880 | "mode": "thresholds" 2881 | }, 2882 | "decimals": 2, 2883 | "mappings": [ 2884 | { 2885 | "options": { 2886 | "match": "null", 2887 | "result": { 2888 | "index": 0, 2889 | "text": "N/A" 2890 | } 2891 | }, 2892 | "type": "special" 2893 | } 2894 | ], 2895 | "thresholds": { 2896 | "mode": "absolute", 2897 | "steps": [ 2898 | { 2899 | "color": "green" 2900 | } 2901 | ] 2902 | }, 2903 | "unit": "bytes" 2904 | }, 2905 | "overrides": [] 2906 | }, 2907 | "gridPos": { 2908 | "h": 7, 2909 | "w": 5, 2910 | "x": 11, 2911 | "y": 56 2912 | }, 2913 | "hideTimeOverride": true, 2914 | "id": 50, 2915 | "maxDataPoints": 9000, 2916 | "options": { 2917 | "colorMode": "value", 2918 | "graphMode": "area", 2919 | "justifyMode": "auto", 2920 | "orientation": "horizontal", 2921 | "reduceOptions": { 2922 | "calcs": [ 2923 | "sum" 2924 | ], 2925 | "fields": "", 2926 | "values": false 2927 | }, 2928 | "text": {}, 2929 | "textMode": "auto" 2930 | }, 2931 | "pluginVersion": "8.3.3", 2932 | "targets": [ 2933 | { 2934 | "datasource": { 2935 | "uid": "${dataSource}" 2936 | }, 2937 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: -30d)\r\n |> filter(fn: (r) => \r\n r.host =~ /^${Host:regex}$/ and\r\n r.interface =~ /^${LAN:regex}$/ and\r\n r._measurement == \"net\" and\r\n r._field =~ /bytes_recv|bytes_sent/\r\n )\r\n |> aggregateWindow(every: 1h, fn: last)\r\n |> difference(nonNegative: true)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 2938 | "refId": "A" 2939 | } 2940 | ], 2941 | "timeFrom": "now/M", 2942 | "title": "${LAN} - Bandwidth", 2943 | "transformations": [ 2944 | { 2945 | "id": "concatenate", 2946 | "options": { 2947 | "frameNameLabel": "frame", 2948 | "frameNameMode": "drop" 2949 | } 2950 | }, 2951 | { 2952 | "id": "organize", 2953 | "options": { 2954 | "excludeByName": {}, 2955 | "indexByName": { 2956 | "Time": 0, 2957 | "bytes_recv": 1, 2958 | "bytes_sent": 2 2959 | }, 2960 | "renameByName": { 2961 | "bytes_recv": "Bytes Recv - This Month", 2962 | "bytes_sent": "Bytes Sent - This Month" 2963 | } 2964 | } 2965 | } 2966 | ], 2967 | "type": "stat" 2968 | }, 2969 | { 2970 | "aliasColors": {}, 2971 | "bars": false, 2972 | "dashLength": 10, 2973 | "dashes": false, 2974 | "datasource": { 2975 | "uid": "${dataSource}" 2976 | }, 2977 | "decimals": 2, 2978 | "fieldConfig": { 2979 | "defaults": { 2980 | "unit": "short" 2981 | }, 2982 | "overrides": [] 2983 | }, 2984 | "fill": 0, 2985 | "fillGradient": 0, 2986 | "gridPos": { 2987 | "h": 7, 2988 | "w": 8, 2989 | "x": 16, 2990 | "y": 56 2991 | }, 2992 | "hiddenSeries": false, 2993 | "id": 53, 2994 | "legend": { 2995 | "alignAsTable": true, 2996 | "avg": true, 2997 | "current": true, 2998 | "hideZero": true, 2999 | "max": true, 3000 | "min": true, 3001 | "show": true, 3002 | "total": false, 3003 | "values": true 3004 | }, 3005 | "lines": true, 3006 | "linewidth": 1, 3007 | "maxDataPoints": 9000, 3008 | "nullPointMode": "null", 3009 | "options": { 3010 | "alertThreshold": true 3011 | }, 3012 | "percentage": false, 3013 | "pluginVersion": "8.3.3", 3014 | "pointradius": 2, 3015 | "points": false, 3016 | "renderer": "flot", 3017 | "seriesOverrides": [], 3018 | "spaceLength": 10, 3019 | "stack": false, 3020 | "steppedLine": false, 3021 | "targets": [ 3022 | { 3023 | "datasource": { 3024 | "uid": "${dataSource}" 3025 | }, 3026 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) =>\r\n r.interface =~ /^${LAN:regex}$/ and \r\n r.host =~ /^${Host:regex}$/ and\r\n r._measurement == \"net\" and\r\n r._field =~ /packets_recv|packets_sent/\r\n )\r\n |> aggregateWindow(every: 10s, fn: last)\r\n |> derivative(unit:1s)\r\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:r._field}))", 3027 | "refId": "A" 3028 | } 3029 | ], 3030 | "thresholds": [], 3031 | "timeRegions": [], 3032 | "title": "${LAN} - Throughput", 3033 | "tooltip": { 3034 | "shared": true, 3035 | "sort": 0, 3036 | "value_type": "individual" 3037 | }, 3038 | "transformations": [ 3039 | { 3040 | "id": "concatenate", 3041 | "options": { 3042 | "frameNameLabel": "frame", 3043 | "frameNameMode": "drop" 3044 | } 3045 | }, 3046 | { 3047 | "id": "organize", 3048 | "options": { 3049 | "excludeByName": {}, 3050 | "indexByName": {}, 3051 | "renameByName": { 3052 | "packets_recv": "Packets Recv", 3053 | "packets_sent": "Packets Sent" 3054 | } 3055 | } 3056 | } 3057 | ], 3058 | "type": "graph", 3059 | "xaxis": { 3060 | "mode": "time", 3061 | "show": true, 3062 | "values": [] 3063 | }, 3064 | "yaxes": [ 3065 | { 3066 | "$$hashKey": "object:176", 3067 | "decimals": 2, 3068 | "format": "short", 3069 | "logBase": 2, 3070 | "show": true 3071 | }, 3072 | { 3073 | "$$hashKey": "object:177", 3074 | "decimals": 2, 3075 | "format": "short", 3076 | "label": "", 3077 | "logBase": 1, 3078 | "show": true 3079 | } 3080 | ], 3081 | "yaxis": { 3082 | "align": false 3083 | } 3084 | } 3085 | ], 3086 | "refresh": "10s", 3087 | "schemaVersion": 37, 3088 | "style": "dark", 3089 | "tags": [ 3090 | "OPNsense", 3091 | "telegraf" 3092 | ], 3093 | "templating": { 3094 | "list": [ 3095 | { 3096 | "current": { 3097 | "selected": false, 3098 | "text": "InfluxDB", 3099 | "value": "InfluxDB" 3100 | }, 3101 | "hide": 0, 3102 | "includeAll": false, 3103 | "label": "InfluxDB", 3104 | "multi": false, 3105 | "name": "dataSource", 3106 | "options": [], 3107 | "query": "influxdb", 3108 | "queryValue": "", 3109 | "refresh": 1, 3110 | "regex": "", 3111 | "skipUrlSync": false, 3112 | "type": "datasource" 3113 | }, 3114 | { 3115 | "current": { 3116 | "selected": false, 3117 | "text": "Elasticsearch", 3118 | "value": "Elasticsearch" 3119 | }, 3120 | "hide": 0, 3121 | "includeAll": false, 3122 | "label": "ElasticSearch", 3123 | "multi": false, 3124 | "name": "ESdataSource", 3125 | "options": [], 3126 | "query": "elasticsearch", 3127 | "queryValue": "", 3128 | "refresh": 1, 3129 | "regex": "", 3130 | "skipUrlSync": false, 3131 | "type": "datasource" 3132 | }, 3133 | { 3134 | "current": { 3135 | "selected": false, 3136 | "text": [ 3137 | "All" 3138 | ], 3139 | "value": [ 3140 | "$__all" 3141 | ] 3142 | }, 3143 | "datasource": { 3144 | "uid": "${dataSource}" 3145 | }, 3146 | "definition": "from(bucket: v.defaultBucket)\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn:(r) => r._measurement == \"pf\")\r\n|> keyValues(keyColumns: [\"host\"])\r\n|> group()\r\n|> keep(columns: [\"host\"])\r\n|> distinct(column: \"host\")", 3147 | "hide": 0, 3148 | "includeAll": true, 3149 | "label": "OPNsense", 3150 | "multi": true, 3151 | "name": "Host", 3152 | "options": [], 3153 | "query": "from(bucket: v.defaultBucket)\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn:(r) => r._measurement == \"pf\")\r\n|> keyValues(keyColumns: [\"host\"])\r\n|> group()\r\n|> keep(columns: [\"host\"])\r\n|> distinct(column: \"host\")", 3154 | "refresh": 1, 3155 | "regex": "", 3156 | "skipUrlSync": false, 3157 | "sort": 0, 3158 | "type": "query" 3159 | }, 3160 | { 3161 | "current": { 3162 | "selected": false, 3163 | "text": "All", 3164 | "value": "$__all" 3165 | }, 3166 | "datasource": { 3167 | "uid": "${dataSource}" 3168 | }, 3169 | "definition": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn:(r) => r._measurement == \"disk\" and\r\n r.host =~ /^${Host:regex}$/)\r\n |> keyValues(keyColumns: [\"device\"])\r\n |> group()\r\n |> keep(columns: [\"device\"])\r\n |> distinct(column: \"device\")", 3170 | "hide": 0, 3171 | "includeAll": true, 3172 | "multi": false, 3173 | "name": "Disk", 3174 | "options": [], 3175 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn:(r) => r._measurement == \"disk\" and\r\n r.host =~ /^${Host:regex}$/)\r\n |> keyValues(keyColumns: [\"device\"])\r\n |> group()\r\n |> keep(columns: [\"device\"])\r\n |> distinct(column: \"device\")", 3176 | "refresh": 1, 3177 | "regex": "", 3178 | "skipUrlSync": false, 3179 | "sort": 0, 3180 | "type": "query" 3181 | }, 3182 | { 3183 | "current": { 3184 | "selected": false, 3185 | "text": "All", 3186 | "value": "$__all" 3187 | }, 3188 | "datasource": { 3189 | "uid": "${dataSource}" 3190 | }, 3191 | "definition": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn:(r) => r._measurement == \"temperature\" and\r\n r.host =~ /^${Host:regex}$/)\r\n |> keyValues(keyColumns: [\"sensor\"])\r\n |> group()\r\n |> keep(columns: [\"sensor\"])\r\n |> distinct(column: \"sensor\")", 3192 | "hide": 0, 3193 | "includeAll": true, 3194 | "multi": false, 3195 | "name": "Sensor", 3196 | "options": [], 3197 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn:(r) => r._measurement == \"temperature\" and\r\n r.host =~ /^${Host:regex}$/)\r\n |> keyValues(keyColumns: [\"sensor\"])\r\n |> group()\r\n |> keep(columns: [\"sensor\"])\r\n |> distinct(column: \"sensor\")", 3198 | "refresh": 1, 3199 | "regex": "", 3200 | "skipUrlSync": false, 3201 | "sort": 0, 3202 | "type": "query" 3203 | }, 3204 | { 3205 | "current": { 3206 | "selected": false, 3207 | "text": [ 3208 | "All" 3209 | ], 3210 | "value": [ 3211 | "$__all" 3212 | ] 3213 | }, 3214 | "datasource": { 3215 | "uid": "${dataSource}" 3216 | }, 3217 | "definition": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => \r\n r._measurement == \"interface\"\r\n )\r\n |> keyValues(keyColumns: [\"name\"])\r\n |> group()\r\n |> keep(columns: [\"name\"])\r\n |> sort(columns: [\"name\"])\r\n", 3218 | "hide": 0, 3219 | "includeAll": true, 3220 | "label": "", 3221 | "multi": true, 3222 | "name": "LAN", 3223 | "options": [], 3224 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => \r\n r._measurement == \"interface\"\r\n )\r\n |> keyValues(keyColumns: [\"name\"])\r\n |> group()\r\n |> keep(columns: [\"name\"])\r\n |> sort(columns: [\"name\"])\r\n", 3225 | "refresh": 1, 3226 | "regex": "/^(?!enc0$|igb0$|igb2$|igb3$|ovpnc1$|wg0$)/", 3227 | "skipUrlSync": false, 3228 | "sort": 0, 3229 | "type": "query" 3230 | }, 3231 | { 3232 | "current": { 3233 | "selected": false, 3234 | "text": [ 3235 | "All" 3236 | ], 3237 | "value": [ 3238 | "$__all" 3239 | ] 3240 | }, 3241 | "datasource": { 3242 | "uid": "${dataSource}" 3243 | }, 3244 | "definition": "from(bucket: v.defaultBucket)\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn:(r) => r._measurement == \"gateways\" and\r\n r.host =~ /^${Host:regex}$/)\r\n|> keyValues(keyColumns: [\"gateway_name\"])\r\n|> group()\r\n|> keep(columns: [\"gateway_name\"])\r\n|> distinct(column: \"gateway_name\")", 3245 | "hide": 0, 3246 | "includeAll": true, 3247 | "multi": true, 3248 | "name": "Gateway", 3249 | "options": [], 3250 | "query": "from(bucket: v.defaultBucket)\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn:(r) => r._measurement == \"gateways\" and\r\n r.host =~ /^${Host:regex}$/)\r\n|> keyValues(keyColumns: [\"gateway_name\"])\r\n|> group()\r\n|> keep(columns: [\"gateway_name\"])\r\n|> distinct(column: \"gateway_name\")", 3251 | "refresh": 1, 3252 | "regex": "", 3253 | "skipUrlSync": false, 3254 | "sort": 0, 3255 | "type": "query" 3256 | }, 3257 | { 3258 | "current": { 3259 | "selected": false, 3260 | "text": [ 3261 | "All" 3262 | ], 3263 | "value": [ 3264 | "$__all" 3265 | ] 3266 | }, 3267 | "hide": 0, 3268 | "includeAll": true, 3269 | "multi": true, 3270 | "name": "WAN", 3271 | "options": [ 3272 | { 3273 | "selected": true, 3274 | "text": "All", 3275 | "value": "$__all" 3276 | }, 3277 | { 3278 | "selected": false, 3279 | "text": "igb0", 3280 | "value": "igb0" 3281 | } 3282 | ], 3283 | "query": "igb0", 3284 | "queryValue": "", 3285 | "skipUrlSync": false, 3286 | "type": "custom" 3287 | }, 3288 | { 3289 | "current": { 3290 | "selected": false, 3291 | "text": [ 3292 | "All" 3293 | ], 3294 | "value": [ 3295 | "$__all" 3296 | ] 3297 | }, 3298 | "datasource": { 3299 | "type": "influxdb", 3300 | "uid": "${dataSource}" 3301 | }, 3302 | "definition": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"interface\")\r\n |> last()\r\n |> group(columns: [\"tag\"])\r\n |> keep(columns: [\"name\"])", 3303 | "hide": 0, 3304 | "includeAll": true, 3305 | "label": "FW_Interface", 3306 | "multi": true, 3307 | "name": "iface", 3308 | "options": [], 3309 | "query": "from(bucket: v.defaultBucket)\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"interface\")\r\n |> last()\r\n |> group(columns: [\"tag\"])\r\n |> keep(columns: [\"name\"])", 3310 | "refresh": 1, 3311 | "regex": "", 3312 | "skipUrlSync": false, 3313 | "sort": 0, 3314 | "type": "query" 3315 | }, 3316 | { 3317 | "allValue": "*", 3318 | "current": { 3319 | "selected": false, 3320 | "text": [ 3321 | "All" 3322 | ], 3323 | "value": [ 3324 | "$__all" 3325 | ] 3326 | }, 3327 | "datasource": { 3328 | "type": "elasticsearch", 3329 | "uid": "${ESdataSource}" 3330 | }, 3331 | "definition": "{\"find\": \"terms\", \"field\": \"dst_port\", \"query\": \"interface:$iface\", \"timestamp\": {\n\"timestamp\" : \"now-$__Interval_ms\"\n}}", 3332 | "hide": 0, 3333 | "includeAll": true, 3334 | "label": "FW_Destination Port", 3335 | "multi": true, 3336 | "name": "dst_port", 3337 | "options": [], 3338 | "query": "{\"find\": \"terms\", \"field\": \"dst_port\", \"query\": \"interface:$iface\", \"timestamp\": {\n\"timestamp\" : \"now-$__Interval_ms\"\n}}", 3339 | "refresh": 1, 3340 | "regex": "", 3341 | "skipUrlSync": false, 3342 | "sort": 0, 3343 | "type": "query" 3344 | }, 3345 | { 3346 | "allValue": "*", 3347 | "current": { 3348 | "selected": false, 3349 | "text": [ 3350 | "All" 3351 | ], 3352 | "value": [ 3353 | "$__all" 3354 | ] 3355 | }, 3356 | "datasource": { 3357 | "type": "elasticsearch", 3358 | "uid": "${ESdataSource}" 3359 | }, 3360 | "definition": "{\"find\": \"terms\", \"field\": \"src_ip\", \"query\": \"interface:$iface\", \"timestamp\": {\n\"timestamp\" : \"now-$__Interval_ms\"\n}}", 3361 | "hide": 0, 3362 | "includeAll": true, 3363 | "label": "FW_Source IP", 3364 | "multi": true, 3365 | "name": "src_ip", 3366 | "options": [], 3367 | "query": "{\"find\": \"terms\", \"field\": \"src_ip\", \"query\": \"interface:$iface\", \"timestamp\": {\n\"timestamp\" : \"now-$__Interval_ms\"\n}}", 3368 | "refresh": 1, 3369 | "regex": "", 3370 | "skipUrlSync": false, 3371 | "sort": 0, 3372 | "type": "query" 3373 | }, 3374 | { 3375 | "allValue": "*", 3376 | "current": { 3377 | "selected": false, 3378 | "text": [ 3379 | "All" 3380 | ], 3381 | "value": [ 3382 | "$__all" 3383 | ] 3384 | }, 3385 | "datasource": { 3386 | "type": "elasticsearch", 3387 | "uid": "${ESdataSource}" 3388 | }, 3389 | "definition": "{\"find\": \"terms\", \"field\": \"dst_ip\", \"query\": \"interface:$iface\", \"timestamp\": {\n\"timestamp\" : \"now-$__Interval_ms\"\n}}", 3390 | "hide": 0, 3391 | "includeAll": true, 3392 | "label": "FW_Destination IP", 3393 | "multi": true, 3394 | "name": "dst_ip", 3395 | "options": [], 3396 | "query": "{\"find\": \"terms\", \"field\": \"dst_ip\", \"query\": \"interface:$iface\", \"timestamp\": {\n\"timestamp\" : \"now-$__Interval_ms\"\n}}", 3397 | "refresh": 1, 3398 | "regex": "", 3399 | "skipUrlSync": false, 3400 | "sort": 0, 3401 | "type": "query" 3402 | } 3403 | ] 3404 | }, 3405 | "time": { 3406 | "from": "now-24h", 3407 | "to": "now" 3408 | }, 3409 | "timepicker": { 3410 | "hidden": false, 3411 | "refresh_intervals": [ 3412 | "10s" 3413 | ] 3414 | }, 3415 | "timezone": "", 3416 | "title": "OPNsense", 3417 | "uid": "suTmk8c7k", 3418 | "version": 7, 3419 | "weekStart": "" 3420 | } 3421 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What's Monitored 2 | - Active Users 3 | - Uptime 4 | - CPU Load total 5 | - Disk Utilization 6 | - Memory Utilization 7 | - CPU Utilization per core (Single Graph) 8 | - Ram Utilization time graph 9 | - Load Average 10 | - Load Average Graph 11 | - CPU and ACPI Temperature Sensors 12 | - Gateway Response time - dpinger 13 | - List of interfaces with IPv4, IPv6, Subnet, MAC, Status and pfSense labels thanks to [/u/trumee](https://www.reddit.com/r/PFSENSE/comments/fsss8r/additional_grafana_dashboard/fmal0t6/) 14 | - WAN Statistics - Traffic & Throughput (Identified by dashboard variable) 15 | - LAN Statistics - Traffic & Throughput (Identified by dashboard variable) 16 | - Firewall Statistics - Blocked Ports, Protocols, Events, Blocked IP Locations, and Top Blocked IP 17 | # Changelog 18 | 19 | 20 | Converted InfluxQL queries to Flux. 21 | 22 | Converted pfSense functions to OPNsense. 23 | 24 | Added Firewall panels. 25 | 26 | Added subnet info to Interface Summary panels 27 | 28 | Added Suricata dashboard, see instructions [here](./configure.md#configuration-for-the-suricata-dashboard-optional) 29 | 30 | Added RFC5424 support thanks to [subract](https://github.com/IRQ10/Graylog-OPNsense_Extractors/pull/11) 31 | 32 | ![Main Dashboard](Grafana-OPNsense.png) 33 | 34 | ![Suricata Dashboard](Grafana-OPNsense-Suricata.png) 35 | 36 | # Running on 37 | 38 | Grafana 9.2.10 39 | InfluxDB 2.6.1 40 | Graylog 5.0.2 41 | 42 | 43 | # Configuration 44 | Configuration instructions can be found [here](./configure.md). 45 | -------------------------------------------------------------------------------- /ansible/README.md: -------------------------------------------------------------------------------- 1 | run this using: 2 | ansible-playbook -i inventory.yml -u root -k playbook.yml 3 | 4 | It will prompt you for the SSH password to your OPNSense device. This playbook assumes you've completed the first part of configuring OPNSense. 5 | 6 | Change the IP Address to whatever IP address you use for OPNSense 7 | -------------------------------------------------------------------------------- /ansible/inventory.yml: -------------------------------------------------------------------------------- 1 | [router] 2 | 192.168.1.1 3 | -------------------------------------------------------------------------------- /ansible/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Opnsense for Grafana 3 | hosts: all 4 | become: true 5 | 6 | tasks: 7 | - name: Add telegraf to sudoers 8 | lineinfile: 9 | path: /usr/local/etc/sudoers 10 | state: present 11 | regexp: '^telegraf\s+ALL=' 12 | line: 'telegraf ALL=(root) NOPASSWD: /usr/local/bin/telegraf_pfifgw.php' 13 | validate: '/usr/local/sbin/visudo -cf %s' 14 | 15 | - name: Add telegraf cmd alias to sudoers 16 | lineinfile: 17 | path: /usr/local/etc/sudoers 18 | state: present 19 | regexp: '^Cmnd_Alias\s+PFIGW' 20 | line: 'Cmnd_Alias PFIFGW = /usr/local/bin/telegraf_pfifgw.php' 21 | validate: '/usr/local/sbin/visudo -cf %s' 22 | # - name: disable logging for pfifgw script 23 | 24 | - name: Disable logging for PFIGW 25 | lineinfile: 26 | path: /usr/local/etc/sudoers 27 | state: present 28 | regexp: '^Defaults!PFIGW' 29 | line: 'Defaults!PFIFGW !log_allowed' 30 | validate: '/usr/local/sbin/visudo -cf %s' 31 | 32 | - name: Create telegraf directory 33 | file: 34 | path: /usr/local/etc/telegraf.d 35 | state: directory 36 | owner: telegraf 37 | group: telegraf 38 | mode: '0750' 39 | 40 | - name: Download telegraf config 41 | get_url: 42 | url: https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/custom.conf 43 | dest: /usr/local/etc/telegraf.d/custom.conf 44 | mode: '0644' 45 | 46 | - name: Download telegraf_pfifgw.php 47 | get_url: 48 | url: https://raw.githubusercontent.com/Bsmith101/OPNsense-Dashboard/master/plugins/telegraf_pfifgw.php 49 | dest: /usr/local/bin/telegraf_pfifgw.php 50 | mode: '0755' 51 | 52 | - name: Download telegraf_temperature.sh 53 | get_url: 54 | url: https://raw.githubusercontent.com/Bsmith101/OPNsense-Dashboard/master/plugins/telegraf_temperature.sh 55 | dest: /usr/local/bin/telegraf_temperature.sh 56 | mode: '0755' 57 | 58 | - name: Download Suricata.conf 59 | get_url: 60 | url: https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/suricata/suricata.conf 61 | dest: /usr/local/etc/telegraf.d/suricata.conf 62 | mode: '0644' 63 | 64 | - name: Download suricata custom.yaml 65 | get_url: 66 | url: https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/suricata/custom.yaml 67 | dest: /usr/local/opnsense/service/templates/OPNsense/IDS/custom.yaml 68 | mode: '0644' 69 | 70 | - name: create eve.json 71 | file: 72 | path: /tmp/eve.json 73 | owner: telegraf 74 | state: touch 75 | group: telegraf 76 | mode: '0640' 77 | 78 | - name: Restart Telegraf service 79 | service: 80 | name: telegraf 81 | state: restarted 82 | -------------------------------------------------------------------------------- /config/OPNsense-pack.json: -------------------------------------------------------------------------------- 1 | { 2 | "v": "1", 3 | "id": "6f88399d-9c58-4a70-b7fe-30d4a057132a", 4 | "rev": 2, 5 | "name": "OPNsense Dashboard", 6 | "summary": "This pack includes everything needed to setup Graylog for the dashboard.", 7 | "description": "", 8 | "vendor": "bsmithio", 9 | "url": "https://github.com/bsmithio/OPNsense-Dashboard", 10 | "parameters": [], 11 | "entities": [ 12 | { 13 | "v": "1", 14 | "type": { 15 | "name": "input", 16 | "version": "1" 17 | }, 18 | "id": "a9e59e12-e4a8-4a9f-acda-960e78b8f9b6", 19 | "data": { 20 | "title": { 21 | "@type": "string", 22 | "@value": "Syslog UDP" 23 | }, 24 | "configuration": { 25 | "port": { 26 | "@type": "integer", 27 | "@value": 1514 28 | }, 29 | "recv_buffer_size": { 30 | "@type": "integer", 31 | "@value": 262144 32 | }, 33 | "force_rdns": { 34 | "@type": "boolean", 35 | "@value": false 36 | }, 37 | "allow_override_date": { 38 | "@type": "boolean", 39 | "@value": true 40 | }, 41 | "bind_address": { 42 | "@type": "string", 43 | "@value": "0.0.0.0" 44 | }, 45 | "expand_structured_data": { 46 | "@type": "boolean", 47 | "@value": false 48 | }, 49 | "store_full_message": { 50 | "@type": "boolean", 51 | "@value": true 52 | }, 53 | "charset_name": { 54 | "@type": "string", 55 | "@value": "UTF-8" 56 | }, 57 | "number_worker_threads": { 58 | "@type": "integer", 59 | "@value": 6 60 | } 61 | }, 62 | "static_fields": {}, 63 | "type": { 64 | "@type": "string", 65 | "@value": "org.graylog2.inputs.syslog.udp.SyslogUDPInput" 66 | }, 67 | "global": { 68 | "@type": "boolean", 69 | "@value": false 70 | }, 71 | "extractors": [ 72 | { 73 | "target_field": { 74 | "@type": "string", 75 | "@value": "filterlog_ipv6_icmp" 76 | }, 77 | "condition_value": { 78 | "@type": "string", 79 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*,(in|out),6,.*,icmp,.*)$" 80 | }, 81 | "order": { 82 | "@type": "integer", 83 | "@value": 5 84 | }, 85 | "converters": [ 86 | { 87 | "type": { 88 | "@type": "string", 89 | "@value": "CSV" 90 | }, 91 | "configuration": { 92 | "column_header": { 93 | "@type": "string", 94 | "@value": "rule-number,sub-rule-number,anchor,tracker,interface,reason,action,direction,ip-version,class,flowlabel,hoplimit,protocol-name,protocol-id,length,src-ip,dst-ip,datalength" 95 | } 96 | } 97 | } 98 | ], 99 | "configuration": { 100 | "regex_value": { 101 | "@type": "string", 102 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*)$" 103 | } 104 | }, 105 | "source_field": { 106 | "@type": "string", 107 | "@value": "full_message" 108 | }, 109 | "title": { 110 | "@type": "string", 111 | "@value": "OPNsense: RFC5424 IPv6 ICMP" 112 | }, 113 | "type": { 114 | "@type": "string", 115 | "@value": "REGEX" 116 | }, 117 | "cursor_strategy": { 118 | "@type": "string", 119 | "@value": "COPY" 120 | }, 121 | "condition_type": { 122 | "@type": "string", 123 | "@value": "REGEX" 124 | } 125 | }, 126 | { 127 | "target_field": { 128 | "@type": "string", 129 | "@value": "filterlog_ipv6_tcp" 130 | }, 131 | "condition_value": { 132 | "@type": "string", 133 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*,(in|out),6,.*,tcp,.*)$" 134 | }, 135 | "order": { 136 | "@type": "integer", 137 | "@value": 1 138 | }, 139 | "converters": [ 140 | { 141 | "type": { 142 | "@type": "string", 143 | "@value": "CSV" 144 | }, 145 | "configuration": { 146 | "column_header": { 147 | "@type": "string", 148 | "@value": "rule-number,sub-rule-number,anchor,tracker,interface,reason,action,direction,ipversion,class,flowlabel,hoplimit,protocol-name,protocol-id,length,src-ip,dst-ip,src-port,dst-port,datalength,tcp-flags,sequence,ack,window,urg,options,opnsense-rid" 149 | }, 150 | "trim_leading_whitespace": { 151 | "@type": "boolean", 152 | "@value": true 153 | } 154 | } 155 | } 156 | ], 157 | "configuration": { 158 | "regex_value": { 159 | "@type": "string", 160 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*)$" 161 | } 162 | }, 163 | "source_field": { 164 | "@type": "string", 165 | "@value": "full_message" 166 | }, 167 | "title": { 168 | "@type": "string", 169 | "@value": "OPNsense: RFC5424 IPv6 TCP" 170 | }, 171 | "type": { 172 | "@type": "string", 173 | "@value": "REGEX" 174 | }, 175 | "cursor_strategy": { 176 | "@type": "string", 177 | "@value": "COPY" 178 | }, 179 | "condition_type": { 180 | "@type": "string", 181 | "@value": "REGEX" 182 | } 183 | }, 184 | { 185 | "target_field": { 186 | "@type": "string", 187 | "@value": "filterlog_ipv4_tcp" 188 | }, 189 | "condition_value": { 190 | "@type": "string", 191 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*,(in|out),4,.*,tcp,.*)$" 192 | }, 193 | "order": { 194 | "@type": "integer", 195 | "@value": 0 196 | }, 197 | "converters": [ 198 | { 199 | "type": { 200 | "@type": "string", 201 | "@value": "CSV" 202 | }, 203 | "configuration": { 204 | "column_header": { 205 | "@type": "string", 206 | "@value": "rule-number,sub-rule-number,anchor,tracker,interface,reason,action,direction,ip-version,tos,ecn,ttl,id,offset,ip-flags,protocol-id,protocol-name,length,src-ip,dst-ip,src-port,dst-port,datalength,tcp-flags,sequence,f1,f2,tcp-options,opnsense-rid" 207 | }, 208 | "trim_leading_whitespace": { 209 | "@type": "boolean", 210 | "@value": true 211 | } 212 | } 213 | } 214 | ], 215 | "configuration": { 216 | "regex_value": { 217 | "@type": "string", 218 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*)$" 219 | } 220 | }, 221 | "source_field": { 222 | "@type": "string", 223 | "@value": "full_message" 224 | }, 225 | "title": { 226 | "@type": "string", 227 | "@value": "OPNsense: RFC5424 IPv4 TCP" 228 | }, 229 | "type": { 230 | "@type": "string", 231 | "@value": "REGEX" 232 | }, 233 | "cursor_strategy": { 234 | "@type": "string", 235 | "@value": "COPY" 236 | }, 237 | "condition_type": { 238 | "@type": "string", 239 | "@value": "REGEX" 240 | } 241 | }, 242 | { 243 | "target_field": { 244 | "@type": "string", 245 | "@value": "filterlog_ipv4_udp" 246 | }, 247 | "condition_value": { 248 | "@type": "string", 249 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*,(in|out),4,.*,udp,.*)$" 250 | }, 251 | "order": { 252 | "@type": "integer", 253 | "@value": 2 254 | }, 255 | "converters": [ 256 | { 257 | "type": { 258 | "@type": "string", 259 | "@value": "CSV" 260 | }, 261 | "configuration": { 262 | "column_header": { 263 | "@type": "string", 264 | "@value": "rule-number,sub-rule-number,anchor,tracker,interface,reason,action,direction,ip-version,tos,ecn,ttl,id,offset,flags,protocol-id,protocol-name,length,src-ip,dst-ip,src-port,dst-port,opnsense-rid" 265 | }, 266 | "trim_leading_whitespace": { 267 | "@type": "boolean", 268 | "@value": true 269 | } 270 | } 271 | } 272 | ], 273 | "configuration": { 274 | "regex_value": { 275 | "@type": "string", 276 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*)$" 277 | } 278 | }, 279 | "source_field": { 280 | "@type": "string", 281 | "@value": "full_message" 282 | }, 283 | "title": { 284 | "@type": "string", 285 | "@value": "OPNsense: RFC5424 IPv4 UDP" 286 | }, 287 | "type": { 288 | "@type": "string", 289 | "@value": "REGEX" 290 | }, 291 | "cursor_strategy": { 292 | "@type": "string", 293 | "@value": "COPY" 294 | }, 295 | "condition_type": { 296 | "@type": "string", 297 | "@value": "REGEX" 298 | } 299 | }, 300 | { 301 | "target_field": { 302 | "@type": "string", 303 | "@value": "filterlog_ipv4_icmp" 304 | }, 305 | "condition_value": { 306 | "@type": "string", 307 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*,(in|out),4,.*,icmp,.*)$" 308 | }, 309 | "order": { 310 | "@type": "integer", 311 | "@value": 4 312 | }, 313 | "converters": [ 314 | { 315 | "type": { 316 | "@type": "string", 317 | "@value": "CSV" 318 | }, 319 | "configuration": { 320 | "column_header": { 321 | "@type": "string", 322 | "@value": "rule-number,sub-rule-number,anchor,tracker,interface,reason,action,direction,ip-version,tos,ecn,ttl,id,offset,flags,protocol-id,protocol-name,length,src-ip,dst-ip,datalength" 323 | } 324 | } 325 | } 326 | ], 327 | "configuration": { 328 | "regex_value": { 329 | "@type": "string", 330 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*)$" 331 | } 332 | }, 333 | "source_field": { 334 | "@type": "string", 335 | "@value": "full_message" 336 | }, 337 | "title": { 338 | "@type": "string", 339 | "@value": "OPNsense: RFC5424 IPv4 ICMP" 340 | }, 341 | "type": { 342 | "@type": "string", 343 | "@value": "REGEX" 344 | }, 345 | "cursor_strategy": { 346 | "@type": "string", 347 | "@value": "COPY" 348 | }, 349 | "condition_type": { 350 | "@type": "string", 351 | "@value": "REGEX" 352 | } 353 | }, 354 | { 355 | "target_field": { 356 | "@type": "string", 357 | "@value": "filterlog_ipv6_udp" 358 | }, 359 | "condition_value": { 360 | "@type": "string", 361 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*,(in|out),6,.*,udp,.*)$" 362 | }, 363 | "order": { 364 | "@type": "integer", 365 | "@value": 3 366 | }, 367 | "converters": [ 368 | { 369 | "type": { 370 | "@type": "string", 371 | "@value": "CSV" 372 | }, 373 | "configuration": { 374 | "column_header": { 375 | "@type": "string", 376 | "@value": "rule-number,sub-rule-number,anchor,tracker,interface,reason,action,direction,ip-version,class,flowlabel,hoplimit,protocol-name,protocol-id,length,src-ip,dst-ip,src-port,dst-port,opnsense-rid" 377 | } 378 | } 379 | } 380 | ], 381 | "configuration": { 382 | "regex_value": { 383 | "@type": "string", 384 | "@value": "^(?i).*\\sfilterlog.+\\[.+\\]\\s(.*)$" 385 | } 386 | }, 387 | "source_field": { 388 | "@type": "string", 389 | "@value": "full_message" 390 | }, 391 | "title": { 392 | "@type": "string", 393 | "@value": "OPNsense: RFC5424 IPv6 UDP" 394 | }, 395 | "type": { 396 | "@type": "string", 397 | "@value": "REGEX" 398 | }, 399 | "cursor_strategy": { 400 | "@type": "string", 401 | "@value": "COPY" 402 | }, 403 | "condition_type": { 404 | "@type": "string", 405 | "@value": "REGEX" 406 | } 407 | } 408 | ] 409 | }, 410 | "constraints": [ 411 | { 412 | "type": "server-version", 413 | "version": ">=5.0.2+59d96f8" 414 | } 415 | ] 416 | }, 417 | { 418 | "v": "1", 419 | "type": { 420 | "name": "lookup_adapter", 421 | "version": "1" 422 | }, 423 | "id": "056ed2d3-38f8-41cc-8cb0-b9fdb8d95d32", 424 | "data": { 425 | "_scope": { 426 | "@type": "string", 427 | "@value": "DEFAULT" 428 | }, 429 | "name": { 430 | "@type": "string", 431 | "@value": "geoip" 432 | }, 433 | "title": { 434 | "@type": "string", 435 | "@value": "GeoIP" 436 | }, 437 | "description": { 438 | "@type": "string", 439 | "@value": "Geo IP Lookup Table" 440 | }, 441 | "configuration": { 442 | "type": { 443 | "@type": "string", 444 | "@value": "maxmind_geoip" 445 | }, 446 | "path": { 447 | "@type": "string", 448 | "@value": "/usr/share/graylog/data/data/GeoLite2-Country.mmdb" 449 | }, 450 | "database_type": { 451 | "@type": "string", 452 | "@value": "MAXMIND_COUNTRY" 453 | }, 454 | "check_interval": { 455 | "@type": "long", 456 | "@value": 1 457 | }, 458 | "check_interval_unit": { 459 | "@type": "string", 460 | "@value": "MINUTES" 461 | } 462 | } 463 | }, 464 | "constraints": [ 465 | { 466 | "type": "server-version", 467 | "version": ">=5.0.2+59d96f8" 468 | } 469 | ] 470 | }, 471 | { 472 | "v": "1", 473 | "type": { 474 | "name": "lookup_cache", 475 | "version": "1" 476 | }, 477 | "id": "776809e0-ea08-45e0-9df3-f06bb15585ed", 478 | "data": { 479 | "_scope": { 480 | "@type": "string", 481 | "@value": "DEFAULT" 482 | }, 483 | "name": { 484 | "@type": "string", 485 | "@value": "geoip" 486 | }, 487 | "title": { 488 | "@type": "string", 489 | "@value": "GeoIP" 490 | }, 491 | "description": { 492 | "@type": "string", 493 | "@value": "GeoIP Cache" 494 | }, 495 | "configuration": { 496 | "type": { 497 | "@type": "string", 498 | "@value": "guava_cache" 499 | }, 500 | "max_size": { 501 | "@type": "integer", 502 | "@value": 1000 503 | }, 504 | "expire_after_access": { 505 | "@type": "long", 506 | "@value": 1 507 | }, 508 | "expire_after_access_unit": { 509 | "@type": "string", 510 | "@value": "SECONDS" 511 | }, 512 | "expire_after_write": { 513 | "@type": "long", 514 | "@value": 0 515 | } 516 | } 517 | }, 518 | "constraints": [ 519 | { 520 | "type": "server-version", 521 | "version": ">=5.0.2+59d96f8" 522 | } 523 | ] 524 | }, 525 | { 526 | "v": "1", 527 | "type": { 528 | "name": "lookup_table", 529 | "version": "1" 530 | }, 531 | "id": "19a27a83-5ffc-4f8d-a39c-a00d7c4ea36a", 532 | "data": { 533 | "default_single_value_type": { 534 | "@type": "string", 535 | "@value": "NULL" 536 | }, 537 | "cache_name": { 538 | "@type": "string", 539 | "@value": "776809e0-ea08-45e0-9df3-f06bb15585ed" 540 | }, 541 | "name": { 542 | "@type": "string", 543 | "@value": "geoip" 544 | }, 545 | "default_multi_value_type": { 546 | "@type": "string", 547 | "@value": "NULL" 548 | }, 549 | "default_multi_value": { 550 | "@type": "string", 551 | "@value": "" 552 | }, 553 | "data_adapter_name": { 554 | "@type": "string", 555 | "@value": "056ed2d3-38f8-41cc-8cb0-b9fdb8d95d32" 556 | }, 557 | "_scope": { 558 | "@type": "string", 559 | "@value": "DEFAULT" 560 | }, 561 | "title": { 562 | "@type": "string", 563 | "@value": "GeoIP" 564 | }, 565 | "default_single_value": { 566 | "@type": "string", 567 | "@value": "" 568 | }, 569 | "description": { 570 | "@type": "string", 571 | "@value": "Geo IP Lookup" 572 | } 573 | }, 574 | "constraints": [ 575 | { 576 | "type": "server-version", 577 | "version": ">=5.0.2+59d96f8" 578 | } 579 | ] 580 | }, 581 | { 582 | "v": "1", 583 | "type": { 584 | "name": "pipeline", 585 | "version": "1" 586 | }, 587 | "id": "5a7ec7eb-d413-4d6f-96e1-70a73f4df8e1", 588 | "data": { 589 | "title": { 590 | "@type": "string", 591 | "@value": "GeoIP" 592 | }, 593 | "description": { 594 | "@type": "string", 595 | "@value": "GeoIP" 596 | }, 597 | "source": { 598 | "@type": "string", 599 | "@value": "pipeline \"GeoIP\"\nstage 0 match either\nrule \"GeoIP lookup: src-ip\"\nend" 600 | }, 601 | "connected_streams": [ 602 | { 603 | "@type": "string", 604 | "@value": "67c8983f-c842-4a33-9650-94f19a793e0d" 605 | } 606 | ] 607 | }, 608 | "constraints": [ 609 | { 610 | "type": "server-version", 611 | "version": ">=5.0.2+59d96f8" 612 | } 613 | ] 614 | }, 615 | { 616 | "v": "1", 617 | "type": { 618 | "name": "pipeline_rule", 619 | "version": "1" 620 | }, 621 | "id": "9bea4894-60ec-495b-8531-0f5e27fc8025", 622 | "data": { 623 | "title": { 624 | "@type": "string", 625 | "@value": "GeoIP lookup: src-ip" 626 | }, 627 | "description": { 628 | "@type": "string", 629 | "@value": "" 630 | }, 631 | "source": { 632 | "@type": "string", 633 | "@value": "rule \"GeoIP lookup: src-ip\"\nwhen\nhas_field(\"src-ip\")\nthen\nlet geo = lookup(\"geoip\", to_string($message.\"src-ip\"));\nset_field(\"src-ip-geo-location\", geo[\"coordinates\"]);\nset_field(\"src-ip-geo-country\", geo[\"country\"].iso_code);\nset_field(\"src-ip-geo-city\", geo[\"city\"].names.en);\nend" 634 | } 635 | }, 636 | "constraints": [ 637 | { 638 | "type": "server-version", 639 | "version": ">=5.0.2+59d96f8" 640 | } 641 | ] 642 | }, 643 | { 644 | "v": "1", 645 | "type": { 646 | "name": "stream", 647 | "version": "1" 648 | }, 649 | "id": "67c8983f-c842-4a33-9650-94f19a793e0d", 650 | "data": { 651 | "alarm_callbacks": [], 652 | "outputs": [], 653 | "remove_matches": { 654 | "@type": "boolean", 655 | "@value": true 656 | }, 657 | "title": { 658 | "@type": "string", 659 | "@value": "OPNsense / filterlog" 660 | }, 661 | "stream_rules": [ 662 | { 663 | "type": { 664 | "@type": "string", 665 | "@value": "CONTAINS" 666 | }, 667 | "field": { 668 | "@type": "string", 669 | "@value": "application_name" 670 | }, 671 | "value": { 672 | "@type": "string", 673 | "@value": "filterlog" 674 | }, 675 | "inverted": { 676 | "@type": "boolean", 677 | "@value": false 678 | }, 679 | "description": { 680 | "@type": "string", 681 | "@value": "" 682 | } 683 | } 684 | ], 685 | "alert_conditions": [], 686 | "matching_type": { 687 | "@type": "string", 688 | "@value": "OR" 689 | }, 690 | "disabled": { 691 | "@type": "boolean", 692 | "@value": false 693 | }, 694 | "description": { 695 | "@type": "string", 696 | "@value": "OPNsense filter logs" 697 | }, 698 | "default_stream": { 699 | "@type": "boolean", 700 | "@value": false 701 | } 702 | }, 703 | "constraints": [ 704 | { 705 | "type": "server-version", 706 | "version": ">=5.0.2+59d96f8" 707 | } 708 | ] 709 | } 710 | ] 711 | } 712 | -------------------------------------------------------------------------------- /config/custom.conf: -------------------------------------------------------------------------------- 1 | [[inputs.exec]] 2 | commands = [ 3 | "sudo /usr/local/bin/telegraf_pfifgw.php", 4 | "sh /usr/local/bin/telegraf_temperature.sh" 5 | ] 6 | data_format = "influx" 7 | -------------------------------------------------------------------------------- /config/suricata/custom.yaml: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | --- 3 | outputs: 4 | - eve-log: 5 | enabled: yes 6 | filetype: regular 7 | filename: /tmp/eve.json 8 | filemode: 660 9 | types: 10 | - alert: 11 | tagged-packets: yes 12 | http: yes 13 | tls: yes 14 | 15 | - drop: 16 | alerts: yes 17 | flows: start 18 | -------------------------------------------------------------------------------- /config/suricata/suricata.conf: -------------------------------------------------------------------------------- 1 | [[inputs.tail]] 2 | data_format = "json" 3 | files = ["/tmp/eve.json"] 4 | name_override = "suricata" 5 | tag_keys = ["event_type","src_ip","src_port","dest_ip","dest_port"] 6 | json_string_fields = ["*"] 7 | -------------------------------------------------------------------------------- /configure.md: -------------------------------------------------------------------------------- 1 | - [Docker](#docker) 2 | - [Configuring InfluxDB](#configuring-influxdb) 3 | - [Configuring Telegraf](#configuring-telegraf) 4 | * [For previous users](#for-previous-users) 5 | * [Install the plugin and configure options](#install-the-plugin-and-configure-options) 6 | * [Alternative OPNSense Configuration via Ansible](#alternative-opnsense-configuration-via-ansible) 7 | * [Add telegraf to sudoers](#add-telegraf-to-sudoers) 8 | * [Telegraf Plugins](#telegraf-plugins) 9 | - [Configuring Graylog](#configuring-graylog) 10 | * [Add GeoIP to Graylog](#add-geoip-to-graylog) 11 | * [Configure Additional Settings](#configure-additional-settings) 12 | * [Add Graylog server as syslog target on OPNsense](#add-graylog-server-as-syslog-target-on-opnsense) 13 | - [Configuring Grafana](#configuring-grafana) 14 | * [Add InfluxDB and ElasticSearch data sources](#add-influxdb-and-elasticsearch-data-sources) 15 | * [Import Dashboard](#import-dashboard) 16 | * [Configure Variables](#configure-variables) 17 | - [Configuration for the Suricata dashboard #Optional](#configuration-for-the-suricata-dashboard-optional) 18 | * [Add the necessary files](#add-the-necessary-files) 19 | * [Restart Suricata and Telegraf](#restart-suricata-and-telegraf) 20 | * [Import the Suricata Dashboard](#import-the-suricata-dashboard) 21 | - [Troubleshooting](#troubleshooting) 22 | * [Telegraf Plugins](#telegraf-plugins-1) 23 | * [Telegraf Troubleshooting](#telegraf-troubleshooting) 24 | * [InfluxDB](#influxdb) 25 | * [View measurements](#view-measurements) 26 | * [View field values](#view-field-values) 27 | * [How to drop an InfluxDB v2 measurement](#how-to-drop-an-influxdb-v2-measurement) 28 | * [Learn more about Flux queries](#learn-more-about-flux-queries) 29 | * [Suricata Troubleshooting](#suricata-troubleshooting) 30 | * [Map Issues](#map-issues) 31 | 32 | ## Docker 33 | 34 | To simplify everything, we'll use a Docker Compose file. 35 | 36 | You will need to have Docker and Docker Compose installed on a server that will host the dashboard. 37 | 38 | [Install Docker](https://docs.docker.com/engine/install/) 39 | 40 | [Install Docker Compose](https://docs.docker.com/compose/install/) 41 | 42 | After you've installed Docker and Docker Compose, download the docker-compose.yaml from this repo. 43 | 44 | `curl https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/docker-compose.yaml -o docker-compose.yaml` 45 | 46 | It's important that you change the TZ environment variable to your timezone for everything to work properly. 47 | I also recommend you change the passwords in this compose file as well. 48 | After you've made the necessary changes, run `docker-compose up -d` in the same directory as your docker-compose.yaml. 49 | Once you have your docker containers running, follow the steps below. 50 | 51 | ## Configuring InfluxDB 52 | After InfluxDB is started, go to http://(ip of docker server):8086, you will need to setup your username, password, bucket and organization here. Once that is done navigate to the Data tab, click on Telegraf, and create a configuration for a system. Name it, and copy your API token, you will need this for your Telegraf configuration. You will also need to generate another API token for Grafana. Click on API tokens -> Generate API Token -> Read/Write Access -> Click on your bucket under Read -> and Save. Copy this somewhere as well, you'll need it for Grafana. 53 | 54 | 55 | ## Configuring Telegraf 56 | 57 | ### For previous users 58 | 59 | If you previously used the pkg install version of telegraf, follow these instructions. 60 | 61 | Run `sudo pkg remove telegraf` to remove telegraf. 62 | 63 | Delete the line that starts with telegraf in /usr/local/etc/sudoers. 64 | 65 | Once those are done you can continue with the new configuration. 66 | 67 | 68 | ### Install the plugin and configure options 69 | Install the Telegraf plugin on OPNsense, to do so, navigate to System -> Firmware -> Plugins -> Search for telegraf, and click the plus icon to install. 70 | 71 | ![](https://www.bsmithio.com/post/opnsense-dashboard/plugin.png) 72 | 73 | Navigate to Services -> Telegraf -> Input 74 | 75 | Enable Network and PF Inputs. 76 | 77 | ![](https://www.bsmithio.com/post/opnsense-dashboard/pfinput.png) 78 | 79 | Then click Save. 80 | 81 | Now navigate to Services -> Telegraf -> Output 82 | 83 | Enable Influx v2 Output and fill in the following: 84 | 85 | Influx v2 Token: Your InfluxDB Token 86 | 87 | Influx v2 URL: Your InfluxDB URL, this will be the IP address or hostname of your system that is running InfluxDB. E.g http://192.168.1.10:8086 88 | 89 | Influx v2 Organization: Your InfluxDB Organization 90 | 91 | Influx v2 Bucket: Your InfluxDB Bucket 92 | 93 | ![](https://www.bsmithio.com/post/opnsense-dashboard/influxbucket.png) 94 | 95 | Then click Save. 96 | 97 | 98 | ### Alternative OPNSense Configuration via Ansible 99 | 100 | You can use Ansible to automate a few sections. Install [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/installation_distros.html) on your linux server and use the files at https://github.com/bsmithio/OPNsense-Dashboard/tree/master/ansible. If you use this method you can skip these sections: Add telegraf to sudoers, Telegraf Plugins, and Configuration for the Suricata dashboard. 101 | 102 | ### Add telegraf to sudoers 103 | 104 | After that, we need to add telegraf to sudoers and use nopasswd to restrict telegraf to only what it needs to run as root. 105 | 106 | ``` 107 | printf 'telegraf ALL=(root) NOPASSWD: /usr/local/bin/telegraf_pfifgw.php\n' | sudo tee -a /usr/local/etc/sudoers > /dev/null 108 | ``` 109 | 110 | You may also wish to disable sudo logging for telegraf_pfifgw.php, otherwise you'll see many sudo logs from telegraf running the script every 10 seconds. 111 | 112 | ``` 113 | printf 'Cmnd_Alias PFIFGW = /usr/local/bin/telegraf_pfifgw.php\n' | sudo tee -a /usr/local/etc/sudoers > /dev/null 114 | printf 'Defaults!PFIFGW !log_allowed\n' | sudo tee -a /usr/local/etc/sudoers > /dev/null 115 | ``` 116 | 117 | Add the [custom.conf](./config/custom.conf) telegraf config to /usr/local/etc/telegraf.d 118 | 119 | ``` 120 | sudo mkdir /usr/local/etc/telegraf.d 121 | sudo chown telegraf:telegraf /usr/local/etc/telegraf.d 122 | sudo chmod 750 /usr/local/etc/telegraf.d 123 | sudo curl https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/custom.conf -o /usr/local/etc/telegraf.d/custom.conf 124 | ``` 125 | 126 | ### Telegraf Plugins 127 | 128 | **Plugins must be copied to your OPNsense system** 129 | 130 | Place [telegraf_pfifgw.php](https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/plugins/telegraf_pfifgw.php) and [telegraf_temperature.sh](https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/plugins/telegraf_temperature.sh) in /usr/local/bin and chmod them to 755. 131 | 132 | ``` 133 | curl "https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/plugins/telegraf_pfifgw.php" -o /usr/local/bin/telegraf_pfifgw.php 134 | curl "https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/plugins/telegraf_temperature.sh" -o /usr/local/bin/telegraf_temperature.sh 135 | chmod 755 /usr/local/bin/telegraf_temperature.sh /usr/local/bin/telegraf_pfifgw.php 136 | ``` 137 | 138 | Test these out before starting the telegraf service by executing them 139 | 140 | `sudo telegraf_pfifgw.php` 141 | 142 | `telegraf_temperature.sh` 143 | 144 | The temperature plugin may not work on every system, if you receive `sysctl: unknown oid 'hw.acpi.thermal'` comment out or remove that line from the plugin. 145 | 146 | After this is done, navigate to Services -> Telegraf -> General -> Enable Telegraf Agent. 147 | 148 | Lastly, check if Telegraf is running 149 | 150 | `sudo service telegraf status` 151 | 152 | ## Configuring Graylog 153 | 154 | ### Add GeoIP to Graylog 155 | 156 | To make the map work on Grafana, you must create a MaxMind account here https://www.maxmind.com/en/geolite2/signup. Then generate a license key by going to Account -> Manage License Keys -> Generate New License Key. Copy this key somewhere because you'll need it again soon. 157 | 158 | You'll need to download the GeoIP database file to your Graylog container. Access your Graylog container's shell from your Docker host like so 159 | 160 | `sudo docker exec -it graylog /bin/bash` 161 | 162 | Then download the database file, replace `YOUR_LICENSE_KEY` with the key you generated above. 163 | 164 | ``` 165 | curl "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_LICENSE_KEY&suffix=tar.gz" -o GeoLite2-Country.tar.gz \ 166 | && tar -xzvf GeoLite2-Country.tar.gz \ 167 | && mv GeoLite2-Country_*/GeoLite2-Country.mmdb /usr/share/graylog/data/data/ 168 | ``` 169 | 170 | ### Configure Additional Settings 171 | 172 | In a browser navigate to http://(ip of docker server):9000 and login. 173 | 174 | For Graylog, it's recommended to create an index set. To do so, navigate to System -> Indices. Create an index set with the name "OPNsense / filterlog" and set the index prefix to `opnsense_filterlog`. 175 | 176 | ![Graylog Index Set](https://www.bsmithio.com/post/opnsense-dashboard/indexset.png) 177 | 178 | Once that's done, download the [content pack](https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/OPNsense-pack.json) and install it on Graylog by navigating to System -> Content Packs -> Upload, choose the pack, Upload, then Install. 179 | 180 | Now, add your index set from earlier to the "OPNsense / filterlog" stream. Navigate to Streams -> More Actions -> Edit Stream -> select your index set and save. 181 | 182 | ![Graylog Stream Index Set](https://www.bsmithio.com/post/opnsense-dashboard/streamindex.png) 183 | 184 | There's one more step we need to do here, navigate to System -> Configurations -> click on Update under Message Processors, and reorder like so: 185 | 186 | ![Graylog Message Processors](https://www.bsmithio.com/post/opnsense-dashboard/processors.png) 187 | 188 | Ensure that all of these are enabled, and click save. 189 | 190 | ### Add Graylog server as syslog target on OPNsense 191 | 192 | Once that is all done, login to your OPNsense router and navigate to System -> Settings -> Logging / targets. Add a new target with the following options: 193 | 194 | ![OPNsense Syslog Target](https://i.nuuls.com/XQATf.png) 195 | 196 | Add a description if you'd like, then click save. 197 | 198 | ## Configuring Grafana 199 | 200 | ### Add InfluxDB and ElasticSearch data sources 201 | 202 | You will need to add the data sources on Grafana. Navigate to http://(ip of docker server):3000, login and click on the cog wheel and Add a Data Source. 203 | 204 | For InfluxDB, make the following configurations 205 | 206 | Query Language: Flux 207 | 208 | URL: http://influxdb:8086 209 | 210 | Organization: Your InfluxDB Organization 211 | 212 | Token: Your Grafana InfluxDB API Token 213 | 214 | Default Bucket: Your opnsense bucket. This will be the bucket that the panel queries will use. 215 | 216 | ![Grafana InfluxDB Configuration](https://www.bsmithio.com/post/opnsense-dashboard/influxdb.png) 217 | 218 | For ElasticSearch, make the following configurations 219 | 220 | URL: http://elasticsearch:9200 221 | 222 | Time field name: timestamp 223 | 224 | Version: 7.10+ 225 | 226 | ![Grafana ElasticSearch Configuration](https://www.bsmithio.com/post/opnsense-dashboard/elasticsearch.png) 227 | 228 | ### Import Dashboard 229 | 230 | To import the dashboard, copy the JSON from [OPNsense-Grafana-Dashboard.json](https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/OPNsense-Grafana-Dashboard.json) and navigate to Dashboards -> Browse -> Import and paste under Import via panel json. 231 | 232 | ### Configure Variables 233 | 234 | Dashboard Settings -> Variables -> Click on a variable to edit 235 | 236 | WAN - $WAN is the variable for our WAN interface panels. It is currently set to igb0 under Custom options. Use a comma-separated list for multiple WAN interfaces. 237 | 238 | LAN - $LAN uses a regex to remove any interfaces you don't want to be grouped as LAN. The filtering happens in the "Regex" field. I use a negative lookahead regex to match the interfaces I want excluded. It should be pretty easy to understand what you need to do here. I have excluded igb0 (WAN),igb2,igb3,ovpnc1, and wg0. 239 | 240 | iface - $iface is the interface variable for the Firewall panels, I have it set to igb0 by default. You can either remove igb0 so you can select all interfaces, or use a comma separated list of interfaces. 241 | 242 | dataSource - dataSource is the variable for our InfluxDB data source. It is the data source that will be used for all panels with InfluxDB queries. You should see a preview of values you can pick from. Under Instance name filter, use the name of the InfluxDB data source you created for OPNsense if you have multiple InfluxDB data sources. 243 | 244 | ESdataSource - ESdataSource is the variable four our Elasticsearch data source. It is the data source that will be used for all panels with Elasticsearch queries. You should see a preview of values you can pick from. Under Instance name filter, use the name of the Elastisearch data source you created for OPNsense if you have multiple Elasticsearch data sources. 245 | 246 | Lastly, I don't recommend setting the time range beyond 24 hours, due to how many data points that will return in Grafana. 247 | 248 | ## Configuration for the Suricata dashboard #Optional 249 | This section assumes you have already configured Suricata. 250 | 251 | ### Add the necessary files 252 | 253 | Add [suricata.conf](./config/suricata/suricata.conf) to /usr/local/etc/telegraf.d 254 | 255 | ``` 256 | sudo curl 'https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/suricata/suricata.conf' -o /usr/local/etc/telegraf.d/suricata.conf 257 | ``` 258 | 259 | Add [custom.yaml](./config/suricata/custom.yaml) to /usr/local/opnsense/service/templates/OPNsense/IDS 260 | 261 | ``` 262 | sudo curl 'https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/config/suricata/custom.yaml' -o /usr/local/opnsense/service/templates/OPNsense/IDS/custom.yaml 263 | ``` 264 | 265 | Create the log file and give telegraf permissions to read it 266 | 267 | ``` 268 | sudo touch /tmp/eve.json 269 | sudo chown :telegraf /tmp/eve.json 270 | sudo chmod 640 /tmp/eve.json 271 | ``` 272 | 273 | ### Restart Suricata and Telegraf 274 | 275 | Restart Suricata from Services -> Intrusion Detection -> Administration 276 | 277 | Uncheck Enabled and click Apply. 278 | 279 | Check Enabled and click Apply. 280 | 281 | Restart telegraf by running 282 | 283 | `sudo service telegraf restart` 284 | 285 | ### Import the Suricata Dashboard 286 | 287 | To import the dashboard, copy the JSON from [OPNsense-Grafana-Dashboard-Suricata.json](https://raw.githubusercontent.com/bsmithio/OPNsense-Dashboard/master/OPNsense-Grafana-Dashboard-Suricata.json) and navigate to Dashboards -> Browse -> Import and paste under Import via panel json. 288 | 289 | ## Troubleshooting 290 | 291 | ### Telegraf Plugins 292 | 293 | - You can run most plugins from a shell/ssh session to verify the output. (the environment vars may be different when telegraf is executing the plugin) 294 | - If you're copying from a windows system, make sure the [CRLF is correct](https://www.cyberciti.biz/faq/howto-unix-linux-convert-dos-newlines-cr-lf-unix-text-format/) 295 | - The below command should display unix line endings (\n or LF) as $ and Windows line endings (\r\n or CRLF) as ^M$. 296 | 297 | `cat -e /usr/local/bin/telegraf_pfifgw.php` 298 | 299 | ### Telegraf Troubleshooting 300 | If you get no good output from running the plugin directly, try the following command before moving to the step below. 301 | 302 | `sudo su -m telegraf -c 'telegraf --test --config /usr/local/etc/telegraf.conf --config-directory /usr/local/etc/telegraf.d'` 303 | 304 | To troubleshoot plugins further, enable Debug Log and disable Quiet Log in the Telegraf GUI then click Save. Run the above command again. 305 | 306 | `sudo su -m telegraf -c 'telegraf --test --config /usr/local/etc/telegraf.conf --config-directory /usr/local/etc/telegraf.d'` 307 | 308 | 309 | ### InfluxDB 310 | When in doubt, run a few queries to see if the data you are looking for is being populated. 311 | I recommend doing this in Grafana's Explore tab. 312 | 313 | ### View measurements 314 | import "influxdata/influxdb/schema" 315 | 316 | schema.measurements(bucket: "opnsense") 317 | 318 | ### View field values 319 | 320 | from(bucket: "opnsense") 321 | |> range(start: -24h) 322 | |> filter(fn: (r) => r["_measurement"] == "system") 323 | |> limit(n:10) 324 | 325 | ### How to drop an InfluxDB v2 measurement 326 | 327 | You must access your InfluxDB instance's shell to do this. 328 | 329 | To do so run 330 | 331 | `sudo docker exec -it influxdb /bin/bash` 332 | 333 | on your docker host. 334 | 335 | Then use the following 336 | 337 | ``` 338 | influx delete --bucket "$YourBucket" --predicate '_measurement="$Example"' -o $organization --start "1970-01-01T00:00:00Z" --stop "2050-12-31T23:59:00Z" --token "$YourAPIToken" 339 | ``` 340 | 341 | ### Learn more about Flux queries 342 | 343 | https://docs.influxdata.com/influxdb/cloud/query-data/flux/query-fields/ 344 | 345 | https://docs.influxdata.com/influxdb/cloud/query-data/flux/explore-schema/ 346 | 347 | ### Suricata Troubleshooting 348 | 349 | If there is no data on the Suricata dashboard, verify if there are any alerts in /tmp/eve.json. 350 | 351 | If there is nothing in /tmp/eve.json, verify that /usr/local/opnsense/service/templates/OPNsense/IDS/custom.yaml and /usr/local/etc/suricata/custom.yaml are identical to the one in this repo. 352 | 353 | If /usr/local/etc/suricata/custom.yaml is not identical, but /usr/local/opnsense/service/templates/OPNsense/IDS/custom.yaml is, you will need to reload Suricata from the GUI. To do so you would uncheck Enable in the Suricata GUI, click Apply, then check Enable, and click Apply again. You will need to wait for Suricata to reload. If you have a lot of rules this can take some time. 354 | 355 | If you've verified and done all the steps above, and still see nothing, you could try using [tmNIDS](https://github.com/3CORESec/testmynids.org) to generate alerts. You will need bash installed on your OPNsense system for this. 356 | 357 | `sudo pkg install bash` 358 | 359 | Once you have bash installed, you can use this one-liner to download and execute tmNIDS. 360 | 361 | ``` 362 | curl https://raw.githubusercontent.com/3CORESec/testmynids.org/master/tmNIDS -o /tmp/tmNIDS && chmod +x /tmp/tmNIDS && bash /tmp/tmNIDS 363 | ``` 364 | 365 | You can then run the tests through the CLI. 366 | ![](https://www.bsmithio.com/post/opnsense-dashboard/tmnids.png) 367 | 368 | ### Map Issues 369 | 370 | If you see no GeoIP data on the map make sure you rearranged the Message Processors in System -> Configurations, and reorder like so: 371 | 372 | ![Graylog Message Processors](https://www.bsmithio.com/post/opnsense-dashboard/processors.png) 373 | 374 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mongodb: 4 | container_name: mongo 5 | image: mongo:6.0.4 6 | volumes: 7 | - mongodb_data:/data/db 8 | restart: "unless-stopped" 9 | environment: 10 | # Change this to your time zone, valid time zones can be found here: https://www.joda.org/joda-time/timezones.html 11 | - TZ=CST6CDT 12 | networks: 13 | - graylog 14 | elasticsearch: 15 | container_name: elasticsearch 16 | image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2 17 | volumes: 18 | - es_data:/usr/share/elasticsearch/data 19 | environment: 20 | # Change this to your time zone, valid time zones can be found here: https://www.joda.org/joda-time/timezones.html 21 | - TZ=CST6CDT 22 | - http.host=0.0.0.0 23 | - transport.host=localhost 24 | - network.host=0.0.0.0 25 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 26 | restart: "unless-stopped" 27 | networks: 28 | - graylog 29 | graylog: 30 | container_name: graylog 31 | image: graylog/graylog:5.0.2 32 | volumes: 33 | - graylog_data:/usr/share/graylog/data 34 | environment: 35 | # Change these to your time zone, valid time zones can be found here: https://www.joda.org/joda-time/timezones.html 36 | - TZ=CST6CDT 37 | - ROOT_TIMEZONE=CST6CDT 38 | - GRAYLOG_TIMEZONE=CST6CDT 39 | # CHANGE ME (must be at least 16 characters)! This is not your password, this is meant for salting the password below. 40 | - GRAYLOG_PASSWORD_SECRET=ZDcwMzQ3NTE4ZTIwM 41 | # Username is "admin" 42 | # Password is "admin", change this to your own hashed password. 'echo -n "password" | sha256sum' 43 | - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 44 | - GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/ 45 | networks: 46 | - graylog 47 | depends_on: 48 | - mongodb 49 | - elasticsearch 50 | ports: 51 | # Graylog web interface and REST API 52 | - 9000:9000 53 | # Syslog UDP 54 | - 1514:1514/udp 55 | # Syslog TCP Optional 56 | #- 1514:1514 57 | restart: "unless-stopped" 58 | influxdb: 59 | container_name: influxdb 60 | image: influxdb:2.6.1 61 | ports: 62 | - '8086:8086' 63 | volumes: 64 | - influxdb2_data:/var/lib/influxdb2 65 | environment: 66 | # Change this to your time zone, valid time zones can be found here: https://www.joda.org/joda-time/timezones.html 67 | - TZ=CST6CDT 68 | restart: "unless-stopped" 69 | networks: 70 | - graylog 71 | grafana: 72 | container_name: grafana 73 | image: grafana/grafana:9.2.10 74 | ports: 75 | - '3000:3000' 76 | volumes: 77 | - grafana_data:/var/lib/grafana 78 | depends_on: 79 | - influxdb 80 | environment: 81 | # Change this to your time zone, valid time zones can be found here: https://www.joda.org/joda-time/timezones.html 82 | - TZ=CST6CDT 83 | # Change these 84 | - GF_SECURITY_ADMIN_USER=opnsense 85 | - GF_SECURITY_ADMIN_PASSWORD=opnsense 86 | - GF_INSTALL_PLUGINS=grafana-worldmap-panel 87 | restart: "unless-stopped" 88 | networks: 89 | - graylog 90 | networks: 91 | graylog: 92 | driver: bridge 93 | volumes: 94 | grafana_data: 95 | influxdb2_data: 96 | graylog_data: 97 | es_data: 98 | mongodb_data: 99 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # Installing the Plugins 2 | Place these plugins in "/usr/local/bin". The easiest way of doing this would be to SSH into your router, navigate to "/usr/local/bin" and use curl to download the files, like so: 3 | 4 | 5 | `curl https://raw.githubusercontent.com/Bsmith101/OPNsense-Dashboard/master/plugins/telegraf_pfifgw.php -o telegraf_pfifgw.php` 6 | 7 | `curl https://raw.githubusercontent.com/Bsmith101/OPNsense-Dashboard/master/plugins/telegraf_temperature.sh -o telegraf_temperature.sh` 8 | 9 | Make sure to set the permissions to "755" 10 | 11 | # telegraf_pfifgw.php 12 | 13 | This single script collects information for Interfaces and gateways. 14 | 15 | **Interfaces:** 16 | * Interface name 17 | * IP4 address 18 | * IP4 subnet 19 | * IP6 address 20 | * IP6 subnet 21 | * MAC address 22 | * Friendly name 23 | * Status (Online/Offline/Etc.) 24 | 25 | **Gateways:** 26 | * Interface name 27 | * Monitor IP 28 | * Source IP 29 | * GW Description 30 | * Delay 31 | * Stddev 32 | * Loss (%) 33 | * Status (Online/Offline/etc.) 34 | 35 | 36 | # telegraf_temperature.sh 37 | 38 | Provides temperature sensor information. 39 | -------------------------------------------------------------------------------- /plugins/telegraf_pfifgw.php: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/php-cgi -f 2 | $friendly) { 13 | $ifsinfo = get_interfaces_info(); 14 | $ifinfo = $ifsinfo[$ifname]; 15 | $ifstatus = $ifinfo['status']; 16 | $realif = get_real_interface($ifname); 17 | $ip4addr = get_interface_ip($ifname); 18 | $ip4subnet = interfaces_primary_address($realif, $ifconfig_details)[1]; 19 | $ip6addr = get_interface_ipv6($ifname); 20 | $ip6subnet = interfaces_primary_address6($realif, $ifconfig_details)[1]; 21 | $mac = get_interface_mac($realif); 22 | 23 | if (!isset($ifinfo)) { 24 | $ifinfo = "Unavailable"; 25 | } 26 | if (strtolower($ifstatus) == "up") { 27 | $ifstatus = 1; 28 | } 29 | if (strtolower($ifstatus) == "active") { 30 | $ifstatus = 1; 31 | } 32 | if (strtolower($ifstatus) == "no carrier") { 33 | $ifstatus = 0; 34 | } 35 | if (strtolower($ifstatus) == "down") { 36 | $ifstatus = 0; 37 | } 38 | if (!isset($ifstatus)) { 39 | $ifstatus = 2; 40 | } 41 | if (!isset($ip4addr)) { 42 | $ip4addr = "Unassigned"; 43 | } 44 | if (!isset($ip4subnet)) { 45 | $ip4subnet = "Unassigned"; 46 | } 47 | if (!isset($ip6addr)) { 48 | $ip6addr = "Unassigned"; 49 | } 50 | if (!isset($ip6subnet)) { 51 | $ip6subnet = "Unassigned"; 52 | } 53 | if (!isset($realif)) { 54 | $realif = "Unassigned"; 55 | } 56 | if (!isset($mac)) { 57 | $mac = "Unavailable"; 58 | } 59 | 60 | printf( 61 | "interface,host=%s,name=%s,ip4_address=%s,ip4_subnet=%s,ip6_address=%s,ip6_subnet=%s,mac_address=%s,friendlyname=%s,source=%s status=%s\n", 62 | $host, 63 | $realif, 64 | $ip4addr, 65 | $ip4subnet, 66 | $ip6addr, 67 | $ip6subnet, 68 | $mac, 69 | $friendly, 70 | $source, 71 | $ifstatus, 72 | ); 73 | } 74 | 75 | $gw_array = (new \OPNsense\Routing\Gateways(legacy_interfaces_details()))->gatewaysIndexedByName(); 76 | //$gw_statuses is not guarranteed to contain the same number of gateways as $gw_array 77 | $gw_statuses = return_gateways_status(); 78 | 79 | $debug = false; 80 | 81 | if ($debug) { 82 | print_r($gw_array); 83 | print_r($gw_statuses); 84 | } 85 | 86 | foreach ($gw_array as $gw => $gateway) { 87 | 88 | //take the name from the $a_gateways list 89 | $name = $gateway["name"]; 90 | 91 | $delay = $gw_statuses[$gw]["delay"]; 92 | $stddev = $gw_statuses[$gw]["stddev"]; 93 | $status = $gw_statuses[$gw]["status"]; 94 | $loss = $gw_statuses[$gw]["loss"]; 95 | 96 | $interface = $gateway["interface"]; 97 | $gwdescr = $gateway["descr"]; 98 | $monitor = $gateway["monitor"]; 99 | $source = $gateway["gateway"]; 100 | 101 | if (!isset($monitor)) { 102 | $monitor = "Unavailable"; 103 | } 104 | if (!isset($source)) { 105 | $source = "Unavailable"; 106 | } 107 | if (!isset($delay)) { 108 | $delay = "0"; 109 | } 110 | if (!isset($stddev)) { 111 | $stddev = "0"; 112 | } 113 | if (!isset($loss)) { 114 | $loss = "0"; 115 | } 116 | if (strtolower($status) == "none") { 117 | $status = 1; 118 | } 119 | if (strtolower($status) == "force_down") { 120 | $status = 0; 121 | } 122 | if (strtolower($status) == "down") { 123 | $status = 0; 124 | } 125 | if (!isset($status)) { 126 | $status = "Unavailable"; 127 | } 128 | if (!isset($interface)) { 129 | $interface = "Unassigned"; 130 | } 131 | if (!isset($gwdescr)) { 132 | $gwdescr = "Unassigned"; 133 | } 134 | if (isset($gateway['monitor_disable'])) { 135 | $monitor = "Unmonitored"; 136 | } 137 | 138 | printf( 139 | "gateways,host=%s,interface=%s,gateway_name=%s monitor=\"%s\",source=\"%s\",gwdescr=\"%s\",delay=%s,stddev=%s,loss=%s,status=\"%s\"\n", 140 | $host, 141 | $interface, 142 | $name, //name is required as it is possible to have 2 gateways on 1 interface. i.e. WAN_DHCP and WAN_DHCP6 143 | $monitor, 144 | $source, 145 | $gwdescr, 146 | floatval($delay), 147 | floatval($stddev), 148 | floatval($loss), 149 | $status 150 | ); 151 | }; 152 | ?> 153 | -------------------------------------------------------------------------------- /plugins/telegraf_temperature.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/sh 3 | HOSTNAME=$(hostname) 4 | 5 | sysctl dev.cpu | fgrep temperature | tr -d '[:blank:]' | awk -v HOST="$HOSTNAME" -F '[.:]' '{print "temperature,sensor="$2$3",host="HOST" degrees=" $5"."substr($6, 1, length($6)-1)}' 6 | sysctl hw.acpi.thermal | fgrep temperature | tr -d '[:blank:]' | awk -v HOST="$HOSTNAME" -F '[.:]' '{print "temperature,sensor="$4",host="HOST" degrees="$6"." substr($7, 1, length($7)-1)}' 7 | --------------------------------------------------------------------------------