From 73af9b52cc66d90caf41bdd4c00ebcebe874c052 Mon Sep 17 00:00:00 2001 From: DAProgs Date: Mon, 16 Mar 2026 03:26:22 -0400 Subject: [PATCH] added pull.php --- pull.php | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 pull.php diff --git a/pull.php b/pull.php new file mode 100644 index 0000000..9e97650 --- /dev/null +++ b/pull.php @@ -0,0 +1,120 @@ + last_pulled timestamp. +// Each run logs itself in the info table using the current timestamp as list value. +// Safe to run repeatedly (e.g. via cron) — uses ON DUPLICATE KEY UPDATE. + +date_default_timezone_set("America/Montreal"); +include('conn.php'); +include('functions.php'); + +$api_url = "https://www.home.daprogs.net/portspoof/api/frequent_ips.php"; +$api_token = "a2b6ac44bcbf33764c066892f739e546a319e0d68356d08579c2b7e32218f240"; + +$pull_type = 3; // blacklist type ID for portspoof entries +$enddate_days = 600; // how many days until the ban expires +$reason = "Portspoof Auto-Ban"; + +$now = date("YmdHis"); +$enddate = date("YmdHis", strtotime("+" . $enddate_days . " days")); +$info_list = $now; // unique run identifier logged in info table (YYYYMMDDHHmmss) + +// ------------------------------------------------------------------ +// 1. Get last-pulled timestamp from the most recent previous run +// (info rows where list > 1 are portspoof pull log entries) +// ------------------------------------------------------------------ +$SQL = "SELECT MAX(list) AS prev FROM info WHERE list > 1"; +$result = mysqli_query($con, $SQL); +$row = mysqli_fetch_array($result); + +if (!empty($row['prev'])) { + $last_pulled = DateTime::createFromFormat("YmdHis", $row['prev']); +} else { + // First run — accept all IPs from the feed + $last_pulled = new DateTime("@0"); +} + +// ------------------------------------------------------------------ +// 2. Fetch portspoof API +// ------------------------------------------------------------------ +$ch = curl_init($api_url); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . $api_token]); +curl_setopt($ch, CURLOPT_TIMEOUT, 30); +$response = curl_exec($ch); +$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); +curl_close($ch); + +if ($response === false || $http_code !== 200) { + echo "Error: API fetch failed (HTTP " . $http_code . ")\n"; + $con->close(); + exit; +} + +$data = json_decode($response, true); +if (!isset($data['ips']) || !is_array($data['ips'])) { + echo "Error: Unexpected API response format\n"; + $con->close(); + exit; +} + +// ------------------------------------------------------------------ +// 3. Ingest IPs newer than last_pulled +// ------------------------------------------------------------------ +$inserted = 0; +$updated = 0; +$skipped = 0; + +foreach ($data['ips'] as $entry) { + $src_ip = $entry['src_ip']; + $last_seen_str = $entry['last_seen']; + + // last_seen format: "2026-03-14 10:14:37.000000" — strip microseconds + $last_seen = DateTime::createFromFormat("Y-m-d H:i:s", substr($last_seen_str, 0, 19)); + + if ($last_seen === false || $last_seen <= $last_pulled) { + $skipped++; + continue; + } + + // Normalise to CIDR notation + if (strpos($src_ip, '/') === false) { + $src_ip .= '/32'; + } + + $ip_safe = mysqli_real_escape_string($con, $src_ip); + $reason_safe = mysqli_real_escape_string($con, $reason); + + $SQL = "INSERT INTO blacklist (ip, type, adddate, enddate, reason)" + . " VALUES ('" . $ip_safe . "', " . $pull_type . ", " . $now . ", " . $enddate . ", '" . $reason_safe . "')" + . " ON DUPLICATE KEY UPDATE enddate=" . $enddate . ", type=" . $pull_type . ", reason='" . $reason_safe . "'"; + + if ($con->query($SQL) === TRUE) { + if ($con->affected_rows == 1) { + $inserted++; + } else { + $updated++; + } + } else { + echo "Error on " . $src_ip . ": " . $con->error . "\n"; + } +} + +// ------------------------------------------------------------------ +// 4. Update timestamps +// ------------------------------------------------------------------ + +// Log this run — each run gets a unique row (list = current timestamp) +$SQL_pull = "INSERT INTO info (list, last) VALUES (" . $info_list . ", " . $now . ")"; +$con->query($SQL_pull); + +// Update blacklist last-modified only when rows were actually written +if ($inserted > 0 || $updated > 0) { + $SQL_bl = "UPDATE info SET last=" . $now . " WHERE list=0"; + $con->query($SQL_bl); +} + +echo "Done. Inserted: " . $inserted . ", Updated: " . $updated . ", Skipped: " . $skipped . "\n"; + +$con->close(); +?>