feat(web/attackers): surface ASN + AS name on cards and detail
Attacker list cards gain an AS<number> chip with the AS description on hover. Attacker detail page adds an AS row beside ORIGIN — same shape as the existing country/source pair so operators can read "this attacker is in DE on AS24940 Hetzner" at a glance instead of having to grep the IP into a separate tool. Both fields collapse to "unknown" when the IP isn't BGP-announced (CGNAT, dark space, RFC1918), matching the existing pattern for country resolution.
This commit is contained in:
@@ -61,6 +61,9 @@ interface AttackerData {
|
||||
commands: { service: string; decky: string; command: string; timestamp: string }[];
|
||||
country_code: string | null;
|
||||
country_source: string | null;
|
||||
asn: number | null;
|
||||
as_name: string | null;
|
||||
asn_source: string | null;
|
||||
ptr_record: string | null;
|
||||
updated_at: string;
|
||||
behavior: AttackerBehavior | null;
|
||||
@@ -1262,6 +1265,26 @@ const AttackerDetail: React.FC = () => {
|
||||
<span className="dim">unknown</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<span className="dim">AS: </span>
|
||||
{attacker.asn != null ? (
|
||||
<span className="matrix-text">
|
||||
AS{attacker.asn}
|
||||
{attacker.as_name && (
|
||||
<span className="dim" style={{ marginLeft: 6, fontSize: '0.75rem' }}>
|
||||
{attacker.as_name}
|
||||
</span>
|
||||
)}
|
||||
{attacker.asn_source && (
|
||||
<span className="dim" style={{ marginLeft: 6, fontSize: '0.75rem' }}>
|
||||
({attacker.asn_source})
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="dim">unknown</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<span className="dim">REVERSE DNS: </span>
|
||||
{attacker.ptr_record ? (
|
||||
|
||||
Reference in New Issue
Block a user