Fix IP reporting and update the row
Some checks failed
Build IP lists / Build scanners list (binaryedge) (push) Failing after -2m8s
Build IP lists / Build scanners list (stretchoid) (push) Failing after -2m10s
Build IP lists / build-aws-cloudfront (push) Failing after -2m10s

This commit is contained in:
2024-09-23 00:06:03 +02:00
parent d6757902f6
commit e48493cf6a
2 changed files with 93 additions and 36 deletions

View File

@ -19,10 +19,10 @@ use uuid::Uuid;
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use hickory_resolver::config::{NameServerConfigGroup, ResolverConfig, ResolverOpts};
use hickory_resolver::{Name, Resolver}; use hickory_resolver::{Name, Resolver};
use hickory_resolver::config::{NameServerConfigGroup, ResolverOpts, ResolverConfig};
use std::time::Duration;
use std::net::IpAddr; use std::net::IpAddr;
use std::time::Duration;
use diesel::serialize::IsNull; use diesel::serialize::IsNull;
use diesel::{serialize, MysqlConnection}; use diesel::{serialize, MysqlConnection};
@ -144,34 +144,58 @@ fn detect_scanner(ptr_result: &ResolvedResult) -> Result<Scanners, ()> {
async fn handle_ip(pool: web::Data<DbPool>, ip: String) -> Result<Scanner, Option<ResolvedResult>> { async fn handle_ip(pool: web::Data<DbPool>, ip: String) -> Result<Scanner, Option<ResolvedResult>> {
let query_address = ip.parse().expect("To parse"); let query_address = ip.parse().expect("To parse");
let client = get_dns_client(); let ptr_result: Result<ResolvedResult, ()> = std::thread::spawn(move || {
let ptr_result: ResolvedResult = if let Ok(res) = get_ptr(query_address, client) { let client = get_dns_client();
res let ptr_result: ResolvedResult = if let Ok(res) = get_ptr(query_address, client) {
} else { res
return Err(None); } else {
}; return Err(());
};
Ok(ptr_result)
})
.join()
.unwrap();
match detect_scanner(&ptr_result) { if ptr_result.is_err() {
return Err(None);
}
let result = ptr_result.unwrap();
match detect_scanner(&result) {
Ok(scanner_name) => { Ok(scanner_name) => {
let ip_type = if ip.contains(':') { 6 } else { 4 }; let ip_type = if ip.contains(':') { 6 } else { 4 };
let scanner = Scanner {
ip: ip,
ip_type: ip_type,
scanner_name: scanner_name.clone(),
ip_ptr: match ptr_result.result {
Some(ptr) => Some(ptr.to_string()),
None => None,
},
created_at: Utc::now().naive_utc(),
updated_at: None,
last_seen_at: None,
last_checked_at: None,
};
// use web::block to offload blocking Diesel queries without blocking server thread // use web::block to offload blocking Diesel queries without blocking server thread
web::block(move || { web::block(move || {
// note that obtaining a connection from the pool is also potentially blocking // note that obtaining a connection from the pool is also potentially blocking
let conn = &mut pool.get().unwrap(); let conn = &mut pool.get().unwrap();
let scanner_row_result = Scanner::find(ip.clone(), ip_type, conn);
let scanner_row = match scanner_row_result {
Ok(scanner_row) => scanner_row,
Err(_) => return Err(None),
};
let scanner = if let Some(mut scanners) = scanner_row {
scanners.last_seen_at = Some(Utc::now().naive_utc());
scanners.last_checked_at = Some(Utc::now().naive_utc());
scanners.updated_at = Some(Utc::now().naive_utc());
scanners
} else {
Scanner {
ip: ip,
ip_type: ip_type,
scanner_name: scanner_name.clone(),
ip_ptr: match result.result {
Some(ptr) => Some(ptr.to_string()),
None => None,
},
created_at: Utc::now().naive_utc(),
updated_at: None,
last_seen_at: None,
last_checked_at: None,
}
};
match scanner.save(conn) { match scanner.save(conn) {
Ok(scanner) => Ok(scanner), Ok(scanner) => Ok(scanner),
@ -182,7 +206,7 @@ async fn handle_ip(pool: web::Data<DbPool>, ip: String) -> Result<Scanner, Optio
.unwrap() .unwrap()
} }
Err(_) => Err(Some(ptr_result)), Err(_) => Err(Some(result)),
} }
} }
@ -258,14 +282,30 @@ pub struct ReportParams {
async fn handle_report(pool: web::Data<DbPool>, params: web::Form<ReportParams>) -> HttpResponse { async fn handle_report(pool: web::Data<DbPool>, params: web::Form<ReportParams>) -> HttpResponse {
match handle_ip(pool, params.ip.clone()).await { match handle_ip(pool, params.ip.clone()).await {
Ok(scanner) => html_contents(match scanner.scanner_name { Ok(scanner) => html_contents(match scanner.scanner_name {
Scanners::Binaryedge => format!( Scanners::Binaryedge => match scanner.last_checked_at {
"Reported an escaped ninja! <b>{}</a> known as {:?}.", Some(date) => format!(
scanner.ip, scanner.ip_ptr "Reported a binaryedge ninja! <b>{}</b> known as {} since {date}.",
), scanner.ip,
Scanners::Stretchoid => format!( scanner.ip_ptr.unwrap_or("".to_string())
"Reported a stretchoid agent! <b>{}</a> known as {:?}.", ),
scanner.ip, scanner.ip_ptr None => format!(
), "Reported a binaryedge ninja! <b>{}</b> known as {}.",
scanner.ip,
scanner.ip_ptr.unwrap_or("".to_string())
),
},
Scanners::Stretchoid => match scanner.last_checked_at {
Some(date) => format!(
"Reported a stretchoid agent! <b>{}</b> known as {} since {date}.",
scanner.ip,
scanner.ip_ptr.unwrap_or("".to_string())
),
None => format!(
"Reported a stretchoid agent! <b>{}</b> known as {}.",
scanner.ip,
scanner.ip_ptr.unwrap_or("".to_string())
),
},
_ => format!("Not supported"), _ => format!("Not supported"),
}), }),
@ -293,7 +333,9 @@ impl<'de> Deserialize<'de> for SecurePath {
let k: String = s[0].to_string(); let k: String = s[0].to_string();
// A-Z a-z 0-9 // A-Z a-z 0-9
// . - _ // . - _
if k.chars().all(|c| c.is_ascii_alphanumeric() || c == '.' || c == '-' || c == '_') { if k.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '.' || c == '-' || c == '_')
{
return Ok(SecurePath { data: k }); return Ok(SecurePath { data: k });
} }
Err(serde::de::Error::custom(format!( Err(serde::de::Error::custom(format!(
@ -447,13 +489,12 @@ fn get_connection(database_url: &str) -> DbPool {
} }
fn get_dns_client() -> Resolver { fn get_dns_client() -> Resolver {
let server_ip = "1.1.1.1"; let server_ip = "1.1.1.1";
let server = NameServerConfigGroup::from_ips_clear( let server = NameServerConfigGroup::from_ips_clear(
&[IpAddr::from_str(server_ip).unwrap()], &[IpAddr::from_str(server_ip).unwrap()],
53,// Port 53 53, // Port 53
true, true,
); );
let config = ResolverConfig::from_parts(None, vec![], server); let config = ResolverConfig::from_parts(None, vec![], server);

View File

@ -22,6 +22,22 @@ pub struct Scanner {
} }
impl Scanner { impl Scanner {
pub fn find(
ip_address: String,
ip_type: u8,
conn: &mut MysqlConnection,
) -> Result<Option<Scanner>, DieselError> {
use crate::schema::scanners;
scanners
.select(Scanner::as_select())
.filter(scanners::ip.eq(ip_address))
.filter(scanners::ip_type.eq(ip_type))
.order((scanners::ip_type.desc(), scanners::created_at.desc()))
.first(conn)
.optional()
}
pub fn list_names( pub fn list_names(
scanner_name: Scanners, scanner_name: Scanners,
conn: &mut MysqlConnection, conn: &mut MysqlConnection,