Proposal: Add tcptimestamp disabling script for running on host

Situation:

  • On a GNU/Linux system running trusted Free Software, no information is leaked without the users consent. There are two caveats which are a result of misguided standards specs and design decisions.

  • The 2 known ways a host’s clock was/is leaked to the clearnet are through TLS handshakes made by software running on the host and and TCP connection made by default.

  • Recent work was made in this area due to more vigilance by privacy software engineers in the TorProject. At the moment work has been done by TPO member Nick to eliminate ssl timestamp leaks both in upstream crypto libraries OpenSSL and NSS (used in Firefox) and in the IETF standard itself that encouraged this harmful practice.
    If unsure about the availability of this patch in one’s OS, as a workaround its best to simply not to connect to the clearnet from there. There are many compelling reasons not to do so out of a vm as discussed in my blog post.
    However there are reasons where its still necessary to do so such as updating the system. This leaves one more leak open.

  • This leaves the TCP timestamp which is enabled in the Linux kernel by default for some esoteric performance reasons. TCP timestamps serve to reveal how many unique devices are running behind a router, the uptime of the system and the host’s time down to the millisecond. Downright dangerous and unnecessary information.

The clock skew attack for deanonymization becomes a problem only if the adversary has the host’s clock time to compare to the one in the vm. If we deprive them from the former, that renders this attack useless.

At this point whether NTP is enabled or not on the host is irrelevant as a skew should not be readable. Whether a secure distributed torclock ever becomes a reality is far fetched and not needed if the underlying system is configured safely.

Recommendation:
Distribute a simple script that disables TCP timestamps for Linux host’s with the qcow2 images under a : “anonymity enhancements” directory.

References:

PROPOSAL 1:

Declare that implementations MAY replace gmt_unix_time either with
four more random bytes, or four bytes of zeroes.

Rationale:

  • Some implementations (like TorBrowser) are already doing this
    in practice.

  • It’s sensible and simple. Implementors are quite unlikely to
    mess it up.


MAY in this context means not mandated as per the IETF draft and providing a zeroed out timestamp instead.

Sorry about my late reply. I am a programmer working on the NSS crypto libraries. While reviewing recent changes to NSS, I noticed that Nick's proposal 1 has been implemented in the OpenSSL and NSS source code repositories, which led me to this old email thread.

https://mailman.boum.org/pipermail/tails-dev/2013-December/004522.html

Yes. And due to a Tor issue (TLS itself), the absolute clock on the system is also leaked in the handshake. Nick has been working on fixing this - both in the IETF working group on TLS, in patches for OpenSSL and in other places, I think. When Nick finishes killing the gmt time leak in TLS, we'll still have one left in Tails: the TCP timestamp itself... :(

Discussion:

As per http://www.tmltechnologies.com/html-2012/index.php/linux-rescue-kits/82-secret/91-disable-tcp-timestamps-on-linux its done like so:

Disable TCP timestamps on Linux

It is possible to estimate the current uptime of a Linux machine remotely. It’s preferable to disable TCP timestamps on your systems. The less information attackers can get, the better of you are.
Sysctl

Todynamically disable TCPtime stamping,run the following command:

root@thunderchicken:~# echo 0 > /proc/sys/net/ipv4/tcp_timestamps

To make that change permenant though, you need to add the following line to /etc/sysctl.conf:

net.ipv4.tcp_timestamps = 0

IPTables

To be on the safe side, add the following 2 lines to your firewall script:

iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

Whonix does the very first step and so does TAILS. question is wouldn’t it be beneficial to also add the iptables rules too?

What about ipv6 equivalent rules for future proofing this setup?

Its accomplished by using ip6tables and additionally enforcing echo 0 > /proc/sys/net/ipv6/tcp_timestamps

Whonix does the very first step and so does TAILS. question is wouldn't it be beneficial to also add the iptables rules too?
Incoming: Better covering that in Whonix 9 (no big issue in Whonix 8 either): https://github.com/Whonix/whonix-gw-firewall/blob/master/usr/bin/whonix_firewall#L251

Outgoing: I don’t know why it would be useful to block outgoing tcp timestamp requests since only Tor is allowed to connect to outside targets.

See also:
https://www.mail-archive.com/tails-dev@boum.org/msg06492.html

What about ipv6 equivalent rules for future proofing this setup?
We don't allow IPv6 traffic using firewall/iptables at the moment anyway and creating a fully featured IPv6 firewall looks like a huge task I am not even thinking about at this stage.
Its accomplished by using ip6tables and additionally enforcing [b]echo 0 > /proc/sys/net/ipv6/tcp_timestamps[/b]
Could be maybe added here: https://github.com/Whonix/tcp-timestamps-disable/blob/master/etc/sysctl.d/tcp_timestamps.conf

There is no such “file” /proc/sys/net/ipv6/tcp_timestamps and apparently there is a setting net.ipv4.tcp_timestamps=0 but no setting net.ipv6.tcp_timestamps=0. (Also see: https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt)

Could be maybe added here: https://github.com/Whonix/tcp-timestamps-disable/blob/master/etc/sysctl.d/tcp_timestamps.conf

There is no such “file” /proc/sys/net/ipv6/tcp_timestamps and apparently there is a setting net.ipv4.tcp_timestamps=0 but no setting net.ipv6.tcp_timestamps=0. (Also see: https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt)

Seems that ipv4 tcp settings apply to ipv6 as well:

/proc/sys/net/ipv6/* Variables:

IPv6 has no global variables such as tcp_. tcp_ settings under ipv4/ also
apply to IPv6 [XXX?].

We don't allow IPv6 traffic using firewall/iptables at the moment anyway and creating a fully featured IPv6 firewall looks like a huge task I am not even thinking about at this stage.

You are right, for Whonix it wouldn’t make sense for this to be supported yet however Both the incoming and outgoing are relevant for a script that sets the host’s firewall settings to safe values as per my first post’s suggestion.

There are two things here. TCP timestamps and ICMP timestamps.

This will be done when Whonix Host Additions will be implemented:
https://github.com/Whonix/Whonix/issues/39

(It will initially probably be a meta package called whonix-host, that can be installed on Debian [perhaps on derivatives as well], that will depend on the tcp-timestamps-disable package, that will come with a firewall (perhaps using parts of corridor to allow only Tor traffic) and block ICMP timestamps. [And maybe that whonix-host package will later turn into a Whonix host operating system.])

That’s excellent. Can you please consider releasing this specific nd very important fix, also as a standalone bash script so those of us who don’t use Debian as a host can benefit too?

Everything is important. As said in another place there is stuff that may have disastrous effects that is not being worked on either, for example https://github.com/Whonix/Whonix/issues/125.

I’ll implement it when I get to work on the Whonix Host Additions ticket. I don’t know if I ever will be able to support software I maintain on Debian + derivatives + other distributions at the same time. Not there yet. I think best I can do is create a fine implementation for Debian and then hope/rely on maintainers of other distributions to port the software to their distributions.

Here is what have in mind. It’s very primitive so please and help me with this as I would like to commit it for distribution with libvirt files. I don’t want to use variables or anything fancy:

#!/bin/bash

## This file is part of Whonix.
## Copyright (C) 2012 - 2014 Patrick Schleizer <adrelanos@riseup.net>
## See the file COPYING for copying conditions.

## TCP/ICMP Timestamp disabling script for GNU/Linux Hosts.

## This script should be run as root.

set -x

echo "This script will now disable TCP/ICMP Timestamping preventing host clock leaks"

echo 0 > /proc/sys/net/ipv4/tcp_timestamps

echo  net.ipv4.tcp_timestamps = 0 > /etc/sysctl.conf

iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

ip6tables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
ip6tables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

It needs a root check and iptables rules need to be made permanent (after reboot) and be set before networking is getting up.

I added the root check code, please see if it makes sense. making iptables rules permanent differs between distro families. I will dedicate a separate script to support the two main ones in the Linux community.

References:

[code]#!/bin/bash

This file is part of Whonix.

Copyright (C) 2012 - 2014 Patrick Schleizer adrelanos@riseup.net

See the file COPYING for copying conditions.

TCP/ICMP Timestamp disabling script for Debian/Ubuntu GNU/Linux Hosts.

This script should be run as root.

set -x

SUDO=‘’
if (( $EUID != 0 )); then
SUDO=‘sudo’
fi
$SUDO a_command

echo “This script will now disable TCP/ICMP Timestamping to prevent clock leaks on Debian/Ubuntu Hosts.”

echo 0 > /proc/sys/net/ipv4/tcp_timestamps

echo net.ipv4.tcp_timestamps = 0 > /etc/sysctl.conf

iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

ip6tables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
ip6tables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

apt-get update
apt-get install iptables-persistent

iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

[/code]

RHEL/CentOS Hosts

[code]#!/bin/bash

This file is part of Whonix.

Copyright (C) 2012 - 2014 Patrick Schleizer adrelanos@riseup.net

See the file COPYING for copying conditions.

TCP/ICMP Timestamp disabling script for RHEL/CentOS GNU/Linux Hosts.

This script should be run as root.

set -x

SUDO=‘’
if (( $EUID != 0 )); then
SUDO=‘sudo’
fi
$SUDO a_command

echo “This script will now disable TCP/ICMP Timestamping to prevent clock leaks on RHEL/CentOS Hosts.”

echo 0 > /proc/sys/net/ipv4/tcp_timestamps

echo net.ipv4.tcp_timestamps = 0 > /etc/sysctl.conf

iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

ip6tables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
ip6tables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

iptables-save > /etc/sysconfig/iptables
ip6tables-save > /etc/sysconfig/ip6tables

service iptables start
chkconfig iptables on
service iptables save

[/code]

I don’t know if it’s useful to invest time into this. I can’t teach how to code, because explaining all the issues requires equally or more time than doing it myself but I don’t even believe this is a clean, right way to solve it.

As proper implementation for ‘best simplicity’* I am planing to provide an apt repository that users can add and then apt-get install these changes. (* still not that user friendly since it still requires using the command line because linux distros don’t really have a user friendly graphical way to add third party repositories and more.)

  • SUDO=‘’" - what?
  • $SUDO a_command - what?
  • shellcheck is your friend
  • quote your variables
  • use sysctl.d to make uninstallation easier
  • handle failures (any command, especially apt-get would fail silently resulting in a half installed state)
  • begs the question on how to uninstall it

I guess this will cause more confusion and support requests than doing it right. There is lots of stuff that could be done on the host but I don’t think it’s a good idea to invest a lot into a hacky solution. What I would like better in meanwhile would be adding it here: Computer Security Education - Whonix

We’ll be disabling leaking TCP timestamps by default on Qubes:

[quote=“HulaHoop, post:8, topic:447”] iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP iptables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP [/quote]

That works.

[quote=“HulaHoop, post:8, topic:447”] ip6tables -A INPUT -p icmp --icmp-type timestamp-request -j DROP ip6tables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP [/quote]

That does not work. It requires…

-p ipv6-icmp

And…

--icmpv6-type

However, the following still does not work.

ip6tables -A INPUT -p ipv6-icmp --icmpv6-type timestamp-request -j DROP
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type timestamp-reply -j DROP

There are no icmpv6-type timestamp-request / timestamp-reply.
Looks like IPv6 does not support ICMP timestamps.
(IPv6 replacement for ICMP timestamp - Network Engineering Stack Exchange)