Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Jul 2019 20:23:26 +0200
From:      Michael Tuexen <tuexen@freebsd.org>
To:        Vitalij Satanivskij <satan@ukr.net>
Cc:        freebsd-net@freebsd.org, Paul <devgs@ukr.net>
Subject:   Re: Issues with TCP Timestamps allocation
Message-ID:  <B7BD397D-1B0E-4EFD-94EE-483C22952CD7@freebsd.org>
In-Reply-To: <20190717074243.GA65665@hell.ukr.net>
References:  <1562579483.67527000.24rw4xi5@frv39.fwdcdn.com> <32FD061B-245C-41D2-81DE-1B4756A7173D@freebsd.org> <1562591379.369129000.gpmxvurq@frv39.fwdcdn.com> <DF65CA7F-B5FC-499D-B053-0531596D230C@freebsd.org> <1562599181.734953000.1l9a1d23@frv39.fwdcdn.com> <0C475A01-9BCD-4E4A-9731-09AB919CA9BE@freebsd.org> <1562676414.933145000.z3zteyqp@frv39.fwdcdn.com> <1E9F3F99-C3E9-44DD-AA70-9B11E19D4769@freebsd.org> <20190717074243.GA65665@hell.ukr.net>

next in thread | previous in thread | raw e-mail | index | archive | help
> On 17. Jul 2019, at 09:42, Vitalij Satanivskij <satan@ukr.net> wrote:
>=20
>=20
>=20
> Hello.=20
>=20
> Is there any changes about this problem
Please find a patch in https://reviews.freebsd.org/D20980

If possible, please test and report.

Best regards
Michael
>=20
>=20
> I'm using FreeBSD 12 on my desktop and can confirm problem occur with =
some hosts.
>=20
>=20
>=20
> Michael Tuexen wrote:
> MT>=20
> MT>=20
> MT> > On 9. Jul 2019, at 14:58, Paul <devgs@ukr.net> wrote:
> MT> >=20
> MT> > Hi Michael,
> MT> >=20
> MT> > 9 July 2019, 15:34:29, by "Michael Tuexen" <tuexen@freebsd.org>:
> MT> >=20
> MT> >>=20
> MT> >>=20
> MT> >>> On 8. Jul 2019, at 17:22, Paul <devgs@ukr.net> wrote:
> MT> >>>=20
> MT> >>>=20
> MT> >>>=20
> MT> >>> 8 July 2019, 17:12:21, by "Michael Tuexen" =
<tuexen@freebsd.org>:
> MT> >>>=20
> MT> >>>>> On 8. Jul 2019, at 15:24, Paul <devgs@ukr.net> wrote:
> MT> >>>>>=20
> MT> >>>>> Hi Michael,
> MT> >>>>>=20
> MT> >>>>> 8 July 2019, 15:53:15, by "Michael Tuexen" =
<tuexen@freebsd.org>:
> MT> >>>>>=20
> MT> >>>>>>> On 8. Jul 2019, at 12:37, Paul <devgs@ukr.net> wrote:
> MT> >>>>>>>=20
> MT> >>>>>>> Hi team,
> MT> >>>>>>>=20
> MT> >>>>>>> Recently we had an upgrade to 12 Stable. Immediately =
after, we have started=20
> MT> >>>>>>> seeing some strange connection establishment timeouts to =
some fixed number
> MT> >>>>>>> of external (world) hosts. The issue was persistent and =
easy to reproduce.
> MT> >>>>>>> Thanks to a patience and dedication of our system engineer =
we have tracked =20
> MT> >>>>>>> this issue down to a specific commit:
> MT> >>>>>>>=20
> MT> >>>>>>> =
https://svnweb.freebsd.org/base?view=3Drevision&revision=3D338053
> MT> >>>>>>>=20
> MT> >>>>>>> This patch was also back-ported into 11 Stable:
> MT> >>>>>>>=20
> MT> >>>>>>> =
https://svnweb.freebsd.org/base?view=3Drevision&revision=3D348435
> MT> >>>>>>>=20
> MT> >>>>>>> Among other things this patch changes the timestamp =
allocation strategy,
> MT> >>>>>>> by introducing a deterministic randomness via a hash =
function that takes
> MT> >>>>>>> into account a random key as well as source address, =
source port, dest
> MT> >>>>>>> address and dest port. As the result, timestamp offsets of =
different
> MT> >>>>>>> tuples (SA,SP,DA,DP) will be wildly different and will =
jump from small=20
> MT> >>>>>>> to large numbers and back, as long as something in the =
tuple changes.
> MT> >>>>>> Hi Paul,
> MT> >>>>>>=20
> MT> >>>>>> this is correct.
> MT> >>>>>>=20
> MT> >>>>>> Please note that the same happens with the old method, if =
two hosts with
> MT> >>>>>> different uptimes are bind a consumer grade NAT.
> MT> >>>>>=20
> MT> >>>>> If NAT does not replace timestamps then yes, it should be =
the case.
> MT> >>>>>=20
> MT> >>>>>>>=20
> MT> >>>>>>> After performing various tests of hosts that produce the =
above mentioned=20
> MT> >>>>>>> issue we came to conclusion that there are some =
interesting implementations=20
> MT> >>>>>>> that drop SYN packets with timestamps smaller  than the =
largest timestamp=20
> MT> >>>>>>> value from streams of all recent or current connections =
from a specific=20
> MT> >>>>>>> address. This looks as some kind of SYN flood protection.
> MT> >>>>>> This also breaks multiple hosts with different uptimes =
behind a consumer
> MT> >>>>>> level NAT talking to such a server.
> MT> >>>>>>>=20
> MT> >>>>>>> To ensure that each external host is not going to see a =
wild jumps of=20
> MT> >>>>>>> timestamp values I propose a patch that removes ports from =
the equation
> MT> >>>>>>> all together, when calculating the timestamp offset:
> MT> >>>>>>>=20
> MT> >>>>>>> Index: sys/netinet/tcp_subr.c
> MT> >>>>>>> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> MT> >>>>>>> --- sys/netinet/tcp_subr.c	(revision 348435)
> MT> >>>>>>> +++ sys/netinet/tcp_subr.c	(working copy)
> MT> >>>>>>> @@ -2224,7 +2224,22 @@
> MT> >>>>>>> uint32_t
> MT> >>>>>>> tcp_new_ts_offset(struct in_conninfo *inc)
> MT> >>>>>>> {
> MT> >>>>>>> -	return (tcp_keyed_hash(inc, V_ts_offset_secret));
> MT> >>>>>>> +        /*=20
> MT> >>>>>>> +         * Some implementations show a strange behaviour =
when a wildly random=20
> MT> >>>>>>> +         * timestamps allocated for different streams. It =
seems that only the
> MT> >>>>>>> +         * SYN packets are affected. Observed =
implementations drop SYN packets
> MT> >>>>>>> +         * with timestamps smaller than the largest =
timestamp value of all=20
> MT> >>>>>>> +         * recent or current connections from specific a =
address. To mitigate=20
> MT> >>>>>>> +         * this we are going to ensure that each host =
will always observe=20
> MT> >>>>>>> +         * timestamps as increasing no matter the stream: =
by dropping ports
> MT> >>>>>>> +         * from the equation.
> MT> >>>>>>> +         */=20
> MT> >>>>>>> +        struct in_conninfo inc_copy =3D *inc;
> MT> >>>>>>> +
> MT> >>>>>>> +        inc_copy.inc_fport =3D 0;
> MT> >>>>>>> +        inc_copy.inc_lport =3D 0;
> MT> >>>>>>> +
> MT> >>>>>>> +	return (tcp_keyed_hash(&inc_copy, V_ts_offset_secret));
> MT> >>>>>>> }
> MT> >>>>>>>=20
> MT> >>>>>>> /*
> MT> >>>>>>>=20
> MT> >>>>>>> In any case, the solution of the uptime leak, implemented =
in rev338053 is=20
> MT> >>>>>>> not going to suffer, because a supposed attacker is =
currently able to use=20
> MT> >>>>>>> any fixed values of SP and DP, albeit not 0, anyway, to =
remove them out=20
> MT> >>>>>>> of the equation.
> MT> >>>>>> Can you describe how a peer can compute the uptime from two =
observed timestamps?
> MT> >>>>>> I don't see how you can do that...
> MT> >>>>>=20
> MT> >>>>> Supposed attacker could run a script that continuously =
monitors timestamps,
> MT> >>>>> for example via a periodic TCP connection from a fixed local =
port (eg 12345)=20
> MT> >>>>> and a fixed local address to the fixed victim's address and =
port (eg 80).
> MT> >>>>> Whenever large discrepancy is observed, attacker can assume =
that reboot has=20
> MT> >>>>> happened (due to V_ts_offset_secret re-generation), hence =
the received=20
> MT> >>>>> timestamp is considered an approximate point of reboot from =
which the uptime
> MT> >>>>> can be calculated, until the next reboot and so on.
> MT> >>>> Ahh, I see. The patch we are talking about is not intended to =
protect against
> MT> >>>> continuous monitoring, which is something you can always do. =
You could even
> MT> >>>> watch for service availability and detect reboots. A change =
of the local key
> MT> >>>> would also look similar to a reboot without a temporary loss =
of connectivity.
> MT> >>>>=20
> MT> >>>> Thanks for the clarification.
> MT> >>>>>=20
> MT> >>>>>>>=20
> MT> >>>>>>> There is the list of example hosts that we were able to =
reproduce the=20
> MT> >>>>>>> issue with:
> MT> >>>>>>>=20
> MT> >>>>>>> curl -v http://88.99.60.171:80
> MT> >>>>>>> curl -v http://163.172.71.252:80
> MT> >>>>>>> curl -v http://5.9.242.150:80
> MT> >>>>>>> curl -v https://185.134.205.105:443
> MT> >>>>>>> curl -v https://136.243.1.231:443
> MT> >>>>>>> curl -v https://144.76.196.4:443
> MT> >>>>>>> curl -v http://94.127.191.194:80
> MT> >>>>>>>=20
> MT> >>>>>>> To reproduce, call curl repeatedly with a same URL some =
number of times.=20
> MT> >>>>>>> You are going  to see some of the requests stuck in=20
> MT> >>>>>>> `*    Trying XXX.XXX.XXX.XXX...`
> MT> >>>>>>>=20
> MT> >>>>>>> For some reason, the easiest way to reproduce the issue is =
with nc:
> MT> >>>>>>>=20
> MT> >>>>>>> $ echo "foooooo" | nc -v 88.99.60.171 80
> MT> >>>>>>>=20
> MT> >>>>>>> Only a few such calls are required until one of them is =
stuck on connect():
> MT> >>>>>>> issuing SYN packets with an exponential backoff.
> MT> >>>>>> Thanks for providing an end-point to test with. I'll take a =
look.
> MT> >>>>>> Just to be clear: You are running a FreeBSD client against =
one of the above
> MT> >>>>>> servers and experience the problem with the new timestamp =
computations.
> MT> >>>>>>=20
> MT> >>>>>> You are not running arbitrary clients against a FreeBSD =
server...
> MT> >>>>>=20
> MT> >>>>> We are talking about FreeBSD being the client. Peers that =
yield this unwanted
> MT> >>>>> behaviour are unknown. Little bit of tinkering showed that =
some of them run=20
> MT> >>>>> Debian:
> MT> >>>>>=20
> MT> >>>>> telnet 88.99.60.171 22
> MT> >>>>> Trying 88.99.60.171...
> MT> >>>>> Connected to 88.99.60.171.
> MT> >>>>> Escape character is '^]'.
> MT> >>>>> SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u3
> MT> >>>> Also some are hosted by Hetzner, but not all. I'll will look =
into
> MT> >>>> this tomorrow, since I'm on a deadline today (well it is 2am =
tomorrow
> MT> >>>> morning, to be precise)...
> MT> >>>=20
> MT> >>> Thanks a lot, I would appreciate that.
> MT> >> Hi Paul,
> MT> >>=20
> MT> >> I have looked into this.
> MT> >>=20
> MT> >> * The FreeBSD behaviour is the one which is specified in the =
last bullet item
> MT> >>  in https://tools.ietf.org/html/rfc7323#section-5.4
> MT> >>  It is also the one, which is RECOMMENDED in
> MT> >>  https://tools.ietf.org/html/rfc7323#section-7.1=20
> MT> >>=20
> MT> >> * My NAT box (a popular one in Germany) does NOT rewrite TCP =
timestamps.
> MT> >>=20
> MT> >> This means that the host you are referring to have some sort of =
protection,
> MT> >> which makes incorrect assumptions. It will also break multiple =
hosts behind
> MT> >> a NAT.
> MT> >>=20
> MT> >> I can run
> MT> >> curl -v http://88.99.60.171:80
> MT> >> in a loop without any problems from a FreeBSD head system. I =
tested 1000
> MT> >> iterations or so. The TS.val is jumping up and down as =
expected.
> MT> >> I'm wondering why you are observing errors in this case, too.
> MT> >>=20
> MT> >> However, doing something like
> MT> >> echo "foooooo" | nc -v 88.99.60.171 80
> MT> >> triggers the problem.
> MT> >>=20
> MT> >> So I think there is some functionality (in a middlebox or =
running on the host),
> MT> >> which incorrectly assume monotonic timestamps between multiple =
TCP connections
> MT> >> coming from the same IP address, but only in case of errors at =
the application layer.
> MT> >=20
> MT> > Yeah, exactly, some hosts seem to enable this only in case of an =
error in HTTP
> MT> > communication (some smart proxy?). However, there are some that =
behave this way
> MT> > regardless of errors, for example these:
> MT> >=20
> MT> > curl -v https://185.134.205.105:443
> MT> > curl -v https://136.243.1.231:443
> MT> Wireshark sees an Encrypted Alert in both cases. So I guess this =
is another indication
> MT> of "error at the application layer".
> MT> >=20
> MT> >>=20
> MT> >> Do you have any insights whether the hosts you are listed share =
something in
> MT> >> common. Some of them are hosted by Hetzner, but not all.
> MT> >=20
> MT> > Nope. A whole set of endpoints that we have detected so far is =
pretty diverse,
> MT> > containing a lot of different locations geographically, as well =
as different
> MT> > hosters.
> MT> OK. Thanks for the clarification.
> MT> >=20
> MT> >>=20
> MT> >> I think in general, it is the correct thing to include the port =
numbers in
> MT> >> the offset computation. We might add a sysctl variable to =
control the inclusion.
> MT> >> This would allow interworking with broken middleboxes.
> MT> >=20
> MT> > Yeah, I completely agree that these rare cases should not =
dictate the implementation.
> MT> > But an ability to enable a work-around via sysctl would be =
greatly appreciated.
> MT> > Currently we are unable to roll-out the upgrade across all =
servers because of this
> MT> > issue: even though it happens not so often, a lot of requests =
from our users=20
> MT> > get stuck or fail all together. For example, a host =
185.134.205.105 is a kind of
> MT> > social network that our proxy servers connect to so securely =
access to content,
> MT> > such as images, on behalf of our users.
> MT> >=20
> MT> >>=20
> MT> >> Please note, this does not fix the case of multiple clients =
behind a NAT.
> MT> >=20
> MT> > Yeah, that's true. Fortunately we don't use NAT.
> MT> >=20
> MT> >>=20
> MT> >> I'm also trying to figure out how and why Linux and Windows are =
handling this.
> MT> >=20
> MT> > Thanks for bothering!
> MT> Will let you know what I figure out.
> MT>=20
> MT> Best regards
> MT> Michael
> MT> >=20
> MT> >>=20
> MT> >> Best regards
> MT> >> Michael
> MT> >>=20
> MT> >>>=20
> MT> >>>>=20
> MT> >>>> Best regards
> MT> >>>> Michael=20
> MT> >>>>>=20
> MT> >>>>>=20
> MT> >>>>>>=20
> MT> >>>>>> Best regards
> MT> >>>>>> Michael
> MT> >>>>>>=20
> MT> >>>>>>=20
> MT> >>>>=20
> MT> >>>>=20
> MT> >>=20
> MT> >>=20
> MT>=20
> MT> _______________________________________________
> MT> freebsd-net@freebsd.org mailing list
> MT> https://lists.freebsd.org/mailman/listinfo/freebsd-net
> MT> To unsubscribe, send any mail to =
"freebsd-net-unsubscribe@freebsd.org"
> _______________________________________________
> freebsd-net@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B7BD397D-1B0E-4EFD-94EE-483C22952CD7>