Request for a Lockdown option

Steffen Nurpmeso steffen at sdaoden.eu
Tue Jul 16 09:19:47 AEST 2024


Gert Doering wrote in
 <ZpUvZQr0T-vOToo2 at greenie.muc.de>:
 |On Sun, Jul 14, 2024 at 10:25:46AM +0100, Brian Candler wrote:
 |> On 14/07/2024 03:49, Steffen Nurpmeso wrote:
 |>>    https://datatracker.ietf.org/doc/html/draft-cmetz-v6ops-v4mapped-api-\
 |>>    harmful-01
 |>> 
 |>> but as an application developer i find it ugly not to be able to
 |>> "simply do it", and get back a mapped address.
 |> 
 |> You are looking at a Internet draft which expired more than 20 years ago.
 |
 |But, speaking as another application developer, it's still harmful - the
 |amount of bugs I've found in OS stacks that were the result of cross-stack
 |packets (v4 packets mapped in a v6 socket) was quite amazing.  Like,
 |ancillary data not being returned ("oops, we forgot to implement that
 |code path in the kernel"), outgoing source IP not being settable for UDP
 |packets ("oops, another code path that was never written")...

I also found a Linux xt_recent "bug" while doing this now in that

  printf '%s\n' "+::ffff:80.187.103.83" > /proc/net/xt_recent/alien_super

results in

  < /proc/net/xt_recent/alien_super awk '{print $1}'
  src=0000:0000:0000:0000:0000:ffff:50bb:6755

without the actual IPv4 address being handled (bugzilla 219038).
(But then i would assume bugs happen everywhere and all the time,
and it would be interesting to know the timeframe of your
experience.)

 |Add to that logging of addresses ("packet from xxx") which all of a sudden
 |looks different between "v4 on a v4 socket" and "v4 on a v6 socket".

My IPAddress C++ class always checked whether it was IPv4 upon
setting an IPv6 address (i have forgotten what this does, could be
wrong even, way over twenty years and practically no wire
experience, no interface identifier support)

          // is it IPv4 (RFC's 1884, 2133)?
          if(
  #if(SF_64BIT)
                  m_ip6.a64[0] == 0
  #else
                  m_ip6.a32[0] == 0
           &&     m_ip6.a32[1] == 0
  #endif
           &&     m_ip6.a16[4] == 0  // a32[2] == 0 || a32[2] == NTOH(0x0000FFFF)
           ) {
                  ui4     i = m_ip6.a32[3];
                  m_ip4 = i;
                  switch(m_ip6.a16[5]) {
                  case 0xFFFF:    // mapped
                          m_flags = f_map4;
                          goto jchk;
                  case 0x0:       // compatible?
                          m_flags = f_comp4;
  jchk:                   // not any6, not loopback6
                          if(i != 0 && i != SF_INJ_BLE(0x00000001,0x01000000))
                                  break;
                          // fall..
                  default:
                          goto jno4;
                  }
          } else {
  jno4:           m_flags = f_none;
                  m_ip4 = broadcast4;
          }

and then the toString() had a v4if4 (much faster even).
Unfortunately the normal C environment is so poor (but the modern
C++ environment is a monster).

 |So the first impression is quite nice, but in retrospective, it was one
 |of the truly bad ideas in IPv6 socket API design - and I do applaud the
 |OpenBSD people for being stubborn here.

All the BSDs (started off) use(ing) the KAME stack, which has
a nice read in

  https://github.com/kame/kame/blob/master/IMPLEMENTATION

  RFC3493: Basic Socket Interface Extensions for IPv6
      * IPv4 mapped address (3.7) and special behavior of IPv6 wildcard bind
        socket (3.8) are,
          - supported and turned on by default on KAME/FreeBSD[34]
            and KAME/BSDI4,
          - supported but turned off by default on KAME/NetBSD and KAME/FreeBSD5,
          - not supported on KAME/FreeBSD228, KAME/OpenBSD and KAME/BSDI3.
        see 1.12 in this document for details.
      * The AI_ALL and AI_V4MAPPED flags are not supported.

and

  It looks that RFC2553/3493 talks too little on wildcard bind issue,
  specifically on (1) port space issue, (2) failure mode, (3) relationship
  between AF_INET/INET6 wildcard bind like ordering constraint, and (4) behavior
  when conflicting socket is opened

and .. what i do not like ..

  If the address is IPv4 mapped address, you may want to reject
  the connection.  You can check the condition by using
  IN6_IS_ADDR_V4MAPPED() macro.  This is one of the reasons the
  author of the section (itojun) dislikes special behavior of
  AF_INET6 wildcard bind.

I mean, that easy it is!  Mapped or compat, or plain IPv6.  Where
is the problem?
At least i as an application developer would naively say so.

 |(Yes, OpenVPN also went the lazy way of "not implement multiple socket
 |support", and then having to debug all the ways this didn't work right,
 |or the logging was confusing or wrong, etc.)

But that logging thing was just a missing abstraction, likely.
Sounds horrible.

 |-- 
 |"If was one thing all people took for granted, was conviction that if you 
 | feed honest figures into a computer, honest figures come out. Never \
 | doubted 
 | it myself till I met a computer with a sense of humor."
 |                             Robert A. Heinlein, The Moon is a Harsh \
 |                             Mistress

I thought the moon is that thing we stood on in five days 55 years
ago (iirc).  And Mars is next.

Btw i will do this tomorrow.  The script had an ugly way of
finding bash (if necessary) which soils the rest.  This means
select(2) plus two sockets.  The rest seems fine.  I post the
final thing once again when that is also done, and then i am
silent on this issue.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)


More information about the openssh-unix-dev mailing list