diff --git a/automation/abusemonitor.php b/automation/abusemonitor.php new file mode 100644 index 0000000..92eb7fb --- /dev/null +++ b/automation/abusemonitor.php @@ -0,0 +1,89 @@ +info('job started.'); + +use Swoole\Coroutine; + +// Initialize the PDO connection pool +$pool = new Swoole\Database\PDOPool( + (new Swoole\Database\PDOConfig()) + ->withDriver($c['db_type']) + ->withHost($c['db_host']) + ->withPort($c['db_port']) + ->withDbName($c['db_database']) + ->withUsername($c['db_username']) + ->withPassword($c['db_password']) + ->withCharset('utf8mb4') +); + +Swoole\Runtime::enableCoroutine(); + +// Creating first coroutine +Coroutine::create(function () use ($pool, $log) { + try { + $pdo = $pool->get(); + $stmt = $pdo->query('SELECT name, clid FROM domain'); + + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $domain = $row['name']; + + if (checkSpamhaus($domain)) { + $userStmt = $pdo->prepare('SELECT user_id FROM registrar_users WHERE registrar_id = ?'); + $userStmt->execute([$row['clid']]); + $userData = $userStmt->fetch(PDO::FETCH_ASSOC); + + if ($userData) { + // Prepare INSERT statement to add a ticket + $insertStmt = $pdo->prepare('INSERT INTO support_tickets (id, user_id, category_id, subject, message, status, priority, reported_domain, nature_of_abuse, evidence, relevant_urls, date_of_incident, date_created, last_updated) VALUES (NULL, ?, 8, ?, ?, "Open", "High", ?, "Abuse", ?, ?, ?, CURRENT_TIMESTAMP(3), CURRENT_TIMESTAMP(3))'); + + // Execute the prepared statement with appropriate values + $insertStmt->execute([ + $userData['user_id'], // user_id + "Abuse Report for $domain", // subject + "Abuse detected for domain $domain.", // message + $domain, // reported_domain + "Link to Spamhaus", // evidence + "http://www.spamhaus.org/query/domain/$domain", // relevant_urls + date('Y-m-d H:i:s') // date_of_incident + ]); + } + } + + // Get URLhaus data + $urlhausData = getUrlhausData(); + $urlhausResult = checkUrlhaus($domain, $urlhausData); + + if ($urlhausResult) { + $userStmt = $pdo->prepare('SELECT user_id FROM registrar_users WHERE registrar_id = ?'); + $userStmt->execute([$row['clid']]); + $userData = $userStmt->fetch(PDO::FETCH_ASSOC); + + if ($userData) { + // Prepare INSERT statement to add a ticket + $insertStmt = $pdo->prepare('INSERT INTO support_tickets (id, user_id, category_id, subject, message, status, priority, reported_domain, nature_of_abuse, evidence, relevant_urls, date_of_incident, date_created, last_updated) VALUES (NULL, ?, 8, ?, ?, "Open", "High", ?, "Abuse", ?, ?, ?, CURRENT_TIMESTAMP(3), CURRENT_TIMESTAMP(3))'); + + // Execute the prepared statement with appropriate values + $insertStmt->execute([ + $userData['user_id'], // user_id + "Abuse Report for $domain", // subject + "Abuse detected for domain $domain.", // message + $domain, // reported_domain + "Link to URLhaus", // evidence + "https://urlhaus.abuse.ch/downloads/json_recent/", // relevant_urls + date('Y-m-d H:i:s') // date_of_incident + ]); + } + } + } + $log->info('job finished successfully.'); + } catch (PDOException $e) { + $log->error('Database error: ' . $e->getMessage()); + } catch (Throwable $e) { + $log->error('Error: ' . $e->getMessage()); + } +}); \ No newline at end of file diff --git a/automation/crontab.example b/automation/crontab.example index 18f52b8..c0d5f74 100644 --- a/automation/crontab.example +++ b/automation/crontab.example @@ -15,6 +15,9 @@ # run auto-approve-transfer.php every hour 45 * * * * root /usr/bin/php8.2 /opt/registry/automation/auto-approve-transfer.php +# run abusemonitor.php every hour +30 * * * * root /usr/bin/php8.2 /opt/registry/automation/abusemonitor.php + # run send-invoice.php every 1st day 1 0 1 * * root /usr/bin/php8.2 /opt/registry/automation/send-invoice.php diff --git a/automation/helpers.php b/automation/helpers.php index f341b3a..f5bcf29 100644 --- a/automation/helpers.php +++ b/automation/helpers.php @@ -6,6 +6,7 @@ use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Monolog\Formatter\LineFormatter; +use Ds\Map; /** * Sets up and returns a Logger instance. @@ -54,4 +55,33 @@ function fetchCount($pdo, $tableName) { // Fetch and return the count $result = $stmt->fetch(); return $result['count']; +} + +// Function to check domain against Spamhaus SBL +function checkSpamhaus($domain) { + // Append '.sbl.spamhaus.org' to the domain + $queryDomain = $domain . '.sbl.spamhaus.org'; + + // Check if the domain is listed in the SBL + return checkdnsrr($queryDomain, "A"); +} + +function getUrlhausData() { + $urlhausUrl = 'https://urlhaus.abuse.ch/downloads/json_recent/'; + $json = file_get_contents($urlhausUrl); + $data = json_decode($json, true); + $map = new Map(); + + foreach ($data as $entry) { + foreach ($entry as $urlData) { + $domain = parse_url($urlData['url'], PHP_URL_HOST); // Extract domain from URL + $map->put($domain, $urlData); // Store data against domain + } + } + + return $map; +} + +function checkUrlhaus($domain, Map $urlhausData) { + return $urlhausData->get($domain, false); } \ No newline at end of file diff --git a/docs/install.md b/docs/install.md index 13a4d72..bf252cf 100644 --- a/docs/install.md +++ b/docs/install.md @@ -9,7 +9,7 @@ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' -o caddy-stabl gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg caddy-stable.gpg.key curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list apt update && apt upgrade -apt install -y bzip2 caddy composer curl gettext git gnupg2 net-tools php8.2 php8.2-bcmath php8.2-cli php8.2-common php8.2-curl php8.2-fpm php8.2-gd php8.2-gmp php8.2-gnupg php8.2-imap php8.2-intl php8.2-mbstring php8.2-opcache php8.2-readline php8.2-swoole php8.2-xml pv unzip wget whois +apt install -y bzip2 caddy composer curl gettext git gnupg2 net-tools php8.2 php8.2-bcmath php8.2-cli php8.2-common php8.2-curl php8.2-ds php8.2-fpm php8.2-gd php8.2-gmp php8.2-gnupg php8.2-imap php8.2-intl php8.2-mbstring php8.2-opcache php8.2-readline php8.2-swoole php8.2-xml pv unzip wget whois ``` ### Configure time: