So, lynis informs me that I should unset net.ipv4.tcp_timestamps. I know that's a bad thing because an attacker could figure out which updates that require restarting the machine I haven't applied, or they could use it to figure out my update schedule and try to attack in the brief interval during which the machine's restarting but before the firewall comes online, or something else I haven't thought of.

I understand it's not ideal.

However, according to RFC 1323 (and this):

The timestamps are used for two distinct mechanisms: RTTM (Round Trip Time Measurement) and PAWS (Protect Against Wrapped Sequences)

Those also seem like nice, useful things to have. That having been said, IIRC from my networking classes that RTTM method definitely isn't necessary for determining RTT, and TCP's sliding window makes sequence wraparound issues unlikely, but since this isn't one of the joke RFCs I'm assuming they had a good reason for proposing these things and implementors had a good reason for implementing them.

Are there any (likely) disadvantages / negative usability or security implications to disabling this feature?

Additionally, is there any way I can both have and eat my cake (by, for example, telling the kernel to initialize with a random value and introduce jitter into the period of the timestamp updates, or initializing it with some of the bits of the system clock, so they can't use a sudden, large change in timestamp to tell a reboot recently occurred)?

  • 2
    Related: stackoverflow.com/questions/7880383/… – StackzOfZtuff Jan 26 '16 at 16:57
  • @StackzOfZtuff Thanks! That answers pretty much all of my question. I did try looking for something like that but... apparently my research abilities need work. – Parthian Shot Jan 26 '16 at 17:09
  • Does your firewall not establish before your network? Seems a bit of a flaw if that is so. – SilverlightFox Jan 27 '16 at 9:59
  • 1
    That's the default on most systems. Not mine, specifically. I agree it's a bad default. – Parthian Shot Jan 27 '16 at 18:37
  • In modern Linux (i.e. Ubuntu 16, 18) changing the value of net.ipv4.tcp_timestamps has no effect. The documentation at kernel.org/doc/Documentation/networking/ip-sysctl.txt is incorrect for modern kernels. – Aiuti Marble Dec 11 '18 at 17:28

The disadvantage would be that the TCP sequence could wrap. This is a risk on very high speed networks. You can randomize the initial timestamp, however, just as you asked. It's a very simple patch, so any rejects will be trivial to fix. It requires the grsecurity patchset to already be applied.

From https://grsecurity.net/~spender/random_timestamp.diff:

diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
index 3abaf02..700e56c 100644
--- a/grsecurity/Kconfig
+++ b/grsecurity/Kconfig
@@ -925,6 +925,16 @@ config GRKERNSEC_RANDNET
      here.  Saying Y here has a similar effect as modifying

+   bool "Add random offset to TCP timestamps"
+   default y if GRKERNSEC_CONFIG_AUTO
+   help
+     If you say Y here, a simple change will be made to TCP timestamp
+     behavior that will prevent the system from leaking the jiffies
+     value remotely to an attacker who has not been persistently
+     monitoring the system since boot.  The jiffies value can be used
+     to remotely determine system uptime.
    bool "TCP/UDP blackhole and LAST_ACK DoS prevention"
    default y if GRKERNSEC_CONFIG_AUTO
diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c
index ae6c028..c7dbe97d 100644
--- a/grsecurity/grsec_init.c
+++ b/grsecurity/grsec_init.c
@@ -7,6 +7,11 @@
 #include <linux/percpu.h>
 #include <linux/module.h>

+__u32 random_timestamp_base __latent_entropy;
 int grsec_enable_ptrace_readexec;
 int grsec_enable_setxid;
 int grsec_enable_symlinkown;
diff --git a/include/net/sock.h b/include/net/sock.h
index b2948c0..ccbeda9 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2296,4 +2296,8 @@ extern int sysctl_optmem_max;
 extern __u32 sysctl_wmem_default;
 extern __u32 sysctl_rmem_default;

+extern __u32 random_timestamp_base;
 #endif /* _SOCK_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 44a58b0..fcdca06 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -684,7 +684,11 @@ void tcp_send_window_probe(struct sock *sk);
  * to use only the low 32-bits of jiffies and hide the ugly
  * casts with the following macro.
+#define tcp_time_stamp     ((__u32)(jiffies) + random_timestamp_base)
 #define tcp_time_stamp     ((__u32)(jiffies))

 #define tcp_flag_byte(th) (((u_int8_t *)th)[13])

diff --git a/net/core/dev.c b/net/core/dev.c
index f3e28ec..8b1cf12 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6986,6 +6986,10 @@ static int __init net_dev_init(void)


+   random_timestamp_base += prandom_u32();
    if (dev_proc_init())
        goto out;

Note that newer kernels have integrated something similar to this in the time since this was posted.


linux: no more kernel patches.

On newer kernels, you can use net.ipv4.tcp_timestamps = 1

Enable timestamps as defined in RFC1323 and use random offset for each connection rather than only using the current time

They choose to change the semantic: in old kernels, tcp_timestamps = 1 enables timestamps backed by time.

Now to get the old behaviour, you have to set tcp_timestamps = 2

I think they choose to change the default behaviour because there isn't any adverse effect on normal users.

  • I'm upvoting, but maybe the answer could be improved to state more clearly that newer kernels (since when?) avoid the security issue by default with the timestamp randomization. – Juan Calero Aug 17 '20 at 13:21

Another advantage is that, according to RedHat, it reduces performance spikes associated with the timestamp generation.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.