DEV Community

IPYE
IPYE

Posted on AI-assisted

IPv6 Logging and Abuse Handling: Why the /64 Is the Unit

Disclosure up front: I run IPYE, a company that leases IP space. It gets one short paragraph at the end; the rest is plain networking.

In IPv4, one address usually identifies one customer or one host, so counting, blocking, and reporting by address works well enough. In IPv6 that stops being true. A single subscriber can have a /64 or larger, and a host with privacy addresses (RFC 8981) changes its source address regularly. A log that treats each IPv6 address as a separate client counts one machine as thousands, misses abuse patterns, and fills with entries that never repeat. This article covers what to log, how to aggregate, how to find the right contact, and what to put in an abuse report. Examples use 2001:db8:100::/48 and 203.0.113.0/24.

Log the full address, aggregate for analysis

Keep the complete address in the raw log, since you may need it later. Then derive an aggregate for analysis. Useful reasoning units are:

Observation Block or count by
One misbehaving client, stable address The single address, only if it stays fixed
Client rotating within its subnet The /64
Client rotating across several /64s The /56 or /48 of the delegation
Whole network misbehaving The announced prefix or ASN, after checking it

The reason for the /64 is that it is the standard size of a subnet, and a device on that subnet can pick any address in it, so no one address is meaningful. Home networks and mobile networks differ in what they delegate, and you cannot see this from the outside, so be ready to widen the unit when evidence shows an attacker moving between /64s.

Normalise the text

IPv6 allows many textual forms of the same address: leading zeros, :: compression, and upper or lower case. RFC 5952 defines a canonical form (lowercase, leading zeros removed, longest run of zeros compressed). If you search logs with grep, differently formatted values will not match each other. Normalise addresses at ingestion, or store them in a type that understands them. In PostgreSQL, for instance, the inet type stores addresses numerically, and you can group by /64 with a query like:

SELECT network(set_masklen(client_ip, 64)) AS subnet, count(*)
FROM access_log
WHERE family(client_ip) = 6
GROUP BY 1
ORDER BY 2 DESC
LIMIT 20;
Enter fullscreen mode Exit fullscreen mode

In scripting, Python's ipaddress module can do the same: ipaddress.ip_network('2001:db8:100:1::25/64', strict=False) returns the enclosing /64.

Take care with proxies and NAT

Behind a load balancer, the logged address may be the balancer's. Restore the real client address first, using the PROXY protocol or a trusted header, as discussed in an earlier article, or your records will say nothing about the client. IPv4 clients behind carrier-grade NAT share one address among many users, so IPv4 evidence is weaker than it looks. IPv6 evidence, though better, is also not a person.

Time and records

Record time in UTC with its zone, and record the time zone of any report you send. For abuse, an address without a timestamp cannot be traced, because a prefix may be reassigned and a subscriber's address may rotate. Keep what you need, for as long as you need it, and no more. IP addresses are treated as personal data in some jurisdictions, so follow your own retention policy and applicable law, and decide in advance who may query these logs.

Find the right contact

To report abuse you need the responsible network's contact. Look up the address with RDAP or WHOIS:

whois 2001:db8:100:1::25
Enter fullscreen mode Exit fullscreen mode

Read the most specific record that covers the address, not the parent allocation: a sub-delegation to a customer or hosting service often has its own contact. Look for the abuse-c or abuse mailbox, the organisation, and the inet6num range. If the specific record has no abuse contact, go up a level. The routing registry or origin AS data show who announces the prefix, which can lead to the upstream when the registered organisation does not respond. The article on WHOIS and RDAP describes reading these records.

What a useful abuse report contains

  1. The offending address and the prefix (the /64) it came from.
  2. Timestamps in UTC, with the time zone stated.
  3. A short, factual description of the behaviour, such as repeated login attempts or scraping against a specific service.
  4. A few sample log lines, with your own sensitive data removed.
  5. Whether the traffic is ongoing.
  6. Your contact details, and what action you ask for.

Keep it brief and factual, one incident per report, and sent to the registered contact. Do not attach large log files unless requested.

Blocking responsibly

  • Start narrow: block the /64, not the /48, unless evidence supports widening.
  • Use expiry on every block, so mistakes and reassigned prefixes age out.
  • Check what you are blocking: a /64 in a hosting network might be a shared service, and a mobile network /64 may be shared between users, depending on how the operator assigns them.
  • Do not block ICMPv6 as a side effect of blocking addresses.
  • Record why each block was added.

Summary

Treat the /64 as the basic unit, log in canonical form, keep the full address, aggregate for analysis, and send precise reports to the contact in the most specific registry record. Done consistently, IPv6 abuse handling works much like IPv4, with the unit of identity changed.

About IPYE

IPYE (https://my.ipye.com) leases IPv4, IPv6, and ASN space; a /48 IPv6 block is free for the first year. LOA, ROA, rDNS, and WHOIS are handled by IPYE. Locations: Los Angeles, New York, Ashburn, Salt Lake City, London, Amsterdam, and Frankfurt. Questions: ipye@turnel.com.

Disclosure: I run IPYE

Top comments (0)