├── README.md ├── analyze_influx.php ├── LICENSE ├── grafana_dashboard.json └── radius_functions.php /README.md: -------------------------------------------------------------------------------- 1 | # InfluxDB RADIUS Analyzer 2 | 3 | ![Example grafana log](https://www.pictshare.net/800/22ca68ad0e.jpg) 4 | 5 | Compatible with all versions of InfluxDB since it uses UDP and the line protocol. 6 | 7 | ## Updating 8 | You can update by copying the whole script but make sure to check the first lines of analyze_influx.php for (new) settings since the settings will be overwritten after each update because for now I'm too lazy to proper implement the config in an external file, sorry. 9 | 10 | How to use: https://blog.haschek.at/2016-how-to-visualize-radius-connections -------------------------------------------------------------------------------- /analyze_influx.php: -------------------------------------------------------------------------------- 1 | 30m", 38 | "isNew": true, 39 | "legend": { 40 | "alignAsTable": false, 41 | "avg": false, 42 | "current": false, 43 | "max": false, 44 | "min": false, 45 | "show": true, 46 | "total": false, 47 | "values": false 48 | }, 49 | "lines": true, 50 | "linewidth": 2, 51 | "links": [], 52 | "nullPointMode": "connected", 53 | "percentage": false, 54 | "pointradius": 5, 55 | "points": false, 56 | "renderer": "flot", 57 | "seriesOverrides": [], 58 | "span": 6, 59 | "stack": false, 60 | "steppedLine": true, 61 | "targets": [ 62 | { 63 | "alias": "[[tag_ap]]", 64 | "dsType": "influxdb", 65 | "groupBy": [ 66 | { 67 | "params": [ 68 | "$interval" 69 | ], 70 | "type": "time" 71 | }, 72 | { 73 | "params": [ 74 | "ap" 75 | ], 76 | "type": "tag" 77 | }, 78 | { 79 | "params": [ 80 | "null" 81 | ], 82 | "type": "fill" 83 | } 84 | ], 85 | "measurement": "radius", 86 | "query": "SELECT count(\"value\") FROM \"radius\" WHERE \"ap\" <> '0' AND $timeFilter GROUP BY time($interval), \"ap\" fill(null)", 87 | "rawQuery": false, 88 | "refId": "A", 89 | "resultFormat": "time_series", 90 | "select": [ 91 | [ 92 | { 93 | "params": [ 94 | "value" 95 | ], 96 | "type": "field" 97 | }, 98 | { 99 | "params": [], 100 | "type": "count" 101 | } 102 | ] 103 | ], 104 | "tags": [ 105 | { 106 | "key": "ap", 107 | "operator": "<>", 108 | "value": "0" 109 | } 110 | ] 111 | } 112 | ], 113 | "timeFrom": null, 114 | "timeShift": null, 115 | "title": "Requests by AP", 116 | "tooltip": { 117 | "shared": true, 118 | "value_type": "cumulative" 119 | }, 120 | "type": "graph", 121 | "x-axis": true, 122 | "y-axis": true, 123 | "y_formats": [ 124 | "ops", 125 | "short" 126 | ] 127 | }, 128 | { 129 | "aliasColors": {}, 130 | "bars": false, 131 | "datasource": "radius", 132 | "editable": true, 133 | "error": false, 134 | "fill": 1, 135 | "grid": { 136 | "leftLogBase": 1, 137 | "leftMax": null, 138 | "leftMin": null, 139 | "rightLogBase": 1, 140 | "rightMax": null, 141 | "rightMin": null, 142 | "threshold1": null, 143 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 144 | "threshold2": null, 145 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 146 | }, 147 | "id": 2, 148 | "interval": ">5m", 149 | "isNew": true, 150 | "legend": { 151 | "avg": false, 152 | "current": false, 153 | "hideEmpty": false, 154 | "max": false, 155 | "min": false, 156 | "show": true, 157 | "total": false, 158 | "values": false 159 | }, 160 | "lines": true, 161 | "linewidth": 2, 162 | "links": [], 163 | "nullPointMode": "connected", 164 | "percentage": false, 165 | "pointradius": 5, 166 | "points": false, 167 | "renderer": "flot", 168 | "seriesOverrides": [ 169 | { 170 | "alias": "Abgelehnte Logins", 171 | "color": "#BF1B00" 172 | } 173 | ], 174 | "span": 6, 175 | "stack": false, 176 | "steppedLine": false, 177 | "targets": [ 178 | { 179 | "alias": "Successful logins", 180 | "dsType": "influxdb", 181 | "groupBy": [ 182 | { 183 | "params": [ 184 | "$interval" 185 | ], 186 | "type": "time" 187 | }, 188 | { 189 | "params": [ 190 | "null" 191 | ], 192 | "type": "fill" 193 | } 194 | ], 195 | "measurement": "radius", 196 | "query": "SELECT count(\"value\") FROM \"radius\" WHERE \"type\" = 'accept' AND $timeFilter GROUP BY time($interval) fill(null)", 197 | "rawQuery": false, 198 | "refId": "A", 199 | "resultFormat": "time_series", 200 | "select": [ 201 | [ 202 | { 203 | "params": [ 204 | "value" 205 | ], 206 | "type": "field" 207 | }, 208 | { 209 | "params": [], 210 | "type": "count" 211 | } 212 | ] 213 | ], 214 | "tags": [ 215 | { 216 | "key": "type", 217 | "operator": "=", 218 | "value": "accept" 219 | } 220 | ] 221 | }, 222 | { 223 | "alias": "Rejected logins", 224 | "dsType": "influxdb", 225 | "groupBy": [ 226 | { 227 | "params": [ 228 | "$interval" 229 | ], 230 | "type": "time" 231 | }, 232 | { 233 | "params": [ 234 | "null" 235 | ], 236 | "type": "fill" 237 | } 238 | ], 239 | "measurement": "radius", 240 | "query": "SELECT count(\"value\") FROM \"radius\" WHERE \"type\" = 'rejected' AND $timeFilter GROUP BY time($interval) fill(null)", 241 | "rawQuery": false, 242 | "refId": "B", 243 | "resultFormat": "time_series", 244 | "select": [ 245 | [ 246 | { 247 | "params": [ 248 | "value" 249 | ], 250 | "type": "field" 251 | }, 252 | { 253 | "params": [], 254 | "type": "count" 255 | } 256 | ] 257 | ], 258 | "tags": [ 259 | { 260 | "key": "type", 261 | "operator": "=", 262 | "value": "rejected" 263 | } 264 | ] 265 | } 266 | ], 267 | "timeFrom": null, 268 | "timeShift": null, 269 | "title": "All requests", 270 | "tooltip": { 271 | "shared": true, 272 | "value_type": "cumulative" 273 | }, 274 | "type": "graph", 275 | "x-axis": true, 276 | "y-axis": true, 277 | "y_formats": [ 278 | "ops", 279 | "short" 280 | ] 281 | } 282 | ], 283 | "title": "Row" 284 | }, 285 | { 286 | "collapse": false, 287 | "editable": true, 288 | "height": 118, 289 | "panels": [ 290 | { 291 | "cacheTimeout": null, 292 | "colorBackground": false, 293 | "colorValue": false, 294 | "colors": [ 295 | "rgba(245, 54, 54, 0.9)", 296 | "rgba(237, 129, 40, 0.89)", 297 | "rgba(50, 172, 45, 0.97)" 298 | ], 299 | "datasource": "radius", 300 | "decimals": 0, 301 | "editable": true, 302 | "error": false, 303 | "format": "none", 304 | "id": 3, 305 | "interval": null, 306 | "isNew": true, 307 | "links": [], 308 | "maxDataPoints": 100, 309 | "nullPointMode": "connected", 310 | "nullText": null, 311 | "postfix": "", 312 | "postfixFontSize": "50%", 313 | "prefix": "", 314 | "prefixFontSize": "50%", 315 | "span": 4.14169921875, 316 | "sparkline": { 317 | "fillColor": "rgba(31, 118, 189, 0.18)", 318 | "full": false, 319 | "lineColor": "rgb(31, 120, 193)", 320 | "show": true 321 | }, 322 | "targets": [ 323 | { 324 | "dsType": "influxdb", 325 | "groupBy": [ 326 | { 327 | "params": [ 328 | "$interval" 329 | ], 330 | "type": "time" 331 | }, 332 | { 333 | "params": [ 334 | "null" 335 | ], 336 | "type": "fill" 337 | } 338 | ], 339 | "measurement": "radius", 340 | "query": "SELECT count(distinct(\"value\")) FROM \"radius\" WHERE $timeFilter GROUP BY time($interval) fill(null)", 341 | "rawQuery": true, 342 | "refId": "A", 343 | "resultFormat": "time_series", 344 | "select": [ 345 | [ 346 | { 347 | "params": [ 348 | "value" 349 | ], 350 | "type": "field" 351 | }, 352 | { 353 | "params": [], 354 | "type": "distinct" 355 | } 356 | ] 357 | ], 358 | "tags": [] 359 | } 360 | ], 361 | "thresholds": "", 362 | "title": "Unique users in timespan", 363 | "type": "singlestat", 364 | "valueFontSize": "80%", 365 | "valueMaps": [], 366 | "valueName": "current" 367 | }, 368 | { 369 | "cacheTimeout": null, 370 | "colorBackground": false, 371 | "colorValue": false, 372 | "colors": [ 373 | "rgba(245, 54, 54, 0.9)", 374 | "rgba(237, 129, 40, 0.89)", 375 | "rgba(50, 172, 45, 0.97)" 376 | ], 377 | "datasource": "radius", 378 | "decimals": 1, 379 | "editable": true, 380 | "error": false, 381 | "format": "none", 382 | "id": 4, 383 | "interval": null, 384 | "isNew": true, 385 | "links": [], 386 | "maxDataPoints": 100, 387 | "nullPointMode": "connected", 388 | "nullText": null, 389 | "postfix": "", 390 | "postfixFontSize": "50%", 391 | "prefix": "", 392 | "prefixFontSize": "50%", 393 | "span": 4, 394 | "sparkline": { 395 | "fillColor": "rgba(31, 118, 189, 0.18)", 396 | "full": false, 397 | "lineColor": "rgb(31, 120, 193)", 398 | "show": true 399 | }, 400 | "targets": [ 401 | { 402 | "dsType": "influxdb", 403 | "groupBy": [ 404 | { 405 | "params": [ 406 | "$interval" 407 | ], 408 | "type": "time" 409 | }, 410 | { 411 | "params": [ 412 | "null" 413 | ], 414 | "type": "fill" 415 | } 416 | ], 417 | "measurement": "radius", 418 | "query": "SELECT count(distinct(\"value\")) FROM \"radius\" WHERE $timeFilter GROUP BY time($interval) fill(null)", 419 | "rawQuery": true, 420 | "refId": "A", 421 | "resultFormat": "time_series", 422 | "select": [ 423 | [ 424 | { 425 | "params": [ 426 | "value" 427 | ], 428 | "type": "field" 429 | }, 430 | { 431 | "params": [], 432 | "type": "distinct" 433 | } 434 | ] 435 | ], 436 | "tags": [] 437 | } 438 | ], 439 | "thresholds": "", 440 | "title": "Users on average", 441 | "type": "singlestat", 442 | "valueFontSize": "80%", 443 | "valueMaps": [], 444 | "valueName": "avg" 445 | }, 446 | { 447 | "cacheTimeout": null, 448 | "colorBackground": false, 449 | "colorValue": false, 450 | "colors": [ 451 | "rgba(245, 54, 54, 0.9)", 452 | "rgba(237, 129, 40, 0.89)", 453 | "rgba(50, 172, 45, 0.97)" 454 | ], 455 | "datasource": "radius", 456 | "decimals": 0, 457 | "editable": true, 458 | "error": false, 459 | "format": "none", 460 | "id": 6, 461 | "interval": null, 462 | "isNew": true, 463 | "links": [], 464 | "maxDataPoints": 100, 465 | "nullPointMode": "connected", 466 | "nullText": null, 467 | "postfix": "", 468 | "postfixFontSize": "50%", 469 | "prefix": "", 470 | "prefixFontSize": "50%", 471 | "span": 3.8583007812499996, 472 | "sparkline": { 473 | "fillColor": "rgba(189, 64, 31, 0.18)", 474 | "full": false, 475 | "lineColor": "rgb(193, 78, 31)", 476 | "show": true 477 | }, 478 | "targets": [ 479 | { 480 | "dsType": "influxdb", 481 | "groupBy": [ 482 | { 483 | "params": [ 484 | "$interval" 485 | ], 486 | "type": "time" 487 | }, 488 | { 489 | "params": [ 490 | "null" 491 | ], 492 | "type": "fill" 493 | } 494 | ], 495 | "measurement": "radius", 496 | "query": "SELECT count(\"value\") FROM \"radius\" WHERE \"type\" = 'rejected' AND $timeFilter GROUP BY time($interval) fill(null)", 497 | "rawQuery": false, 498 | "refId": "B", 499 | "resultFormat": "time_series", 500 | "select": [ 501 | [ 502 | { 503 | "params": [ 504 | "value" 505 | ], 506 | "type": "field" 507 | }, 508 | { 509 | "params": [], 510 | "type": "count" 511 | } 512 | ] 513 | ], 514 | "tags": [ 515 | { 516 | "key": "type", 517 | "operator": "=", 518 | "value": "rejected" 519 | } 520 | ] 521 | } 522 | ], 523 | "thresholds": "", 524 | "title": "Rejected logins", 525 | "type": "singlestat", 526 | "valueFontSize": "80%", 527 | "valueMaps": [], 528 | "valueName": "max" 529 | } 530 | ], 531 | "title": "New row" 532 | }, 533 | { 534 | "collapse": false, 535 | "editable": true, 536 | "height": 393, 537 | "panels": [ 538 | { 539 | "columns": [], 540 | "datasource": "radius", 541 | "editable": true, 542 | "error": false, 543 | "fontSize": "100%", 544 | "id": 5, 545 | "isNew": true, 546 | "links": [], 547 | "pageSize": null, 548 | "scroll": true, 549 | "showHeader": true, 550 | "sort": { 551 | "col": 0, 552 | "desc": true 553 | }, 554 | "span": 6.0375, 555 | "styles": [ 556 | { 557 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 558 | "pattern": "Time", 559 | "type": "date" 560 | }, 561 | { 562 | "colorMode": null, 563 | "colors": [ 564 | "rgba(245, 54, 54, 0.9)", 565 | "rgba(237, 129, 40, 0.89)", 566 | "rgba(50, 172, 45, 0.97)" 567 | ], 568 | "decimals": 2, 569 | "pattern": "/.*/", 570 | "thresholds": [], 571 | "type": "string", 572 | "unit": "short" 573 | } 574 | ], 575 | "targets": [ 576 | { 577 | "dsType": "influxdb", 578 | "groupBy": [ 579 | { 580 | "params": [ 581 | "$interval" 582 | ], 583 | "type": "time" 584 | }, 585 | { 586 | "params": [ 587 | "null" 588 | ], 589 | "type": "fill" 590 | } 591 | ], 592 | "measurement": "radius", 593 | "query": "SELECT \"time\",\"value\" as Benutzer,\"ap\" FROM \"radius\" WHERE \"type\"='accept' AND $timeFilter", 594 | "rawQuery": true, 595 | "refId": "A", 596 | "resultFormat": "table", 597 | "select": [ 598 | [ 599 | { 600 | "params": [ 601 | "value" 602 | ], 603 | "type": "field" 604 | } 605 | ] 606 | ], 607 | "tags": [] 608 | } 609 | ], 610 | "title": "Last successful logins", 611 | "transform": "table", 612 | "type": "table" 613 | }, 614 | { 615 | "columns": [], 616 | "datasource": "radius", 617 | "editable": true, 618 | "error": false, 619 | "fontSize": "100%", 620 | "id": 7, 621 | "isNew": true, 622 | "links": [], 623 | "pageSize": null, 624 | "scroll": true, 625 | "showHeader": true, 626 | "sort": { 627 | "col": 0, 628 | "desc": true 629 | }, 630 | "span": 5.9625, 631 | "styles": [ 632 | { 633 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 634 | "pattern": "Time", 635 | "type": "date" 636 | }, 637 | { 638 | "colorMode": null, 639 | "colors": [ 640 | "rgba(245, 54, 54, 0.9)", 641 | "rgba(237, 129, 40, 0.89)", 642 | "rgba(50, 172, 45, 0.97)" 643 | ], 644 | "decimals": 2, 645 | "pattern": "/.*/", 646 | "thresholds": [], 647 | "type": "string", 648 | "unit": "short" 649 | } 650 | ], 651 | "targets": [ 652 | { 653 | "dsType": "influxdb", 654 | "groupBy": [ 655 | { 656 | "params": [ 657 | "$interval" 658 | ], 659 | "type": "time" 660 | }, 661 | { 662 | "params": [ 663 | "null" 664 | ], 665 | "type": "fill" 666 | } 667 | ], 668 | "measurement": "radius", 669 | "query": "SELECT special_val as Ablehnungsgrund,value as Benutzer FROM \"radius\" WHERE \"type\" = 'rejected' AND special_val != '' AND $timeFilter", 670 | "rawQuery": true, 671 | "refId": "A", 672 | "resultFormat": "table", 673 | "select": [ 674 | [ 675 | { 676 | "params": [ 677 | "value" 678 | ], 679 | "type": "field" 680 | } 681 | ] 682 | ], 683 | "tags": [] 684 | } 685 | ], 686 | "title": "Last rejects", 687 | "transform": "table", 688 | "type": "table" 689 | } 690 | ], 691 | "title": "New row" 692 | } 693 | ], 694 | "time": { 695 | "from": "now-24h", 696 | "to": "now" 697 | }, 698 | "timepicker": { 699 | "now": true, 700 | "refresh_intervals": [ 701 | "5s", 702 | "10s", 703 | "30s", 704 | "1m", 705 | "5m", 706 | "15m", 707 | "30m", 708 | "1h", 709 | "2h", 710 | "1d" 711 | ], 712 | "time_options": [ 713 | "5m", 714 | "15m", 715 | "1h", 716 | "6h", 717 | "12h", 718 | "24h", 719 | "2d", 720 | "7d", 721 | "30d" 722 | ] 723 | }, 724 | "templating": { 725 | "list": [] 726 | }, 727 | "annotations": { 728 | "list": [] 729 | }, 730 | "refresh": "30s", 731 | "schemaVersion": 8, 732 | "version": 44, 733 | "links": [] 734 | } -------------------------------------------------------------------------------- /radius_functions.php: -------------------------------------------------------------------------------- 1 |