Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 03 Apr 2015 10:40:46 +0200
From:      Hans Petter Selasky <hps@selasky.org>
To:        "Robert N. M. Watson" <rwatson@FreeBSD.org>
Cc:        Mateusz Guzik <mjguzik@gmail.com>, Ian Lepore <ian@freebsd.org>, svn-src-all@freebsd.org, src-committers@freebsd.org, Gleb Smirnoff <glebius@FreeBSD.org>, svn-src-head@freebsd.org
Subject:   Re: svn commit: r280971 - in head: contrib/ipfilter/tools share/man/man4 sys/contrib/ipfilter/netinet sys/netinet sys/netipsec sys/netpfil/pf
Message-ID:  <551E520E.1040708@selasky.org>
In-Reply-To: <4B7DAA59-389F-41AE-99D8-034A7AA61C99@FreeBSD.org>
References:  <201504012226.t31MQedN044443@svn.freebsd.org> <1427929676.82583.103.camel@freebsd.org> <20150402123522.GC64665@FreeBSD.org> <20150402133751.GA549@dft-labs.eu> <20150402134217.GG64665@FreeBSD.org> <20150402135157.GB549@dft-labs.eu> <1427983109.82583.115.camel@freebsd.org> <20150402142318.GC549@dft-labs.eu> <20150402143420.GI64665@FreeBSD.org> <20150402153805.GD549@dft-labs.eu> <alpine.BSF.2.11.1504021657440.27263@fledge.watson.org> <551D8143.4060509@selasky.org> <551D8945.8050906@selasky.org> <8900318B-8155-4131-A0C3-3DE169782EFC@FreeBSD.org> <551D8C6C.9060504@selasky.org> <alpine.BSF.2.11.1504021939390.64391@fledge.watson.org> <551DA5EA.1080908@selasky.org> <551DAC9E.9010303@selasky.org> <358EC58D-1F92-411E-ADEB-8072020E9EB3@FreeBSD.org> <551DEF26.4000403@selasky.org> <4B7DAA59-389F-41AE-99D8-034A7AA61C99@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 04/03/15 08:27, Robert N. M. Watson wrote:
> On 3 Apr 2015, at 02:38, Hans Petter Selasky <hps@selasky.org> wrote:
>
>> I would like have a comment on one final issue about the IP ID field.
>>
>> Given two [small] prime numbers: P and Q
>>
>> Assume you have a firewall that separate two networks, called A and B, that are not allowed to communicate.
>>
>> In network A an application pings the firewall and sees the IP ID field changing P steps.
>>
>> In network B an application pings the firewall and sees the IP ID field changing Q steps.
>>
>> If the application in network A always see that the IP ID field is changing P steps, it knows the application in network B did not send any packets.
>>
>> If the application in network B always see that the IP ID field is changing Q steps, it knows the application in network A did not send any packets.
>>
>> Detecting sending and not sending packets can be used as a way of reliable duplex binary communication.
>>
>> I think the current and past implementation of the IP ID field in FreeBSD can be used to leak information between networks, or am I totally wrong?
>>
>> As long as the IP ID counters are shared between two or more secured networks, there will be a problem. Something along the lines of D2211 might be a way to solve such an information leak without too much overhead!
>

Hi,

Robert:

>
> There are countless covert channels in TCP/IP; breaking the IP implementation to close a covert channel is probably not a worthwhile investment.

The IP ID channel is a _broadcast_ channel to all devices connected to 
the same network stack, including all VPN connections and even 
localhost. It is high speed and it cannot be blocked by firewall rules, 
and works across large networks. The other covert channels can easily be 
reduced by firewall rules. This one can't.

Now that Gleb put in a patch that the shared IP ID counter is not used 
that frequently, only for specific traffic like ping packets, I believe 
this is very likely to be abused.

> As indicated in pretty much the original RFC on the topic, IP IDs
> need to be at minimum unique to a 2-tuple pair, so cannot be
> unique only at the granularity of TCP or UDP connections, GRE
> associations, etc. However, our current implementation keeps them
> globally unique, which means they wrap much faster than
> necessary. Shifting to unique IP ID spaces for IP 2-tuples would
> provide for a much longer wrapping time at the cost of
> maintaining (and looking up!) additional state. There are various
> ways to improve things -- and not all require a full set of
> per-IP-2-tuple IP ID counters, for example, you could have hash
> buckets based on 2 tuples. It's harder to do this in a
> multiprocessor-scalable way, however, as the uniqueness
> requirements are global, and the IP ID space is very small -- a
> more fundamental problem. In general, the world therefore tries
> quite hard not to fragment, using TCP PMTU and careful MTU
> selection for UDP (etc). Also, the world has become quite a lot
> more homogeneous with respect to link-layer MTU over time --
> e.g., with convergence on Ethernet, although VPNs have made
> things a bit less fun.

The IP ID field should have been 64-bit, containing a copy of the 16-bit 
source and destination TCP/UDP ports and a 32-bit sequence number. Now 
that's not possible, but how about saying that each unique IP can have 
at maximum 16 different connections passing to another unique IP. And 
then reduce the sequence number to 8-bits. So:

IP ID = ((src port) & 0xF) | (((dst port) & 0xF) << 4) | 
((inp->inp_sequence++) << 8);

Whenever we see TCP PMTU activated we can release some more combinations 
to a common pool somewhere. Will also work with IP encapsulations, where 
some bits of the sequence number gets replaced, if the IP ID is encoded 
the same ...

You might call me a freshman in the IP stack area and I'm very surprised 
about all the issues I've come across in this area the last couple of 
months. I start understanding why DragonFly forked and why there is 
something called infiniband.

Robert and Gleb:

 >  multiprocessor-scalable

Won't r280971 exactly do what you told me was not a good idea and are 
giving me some critisism for? Namely, result in one IP ID counter per 
TCP/UDP connection. If you have two applications that run on each their 
core. One cause updates to the IP-ID value X times per time unit and the 
other one Y times per time unit. If "(X ⁻ Y)" is odd (50% chance), then 
at some point the IP-ID *will* resemble exactly to the same value in a 
predictable fashion, even if the amount of traffic is considered "low". 
And I think the chance increases with more cores, looking at this from 
the pure perspective of mathematics.

Why is then r280971 fine, when it is doing the same like D2211, only 
D2211 does it in a predictable fashion while r280971 is unpredictable. A 
clear IP ID number sequence on a TCP stream maybe wouldn't even need an 
explanation. Even a 12-year-old would understand, a-ha, that TCP stream 
is incrementing that fast and that stream is incrementing that fast, and 
in the end there is a collision. When a collision happens we will have a 
retransmit, and then maybe we can then randomize the next IP ID value a 
bit to avoid repeated collisions.

--HPS



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?551E520E.1040708>