mirror of
https://github.com/getnamingo/registry.git
synced 2025-05-10 08:48:34 +02:00
Added basic abuse monitoring and report (Spec 11)
This commit is contained in:
parent
a453a6d745
commit
55fbbfd503
5 changed files with 161 additions and 28 deletions
|
@ -53,7 +53,7 @@ Namingo is equipped with a comprehensive suite of features to meet the diverse n
|
|||
|
||||
- **GDPR-Compliant Database Encryption**: Supports comprehensive database encryption to ensure GDPR compliance. For more details, see our [Encryption Guide](docs/encryption.md).
|
||||
|
||||
- **Automation Scripts**: Ensures the continuous and smooth operation of the registry by performing routine checks and operations. Advanced scripting capabilities also facilitate the generation of RDE deposits, the creation of ICANN's monthly reports, and ensure full compliance with other ICANN gTLD requirements for streamlined regulatory adherence.
|
||||
- **Automation Scripts**: Ensures the continuous and smooth operation of the registry by performing routine checks and operations. Advanced scripting capabilities also facilitate the generation of RDE deposits, the creation of ICANN's monthly reports, Spec 11 abuse monitoring, and ensure full compliance with other ICANN gTLD requirements for streamlined regulatory adherence.
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
|
|
|
@ -28,34 +28,12 @@ Coroutine::create(function () use ($pool, $log) {
|
|||
try {
|
||||
$pdo = $pool->get();
|
||||
$stmt = $pdo->query('SELECT name, clid FROM domain');
|
||||
// Get URLhaus data
|
||||
$urlhausData = getUrlhausData();
|
||||
|
||||
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) {
|
||||
|
@ -79,6 +57,29 @@ Coroutine::create(function () use ($pool, $log) {
|
|||
]);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$log->info('job finished successfully.');
|
||||
} catch (PDOException $e) {
|
||||
|
|
111
automation/abusereport.php
Normal file
111
automation/abusereport.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$c = require_once 'config.php';
|
||||
require_once 'helpers.php';
|
||||
|
||||
// Connect to the database
|
||||
$dsn = "{$c['db_type']}:host={$c['db_host']};dbname={$c['db_database']}";
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
$logFilePath = '/var/log/namingo/abusereport.log';
|
||||
$log = setupLogger($logFilePath, 'Abuse_Report');
|
||||
$log->info('job started.');
|
||||
|
||||
try {
|
||||
$dbh = new PDO($dsn, $c['db_username'], $c['db_password'], $options);
|
||||
} catch (PDOException $e) {
|
||||
$log->error('DB Connection failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
// Prepare and execute the query
|
||||
$query = "SELECT reported_domain, nature_of_abuse, status, priority, date_of_incident, date_created FROM support_tickets WHERE category_id = '8'";
|
||||
$stmt = $dbh->query($query);
|
||||
|
||||
// Fetch all rows
|
||||
$tickets = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Start HTML output
|
||||
$html = "<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Abuse Report</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Abuse Report</h1>
|
||||
<p>Report Date: " . date('Y-m-d H:i:s') . "</p>"; // Display report generation date
|
||||
|
||||
if (empty($tickets)) {
|
||||
$html .= "<p>No abuse cases found for the period.</p>"; // Message if no tickets
|
||||
} else {
|
||||
// Continue with the table if tickets are found
|
||||
$html .= "<table border='1'>
|
||||
<tr>
|
||||
<th>Reported Domain</th>
|
||||
<th>Nature of Abuse</th>
|
||||
<th>Status</th>
|
||||
<th>Priority</th>
|
||||
<th>Date of Incident</th>
|
||||
<th>Date Reported</th>
|
||||
</tr>";
|
||||
|
||||
// Loop through tickets and add rows to the table
|
||||
foreach ($tickets as $ticket) {
|
||||
$html .= "<tr>
|
||||
<td>" . htmlspecialchars($ticket['reported_domain']) . "</td>
|
||||
<td>" . htmlspecialchars($ticket['nature_of_abuse']) . "</td>
|
||||
<td>" . htmlspecialchars($ticket['status']) . "</td>
|
||||
<td>" . htmlspecialchars($ticket['priority']) . "</td>
|
||||
<td>" . htmlspecialchars($ticket['date_of_incident']) . "</td>
|
||||
<td>" . htmlspecialchars($ticket['date_created']) . "</td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
$html .= "</table>"; // Close the table
|
||||
}
|
||||
|
||||
// End HTML
|
||||
$html .= "</body>
|
||||
</html>";
|
||||
|
||||
// Prepare the data array
|
||||
$data = [
|
||||
'type' => 'sendmail',
|
||||
'toEmail' => $toEmail,
|
||||
'subject' => 'Abuse Report',
|
||||
'body' => $html,
|
||||
];
|
||||
|
||||
$url = 'http://127.0.0.1:8250';
|
||||
|
||||
$options = [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POSTFIELDS => json_encode($data),
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen(json_encode($data))
|
||||
],
|
||||
];
|
||||
|
||||
$curl = curl_init($url);
|
||||
curl_setopt_array($curl, $options);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception(curl_error($curl), curl_errno($curl));
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
$log->info('job finished successfully.');
|
||||
} catch (PDOException $e) {
|
||||
$log->error('Database error: ' . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
$log->error('Error: ' . $e->getMessage());
|
||||
}
|
|
@ -18,6 +18,9 @@
|
|||
# run abusemonitor.php every hour
|
||||
30 * * * * root /usr/bin/php8.2 /opt/registry/automation/abusemonitor.php
|
||||
|
||||
# run abusereport.php every day
|
||||
5 0 * * * root /usr/bin/php8.2 /opt/registry/automation/abusereport.php
|
||||
|
||||
# run send-invoice.php every 1st day
|
||||
1 0 1 * * root /usr/bin/php8.2 /opt/registry/automation/send-invoice.php
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ use Monolog\Handler\StreamHandler;
|
|||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Ds\Map;
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Coroutine\Http\Client;
|
||||
|
||||
/**
|
||||
* Sets up and returns a Logger instance.
|
||||
|
@ -68,9 +70,25 @@ function checkSpamhaus($domain) {
|
|||
|
||||
function getUrlhausData() {
|
||||
$urlhausUrl = 'https://urlhaus.abuse.ch/downloads/json_recent/';
|
||||
$json = file_get_contents($urlhausUrl);
|
||||
$data = json_decode($json, true);
|
||||
$map = new Map();
|
||||
$data = [];
|
||||
|
||||
Coroutine::create(function () use ($urlhausUrl, &$data) {
|
||||
$client = new Client('urlhaus.abuse.ch', 443, true); // SSL
|
||||
$client->set(['timeout' => 5]); // 5 seconds timeout
|
||||
$client->get('/downloads/json_recent/');
|
||||
|
||||
if ($client->statusCode == 200) {
|
||||
$data = json_decode($client->body, true);
|
||||
}
|
||||
|
||||
$client->close();
|
||||
});
|
||||
|
||||
return processUrlhausData($data);
|
||||
}
|
||||
|
||||
function processUrlhausData($data) {
|
||||
$map = new \Ds\Map();
|
||||
|
||||
foreach ($data as $entry) {
|
||||
foreach ($entry as $urlData) {
|
||||
|
|
Loading…
Add table
Reference in a new issue