diff -Naur openvpn-2.4.1.orig/doc/openvpn.8 openvpn-2.4.1/doc/openvpn.8
--- openvpn-2.4.1.orig/doc/openvpn.8	2017-03-22 16:34:21.000000000 +0100
+++ openvpn-2.4.1/doc/openvpn.8	2017-03-30 12:11:58.000000000 +0200
@@ -34,7 +34,7 @@
 .\" .ft -- normal face
 .\" .in +|-{n} -- indent
 .\"
-.TH openvpn 8 "25 August 2016"
+.TH openvpn 8 "28 March 2017"
 .\"*********************************************************
 .SH NAME
 openvpn \- secure IP tunnel daemon.
@@ -4919,11 +4919,19 @@
 packets sent and received (disabled by default).
 .\"*********************************************************
 .TP
-.B \-\-reneg\-sec n
+.B \-\-reneg\-sec n [random]
 Renegotiate data channel key after
 .B n
 seconds (default=3600).
 
+If the optional
+.B random
+parameter is specified, a per session pseudo-random component in the range of
+.B 1 ... random
+is added to the
+.B n
+seconds above (default=0).
+
 When using dual-factor authentication, note that this default value may
 cause the end user to be challenged to reauthorize once per hour.
 
diff -Naur openvpn-2.4.1.orig/src/openvpn/init.c openvpn-2.4.1/src/openvpn/init.c
--- openvpn-2.4.1.orig/src/openvpn/init.c	2017-03-22 16:34:24.000000000 +0100
+++ openvpn-2.4.1/src/openvpn/init.c	2017-03-30 11:52:07.000000000 +0200
@@ -2592,6 +2592,10 @@
     to.renegotiate_bytes = options->renegotiate_bytes;
     to.renegotiate_packets = options->renegotiate_packets;
     to.renegotiate_seconds = options->renegotiate_seconds;
+    if (options->renegotiate_seconds_random)
+    {
+        to.renegotiate_seconds += max_int((int)(get_random() % options->renegotiate_seconds_random) + 1, 1);
+    }
     to.single_session = options->single_session;
     to.mode = options->mode;
     to.pull = options->pull;
diff -Naur openvpn-2.4.1.orig/src/openvpn/options.c openvpn-2.4.1/src/openvpn/options.c
--- openvpn-2.4.1.orig/src/openvpn/options.c	2017-03-22 16:34:24.000000000 +0100
+++ openvpn-2.4.1/src/openvpn/options.c	2017-03-30 12:13:41.000000000 +0200
@@ -603,7 +603,9 @@
     "                  if no ACK from remote within n seconds (default=%d).\n"
     "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
     "--reneg-pkts n  : Renegotiate data chan. key after n packets sent and recvd.\n"
-    "--reneg-sec n   : Renegotiate data chan. key after n seconds (default=%d).\n"
+    "--reneg-sec n [r] : Renegotiate data chan. key after n seconds (default=%d)\n"
+    "                  and if r is specified, add a per session pseudo-random\n"
+    "                  component in the range of 1 ... r to n (default=%d).\n"
     "--hand-window n : Data channel key exchange must finalize within n seconds\n"
     "                  of handshake initiation by any peer (default=%d).\n"
     "--tran-window n : Transition window -- old key can live this many seconds\n"
@@ -1773,6 +1775,7 @@
     SHOW_INT(renegotiate_bytes);
     SHOW_INT(renegotiate_packets);
     SHOW_INT(renegotiate_seconds);
+    SHOW_INT(renegotiate_seconds_random);
 
     SHOW_INT(handshake_window);
     SHOW_INT(transition_window);
@@ -2741,6 +2744,7 @@
         MUST_BE_UNDEF(renegotiate_bytes);
         MUST_BE_UNDEF(renegotiate_packets);
         MUST_BE_UNDEF(renegotiate_seconds);
+        MUST_BE_UNDEF(renegotiate_seconds_random);
         MUST_BE_UNDEF(handshake_window);
         MUST_BE_UNDEF(transition_window);
         MUST_BE_UNDEF(tls_auth_file);
@@ -4091,6 +4095,7 @@
             o.authname, o.ciphername,
             o.replay_window, o.replay_time,
             o.tls_timeout, o.renegotiate_seconds,
+            o.renegotiate_seconds_random,
             o.handshake_window, o.transition_window);
 #else  /* ifdef ENABLE_CRYPTO */
     fprintf(fp, usage_message,
@@ -7983,10 +7988,14 @@
         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
         options->renegotiate_packets = positive_atoi(p[1]);
     }
-    else if (streq(p[0], "reneg-sec") && p[1] && !p[2])
+    else if (streq(p[0], "reneg-sec") && p[1] && !p[3])
     {
         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
         options->renegotiate_seconds = positive_atoi(p[1]);
+        if (p[2])
+        {
+            options->renegotiate_seconds_random = positive_atoi(p[2]);
+        }
     }
     else if (streq(p[0], "hand-window") && p[1] && !p[2])
     {
diff -Naur openvpn-2.4.1.orig/src/openvpn/options.h openvpn-2.4.1/src/openvpn/options.h
--- openvpn-2.4.1.orig/src/openvpn/options.h	2017-03-22 16:34:24.000000000 +0100
+++ openvpn-2.4.1/src/openvpn/options.h	2017-03-29 10:20:27.000000000 +0200
@@ -545,6 +545,7 @@
     int renegotiate_bytes;
     int renegotiate_packets;
     int renegotiate_seconds;
+    int renegotiate_seconds_random;
 
     /* Data channel key handshake must finalize
      * within n seconds of handshake initiation. */
diff -Naur openvpn-2.4.1.orig/src/openvpn/ssl.c openvpn-2.4.1/src/openvpn/ssl.c
--- openvpn-2.4.1.orig/src/openvpn/ssl.c	2017-03-22 16:34:24.000000000 +0100
+++ openvpn-2.4.1/src/openvpn/ssl.c	2017-03-29 10:20:27.000000000 +0200
@@ -2719,8 +2719,8 @@
             || (packet_id_close_to_wrapping(&ks->crypto_options.packet_id.send))))
     {
         msg(D_TLS_DEBUG_LOW,
-            "TLS: soft reset sec=%d bytes=" counter_format "/%d pkts=" counter_format "/%d",
-            (int)(ks->established + session->opt->renegotiate_seconds - now),
+            "TLS: soft reset sec=%d/%d bytes=" counter_format "/%d pkts=" counter_format "/%d",
+            (int)(now - ks->established), (int)session->opt->renegotiate_seconds,
             ks->n_bytes, session->opt->renegotiate_bytes,
             ks->n_packets, session->opt->renegotiate_packets);
         key_state_soft_reset(session);
