diff options
author | Minteck <nekostarfan@gmail.com> | 2021-08-08 18:27:46 +0200 |
---|---|---|
committer | Minteck <nekostarfan@gmail.com> | 2021-08-08 18:27:46 +0200 |
commit | a20dff82a7e2602738f847fa4f1428af3235aafc (patch) | |
tree | e607db59fd59561c055a1b68b29d1cf3c6c99d4e /admin/panes/audit.php | |
parent | c69d44149f544cc80fbe32c26dc4c34266d97bf6 (diff) | |
download | main-a20dff82a7e2602738f847fa4f1428af3235aafc.tar.gz main-a20dff82a7e2602738f847fa4f1428af3235aafc.tar.bz2 main-a20dff82a7e2602738f847fa4f1428af3235aafc.zip |
Updating... the update... that updates
Diffstat (limited to 'admin/panes/audit.php')
-rw-r--r-- | admin/panes/audit.php | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/admin/panes/audit.php b/admin/panes/audit.php new file mode 100644 index 0000000..c2a8609 --- /dev/null +++ b/admin/panes/audit.php @@ -0,0 +1,226 @@ +<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/header.php";/** @var array $_DATA */ ?>
+
+<style>
+ ::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ ::-webkit-scrollbar-track {
+ border-radius: 9999px;
+ background: transparent;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ border-radius: 9999px;
+ background-color: rgba(136, 136, 136, 0.5);
+ transition: background 200ms;
+ }
+
+ ::-webkit-scrollbar-thumb:hover {
+ background-color: rgba(85, 85, 85, 0.75);
+ }
+
+ ::-webkit-scrollbar-thumb:active {
+ background-color: #222;
+ }
+
+ .list-group-item {
+ background: #34373c;
+ }
+
+ table, table * {
+ color: white !important;
+ border-color: #292b2f !important;
+ }
+
+ th {
+ border-top: 0 !important;
+ }
+
+ table a {
+ color: #007bff !important;
+ }
+
+ td.users {
+ width: 20vw;
+ }
+
+ .addr-location {
+ width: 20vw;
+ }
+</style>
+
+<div class="container" style="color:white;padding-top:15vh;padding-bottom:15vh;">
+ <h2 style="text-align:center;">Security Audit</h2>
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th>IP address</th>
+ <th>Connections</th>
+ <th>Username(s)</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody><?php
+
+ $ips = [];
+ $data = "";
+ $dir = scandir("/var/log");
+
+ $dir = array_reverse($dir);
+
+ foreach ($dir as $file) {
+ if ($file !== "." && $file !== "..") {
+ if (substr($file, 0, 5) === "auth.") {
+ if (substr($file, -3) === ".gz") {
+ exec("gzip --decompress /var/log/" . $file);
+ $raw = file_get_contents("/var/log/" . substr($file, 0, -3));
+ } else {
+ $raw = file_get_contents("/var/log/" . $file);
+ }
+
+ $data .= "\n" . $raw;
+ }
+ }
+ }
+
+ $lines = explode("\n", strip_tags($data));
+ $lines = array_reverse($lines);
+
+ foreach ($lines as $line) {
+ if (trim($line) !== "" && strpos($line, "sshd") !== false && strpos($line, "error: kex_exchange_identification: Connection closed by remote host") === false && (strpos($line, "]: Connection closed by invalid user ") !== false || strpos($line, "]: Unable to negotiate with ") !== false || strpos($line, "]: Accepted publickey for ") !== false)) {
+ $data = [];
+
+ $parts = explode(": ", $line);
+
+ $data["date"] = $parts[0];
+ array_shift($parts);
+ $data["message"] = implode(": ", $parts);
+
+
+ if (substr($data["message"], 0, 23) === "Accepted publickey for ") { // Successful connection
+ $data["status"] = "ok";
+ $data["ip"] = explode(" ", $data["message"])[5];
+ $data["user"] = explode(" ", $data["message"])[3];
+ }
+
+ if (substr($data["message"], 0, 25) === "Unable to negotiate with ") { // Errored connection
+ $data["status"] = "error";
+ $data["ip"] = explode(" ", $data["message"])[4];
+ $data["user"] = null;
+ }
+
+ if (substr($data["message"], 0, 34) === "Connection closed by invalid user ") { // Invalid connection
+ $data["status"] = "invalid";
+ $data["ip"] = explode(" ", $data["message"])[count(explode(" ", $data["message"])) - 4];
+ $data["user"] = explode(" ", $data["message"])[5];
+ }
+
+ if (!isset($ips[$data["ip"]])) {
+ $ips[$data["ip"]] = [];
+ }
+ if (!isset($ips[$data["ip"]]["connections"])) {
+ $ips[$data["ip"]]["connections"] = [];
+ }
+ $ips[$data["ip"]]["connections"][] = $data;
+ }
+ }
+
+ $index = 1;
+ foreach ($ips as $ip => $info) {
+ if ($ip !== "port") {
+ echo("<tr>
+ <td class='addr-location'><code>" . $ip . "</code><br><span id='iplocation-" . $ip . "'><span class='text-muted'>Please wait...</span></span>");?>
+ <!--suppress JSUnresolvedVariable -->
+ <script>
+
+ setTimeout(() => {
+ document.getElementById("iplocation-<?= $ip ?>").innerHTML = $.ajax({
+ type: "GET",
+ url: "/admin/api/getIpLocation.php?_=<?= $ip ?>",
+ async: false
+ }).responseText;
+ }, <?= $index ?> * 1000);
+
+ </script>
+ <?php
+ if ($ip === $_SERVER['REMOTE_ADDR']) {
+ echo(" <span class='badge text-primary border-primary' style='border:1px solid;vertical-align: middle;'>You</span>");
+ }
+ echo("</td>
+ <td>");
+
+ $success = 0;
+ $invalid = 0;
+ $failed = 0;
+
+ foreach ($info["connections"] as $connection) {
+ if ($connection["status"] === "invalid") {
+ $invalid++;
+ }
+ if ($connection["status"] === "error") {
+ $failed++;
+ }
+ if ($connection["status"] === "ok") {
+ $success++;
+ }
+ }
+ if (count($info["connections"]) === 0) {
+ echo("<span class='text-muted'>Never connected</span>");
+ } else {
+ echo($success . " succeeded, " . $failed . " failed, " . $invalid . " invalid");
+ }
+
+ echo("<br>Last: ");
+
+ if ($info["connections"][0]["status"] === "ok") {
+ echo("<span class='badge text-success border-success' style='border:1px solid;vertical-align: middle;'>Succeeded</span>");
+ }
+
+ if ($info["connections"][0]["status"] === "error") {
+ echo("<span class='badge text-warning border-warning' style='border:1px solid;vertical-align: middle;'>Failed</span>");
+ }
+
+ if ($info["connections"][0]["status"] === "invalid") {
+ echo("<span class='badge text-danger border-danger' style='border:1px solid;vertical-align: middle;'>Invalid</span>");
+ }
+
+ echo("</td>
+ <td class='users'><details><summary>Show full list</summary><ul class='list-group'>");
+
+ $uniqueUsers = [];
+ $connectionsWithUsers = 0;
+
+ foreach ($info["connections"] as $connection) {
+ if (!in_array($connection["user"], $uniqueUsers) && $connection["user"] !== null) {
+ if (isset($uniqueUsers[$connection["user"]])) {
+ $uniqueUsers[$connection["user"]]++;
+ $connectionsWithUsers++;
+ } else {
+ $uniqueUsers[$connection["user"]] = 1;
+ $connectionsWithUsers++;
+ }
+ }
+ }
+
+ foreach ($uniqueUsers as $user => $occurrences) {
+ echo("<li class='list-group-item'><code>" . $user . "</code> <span style='float:right;'>(" . $occurrences . "×, " . round(($occurrences/$connectionsWithUsers)*100, 2) . "%)</span></li>");
+ }
+
+ if (count($uniqueUsers) === 0) {
+ echo("<li class='list-group-item text-muted'>Username was never sent to server</li>");
+ }
+
+ echo("</ul></details></td></td>
+ <td><a href='#'>Details</a> · <a href='https://cleantalk.org/blacklists/report-ip' target='_blank'>Report</a></td>
+ </tr>");
+
+ $index++;
+ }
+ }
+
+ ?></tbody>
+ </table>
+</div>
+
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/footer.php"; ?>
\ No newline at end of file |