[rbldnsd] v4-in-v6 queries seen in the wild

Alex Lasoriti lasoriti at spamteq.com
Wed Aug 27 15:53:29 MSK 2014


On Wed, Jul 09, 2014 at 01:33:59PM +0200, Michael Tokarev wrote:
> 01.07.2014 06:31, Michael Tokarev wrote:
> >30.06.2014 19:32, Alex Lasoriti wrote:
> >>On Wed, Jan 08, 2014 at 09:46:53AM +0200, Michael Tokarev wrote:
> >>>08.01.2014 01:22, Alex Lasoriti wrote:
> >>>>I analyzed the flux of queries relative to IPv6 addresses that is
> >>>>currently coming to the Spamhaus mirrors  (even if at this stage
> >>>>every IPv6 query is still getting NXDOMAIN as answer and the IPv6
> >>>>service has not been announced yet... but of course mail servers
> >>>>don't know that and generate those queries anyway!).
> >>>>
> >>>>While their overall number is still very tiny, about 12% of them
> >>>>refer to IPs in ::ffff:0:0/96 - the so-called 'v4-in-v6' space
> >>>>(excluding queries for the test addresses).
> >>>>
> >>>>So there are some mail servers around that see IPv4 addresses
> >>>>embedded in an IPv6 framework rather than in their native form,
> >>>>and they send out IPv6 queries to get BL informations about
> >>>>these IPv4 addresses - without bothering to convert them into their
> >>>>native IPv4 representation.
> >>>>
> >>>>You see where I am going: right now, if a zone has both an IPv4 and
> >>>>an IPv6 dataset attached, these two spaces are treated as entirely
> >>>>separate and independent.  So, A.B.C.D may be listed but it's
> >>>>v6-in-v4 counterpart ::ffff:A.B.C.D may not be listed.  So a query for
> >>>>::ffff:A.B.C.D will return NXDOMAIN and the mail will go through.
> 
> >>>If you don't see it is working, -- maybe there's a just bug in there.
> >>>When I implemented it, I weren't able to actually test it, so have
> >>>no real idea whenever it actually works ;)
> 
> So, which queries are made by email software when such mapped addresses
> are encountered?  Can you show me an example real DNS query please?
> 
> I looked at the code (still being on a beach), and here it is, in
> rbldnsd_packet.c:dntoip():
> 
> static const ip6oct_t ip6mapped_pfx[12] =
>   "\0\0\0\0\0\0\0\0"
>   "\377\377\377\377";
> 
>     qi->qi_ip6valid =
>       qlab == 32 && qi->qi_dnlen0 == 64 && dntoip6addr(q, qi->qi_ip6);
>     if (flags & DSTF_IP4REV &&
>         memcmp(qi->qi_ip6, ip6mapped_pfx, sizeof(ip6mapped_pfx)) == 0) {
>       /* construct IP4 from IP4MAPPED */
>       qi->qi_ip4 = unpack32(qi->qi_ip6 + sizeof(ip6mapped_pfx));
>       qi->qi_ip4valid = 1;
>     }
> 
> The code first checks whenever we have a valid IPv6 address in there,
> which is true only if there are 32 domain labels (one for each nibble)
> and the length of dns name representation is 64 bytes.  This test should
> be true, or else rbldnsd wont recognize any v6 addresses at all --
> provided that these v4-mapped addresses are actually represented the
> same way as other regular v6 addresses are.
> 
> Next the code compares the beginning of the recognized IPv6 address with
> the v4-mapped prefix, ::ffff: (only if there's at least one reverse-ipv4
> dataset attached to the base domain), and if the v6 address starts with
> this prefix, it sets the ipv4 address too.
> 
> The idea was to list v4 addresses only in a v4 dataset and v6 addresses
> (at least "pure" v6) only in v6 dataset.
> 
> So from the code, it looks like it should work.  Should work when you
> list v4 addresses in real v4 dataset, and perform a query against it
> using a v4mapped form of a v6 address.
> 
> But it all was quite some time ago, and I don't remember details, maybe
> I really miss somehting and the code should be extended to handle other
> variations.  That's why I'm asking for actual queries as seen in your
> case, to see how a real query looks like.

Ok, here is an example (sorry for the delay, holidays and subsequent
congestion):

89.144.140.114 is currently in Spamhaus XBL.  Its v4-in-v6 representation
is ::ffff:5990:8c72 . So:

% dig a 114.140.144.89.xbl.spamhaus.org
;; ANSWER SECTION:
114.140.144.89.xbl.spamhaus.org. 300 IN	A	127.0.0.4

but

% dig a 2.7.c.8.0.9.9.5.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.xbl.spamhaus.org
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 37719


I found the bug, I think.  In a v4-in-v6 address you have

(10*8=80 '0' bits) + (2*8 = 16 '1' bits) + (4*8 = 32 bits of the IPv4) 

so the initial constant part of 96 bits (12 bytes) is
\0\0\0\0\0\0\0\0\0\0\377\377,    but you are testing against
\0\0\0\0\0\0\0\0\377\377\377\377

Replacing

static const ip6oct_t ip6mapped_pfx[12] =
  "\0\0\0\0\0\0\0\0"
  "\377\377\377\377";

with

static const ip6oct_t ip6mapped_pfx[12] =
  "\0\0\0\0\0\0\0\0"
  "\0\0\377\377";

appears to solve the problem:

% dig a 2.7.c.8.0.9.9.5.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.xbl.spamhaus.org
;; ANSWER SECTION:
2.7.c.8.0.9.9.5.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.xbl.spamhaus.org. 300 IN A 127.0.0.4

Alex



More information about the rbldnsd mailing list