Session rekeying support in OpenSSH

Darren Tucker dtucker at zip.com.au
Thu May 16 17:08:53 EST 2013


On Wed, May 15, 2013 at 11:37:50AM +1000, Darren Tucker wrote:
> On Mon, May 13, 2013 at 11:40:43PM +1000, Darren Tucker wrote:
> > Looks like it wouldn't be hard to add, but what problem are you trying
> > to solve?
> 
> As usual it wasn't quite as simple as I initially thought, but this adds
> an optional second parameter to RekeyLimit in the client and adds
> RekeyLimit to the server.  Basically you should just be able to add
> "RekeyLimit 1G 1h" to the config files on both the client and server.
> 
> Patch is against -current but should apply to 6.2p1 with some fuzz.

The changes to RekeyLimit have been committed and will be in the 6.3
release.  Here's the same changes against the just-released 6.2p2.

Index: clientloop.c
===================================================================
RCS file: /var/cvs/openssh/clientloop.c,v
retrieving revision 1.237
diff -u -p -r1.237 clientloop.c
--- clientloop.c	9 Jan 2013 04:55:51 -0000	1.237
+++ clientloop.c	16 May 2013 06:46:59 -0000
@@ -583,7 +583,7 @@ client_wait_until_can_do_something(fd_se
 {
 	struct timeval tv, *tvp;
 	int timeout_secs;
-	time_t minwait_secs = 0;
+	time_t minwait_secs = 0, server_alive_time = 0, now = time(NULL);
 	int ret;
 
 	/* Add any selections by the channel mechanism. */
@@ -632,12 +632,16 @@ client_wait_until_can_do_something(fd_se
 	 */
 
 	timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
-	if (options.server_alive_interval > 0 && compat20)
+	if (options.server_alive_interval > 0 && compat20) {
 		timeout_secs = options.server_alive_interval;
+		server_alive_time = now + options.server_alive_interval;
+	}
+	if (options.rekey_interval > 0 && compat20 && !rekeying)
+		timeout_secs = MIN(timeout_secs, packet_get_rekey_timeout());
 	set_control_persist_exit_time();
 	if (control_persist_exit_time > 0) {
 		timeout_secs = MIN(timeout_secs,
-			control_persist_exit_time - time(NULL));
+			control_persist_exit_time - now);
 		if (timeout_secs < 0)
 			timeout_secs = 0;
 	}
@@ -669,8 +673,15 @@ client_wait_until_can_do_something(fd_se
 		snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
 		buffer_append(&stderr_buffer, buf, strlen(buf));
 		quit_pending = 1;
-	} else if (ret == 0)
-		server_alive_check();
+	} else if (ret == 0) {
+		/*
+		 * Timeout.  Could have been either keepalive or rekeying.
+		 * Keepalive we check here, rekeying is checked in clientloop.
+		 */
+		if (server_alive_time != 0 && server_alive_time <= time(NULL))
+			server_alive_check();
+	}
+
 }
 
 static void
Index: monitor.c
===================================================================
RCS file: /var/cvs/openssh/monitor.c,v
retrieving revision 1.155
diff -u -p -r1.155 monitor.c
--- monitor.c	11 Dec 2012 23:44:39 -0000	1.155
+++ monitor.c	16 May 2013 06:46:59 -0000
@@ -1799,6 +1799,10 @@ monitor_apply_keystate(struct monitor *p
 	if (options.compression)
 		mm_init_compression(pmonitor->m_zlib);
 
+	if (options.rekey_limit || options.rekey_interval)
+		packet_set_rekey_limits((u_int32_t)options.rekey_limit,
+		    (time_t)options.rekey_interval);
+
 	/* Network I/O buffers */
 	/* XXX inefficient for large buffers, need: buffer_init_from_string */
 	buffer_clear(packet_get_input());
Index: packet.c
===================================================================
RCS file: /var/cvs/openssh/packet.c,v
retrieving revision 1.188.2.1
diff -u -p -r1.188.2.1 packet.c
--- packet.c	10 May 2013 03:41:34 -0000	1.188.2.1
+++ packet.c	16 May 2013 06:46:59 -0000
@@ -58,6 +58,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <signal.h>
+#include <time.h>
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -165,9 +166,14 @@ struct session_state {
 	Newkeys *newkeys[MODE_MAX];
 	struct packet_state p_read, p_send;
 
+	/* Volume-based rekeying */
 	u_int64_t max_blocks_in, max_blocks_out;
 	u_int32_t rekey_limit;
 
+	/* Time-based rekeying */
+	time_t rekey_interval;	/* how often in seconds */
+	time_t rekey_time;	/* time of last rekeying */
+
 	/* Session key for protocol v1 */
 	u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
 	u_int ssh1_keylen;
@@ -1009,6 +1015,7 @@ packet_send2(void)
 	/* after a NEWKEYS message we can send the complete queue */
 	if (type == SSH2_MSG_NEWKEYS) {
 		active_state->rekeying = 0;
+		active_state->rekey_time = time(NULL);
 		while ((p = TAILQ_FIRST(&active_state->outgoing))) {
 			type = p->type;
 			debug("dequeue packet: %u", type);
@@ -1933,13 +1940,33 @@ packet_need_rekeying(void)
 	    (active_state->max_blocks_out &&
 	        (active_state->p_send.blocks > active_state->max_blocks_out)) ||
 	    (active_state->max_blocks_in &&
-	        (active_state->p_read.blocks > active_state->max_blocks_in));
+	        (active_state->p_read.blocks > active_state->max_blocks_in)) ||
+	    (active_state->rekey_interval != 0 && active_state->rekey_time +
+		 active_state->rekey_interval <= time(NULL));
 }
 
 void
-packet_set_rekey_limit(u_int32_t bytes)
+packet_set_rekey_limits(u_int32_t bytes, time_t seconds)
 {
+	debug3("rekey after %lld bytes, %d seconds", (long long)bytes,
+	    (int)seconds);
 	active_state->rekey_limit = bytes;
+	active_state->rekey_interval = seconds;
+	/*
+	 * We set the time here so that in post-auth privsep slave we count
+	 * from the completion of the authentication.
+	 */
+	active_state->rekey_time = time(NULL);
+}
+
+time_t
+packet_get_rekey_timeout(void)
+{
+	time_t seconds;
+
+	seconds = active_state->rekey_time + active_state->rekey_interval -
+	    time(NULL);
+	return (seconds <= 0 ? 1 : seconds);
 }
 
 void
Index: packet.h
===================================================================
RCS file: /var/cvs/openssh/packet.h,v
retrieving revision 1.60
diff -u -p -r1.60 packet.h
--- packet.h	10 Feb 2012 21:19:21 -0000	1.60
+++ packet.h	16 May 2013 06:46:59 -0000
@@ -115,7 +115,8 @@ do { \
 } while (0)
 
 int	 packet_need_rekeying(void);
-void	 packet_set_rekey_limit(u_int32_t);
+void	 packet_set_rekey_limits(u_int32_t, time_t);
+time_t	 packet_get_rekey_timeout(void);
 
 void	 packet_backup_state(void);
 void	 packet_restore_state(void);
Index: readconf.c
===================================================================
RCS file: /var/cvs/openssh/readconf.c,v
retrieving revision 1.174.6.2
diff -u -p -r1.174.6.2 readconf.c
--- readconf.c	5 Apr 2013 00:18:58 -0000	1.174.6.2
+++ readconf.c	16 May 2013 06:46:59 -0000
@@ -562,39 +562,54 @@ parse_yesnoask:
 	case oRekeyLimit:
 		arg = strdelim(&s);
 		if (!arg || *arg == '\0')
-			fatal("%.200s line %d: Missing argument.", filename, linenum);
-		if (arg[0] < '0' || arg[0] > '9')
-			fatal("%.200s line %d: Bad number.", filename, linenum);
-		orig = val64 = strtoll(arg, &endofnumber, 10);
-		if (arg == endofnumber)
-			fatal("%.200s line %d: Bad number.", filename, linenum);
-		switch (toupper(*endofnumber)) {
-		case '\0':
-			scale = 1;
-			break;
-		case 'K':
-			scale = 1<<10;
-			break;
-		case 'M':
-			scale = 1<<20;
-			break;
-		case 'G':
-			scale = 1<<30;
-			break;
-		default:
-			fatal("%.200s line %d: Invalid RekeyLimit suffix",
-			    filename, linenum);
+			fatal("%.200s line %d: Missing argument.", filename,
+			    linenum);
+		if (strcmp(arg, "default") == 0) {
+			val64 = 0;
+		} else {
+			if (arg[0] < '0' || arg[0] > '9')
+				fatal("%.200s line %d: Bad number.", filename,
+				    linenum);
+			orig = val64 = strtoll(arg, &endofnumber, 10);
+			if (arg == endofnumber)
+				fatal("%.200s line %d: Bad number.", filename,
+			 linenum);
+	 		switch (toupper(*endofnumber)) {
+			case '\0':
+				scale = 1;
+				break;
+			case 'K':
+				scale = 1<<10;
+				break;
+			case 'M':
+				scale = 1<<20;
+				break;
+			case 'G':
+				scale = 1<<30;
+				break;
+			default:
+				fatal("%.200s line %d: Invalid RekeyLimit "
+				    "suffix", filename, linenum);
+			}
+			val64 *= scale;
+			/* detect integer wrap and too-large limits */
+			if ((val64 / scale) != orig || val64 > UINT_MAX)
+				fatal("%.200s line %d: RekeyLimit too large",
+				    filename, linenum);
+			if (val64 != 0 && val64 < 16)
+				fatal("%.200s line %d: RekeyLimit too small",
+				    filename, linenum);
 		}
-		val64 *= scale;
-		/* detect integer wrap and too-large limits */
-		if ((val64 / scale) != orig || val64 > UINT_MAX)
-			fatal("%.200s line %d: RekeyLimit too large",
-			    filename, linenum);
-		if (val64 < 16)
-			fatal("%.200s line %d: RekeyLimit too small",
-			    filename, linenum);
 		if (*activep && options->rekey_limit == -1)
 			options->rekey_limit = (u_int32_t)val64;
+		if (s != NULL) { /* optional rekey interval present */
+			if (strcmp(s, "none") == 0) {
+				(void)strdelim(&s);	/* discard */
+				break;
+			}
+			intptr = &options->rekey_interval;
+			goto parse_time;
+		}
 		break;
 
 	case oIdentityFile:
@@ -1202,6 +1217,7 @@ initialize_options(Options * options)
 	options->no_host_authentication_for_localhost = - 1;
 	options->identities_only = - 1;
 	options->rekey_limit = - 1;
+	options->rekey_interval = -1;
 	options->verify_host_key_dns = -1;
 	options->server_alive_interval = -1;
 	options->server_alive_count_max = -1;
@@ -1339,6 +1355,8 @@ fill_default_options(Options * options)
 		options->enable_ssh_keysign = 0;
 	if (options->rekey_limit == -1)
 		options->rekey_limit = 0;
+	if (options->rekey_interval == -1)
+		options->rekey_interval = 0;
 	if (options->verify_host_key_dns == -1)
 		options->verify_host_key_dns = 0;
 	if (options->server_alive_interval == -1)
Index: readconf.h
===================================================================
RCS file: /var/cvs/openssh/readconf.h,v
retrieving revision 1.83.6.2
diff -u -p -r1.83.6.2 readconf.h
--- readconf.h	5 Apr 2013 00:18:58 -0000	1.83.6.2
+++ readconf.h	16 May 2013 06:46:59 -0000
@@ -110,6 +110,7 @@ typedef struct {
 
 	int	enable_ssh_keysign;
 	int64_t rekey_limit;
+	int	rekey_interval;
 	int	no_host_authentication_for_localhost;
 	int	identities_only;
 	int	server_alive_interval;
Index: servconf.c
===================================================================
RCS file: /var/cvs/openssh/servconf.c,v
retrieving revision 1.231
diff -u -p -r1.231 servconf.c
--- servconf.c	12 Feb 2013 00:02:08 -0000	1.231
+++ servconf.c	16 May 2013 06:46:59 -0000
@@ -20,6 +20,7 @@
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 
+#include <ctype.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <stdio.h>
@@ -110,6 +111,8 @@ initialize_server_options(ServerOptions 
 	options->permit_user_env = -1;
 	options->use_login = -1;
 	options->compression = -1;
+	options->rekey_limit = -1;
+	options->rekey_interval = -1;
 	options->allow_tcp_forwarding = -1;
 	options->allow_agent_forwarding = -1;
 	options->num_allow_users = 0;
@@ -249,6 +252,10 @@ fill_default_server_options(ServerOption
 		options->use_login = 0;
 	if (options->compression == -1)
 		options->compression = COMP_DELAYED;
+	if (options->rekey_limit == -1)
+		options->rekey_limit = 0;
+	if (options->rekey_interval == -1)
+		options->rekey_interval = 0;
 	if (options->allow_tcp_forwarding == -1)
 		options->allow_tcp_forwarding = FORWARD_ALLOW;
 	if (options->allow_agent_forwarding == -1)
@@ -320,7 +327,7 @@ typedef enum {
 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
-	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
+	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
 	sMaxStartups, sMaxAuthTries, sMaxSessions,
@@ -422,6 +429,7 @@ static struct {
 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
 	{ "compression", sCompression, SSHCFG_GLOBAL },
+	{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
@@ -800,14 +808,14 @@ process_server_config_line(ServerOptions
     const char *filename, int linenum, int *activep,
     struct connection_info *connectinfo)
 {
-	char *cp, **charptr, *arg, *p;
-	int cmdline = 0, *intptr, value, value2, n;
+	char *cp, **charptr, *arg, *p, *endofnumber;
+	int cmdline = 0, *intptr, value, value2, n, port, scale;
 	SyslogFacility *log_facility_ptr;
 	LogLevel *log_level_ptr;
 	ServerOpCodes opcode;
-	int port;
 	u_int i, flags = 0;
 	size_t len;
+	long long orig, val64;
 	const struct multistate *multistate_ptr;
 
 	cp = line;
@@ -1118,6 +1126,59 @@ process_server_config_line(ServerOptions
 		multistate_ptr = multistate_compression;
 		goto parse_multistate;
 
+	case sRekeyLimit:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename,
+			    linenum);
+		if (strcmp(arg, "default") == 0) {
+			val64 = 0;
+		} else {
+			if (arg[0] < '0' || arg[0] > '9')
+				fatal("%.200s line %d: Bad number.", filename,
+				    linenum);
+			orig = val64 = strtoll(arg, &endofnumber, 10);
+			if (arg == endofnumber)
+				fatal("%.200s line %d: Bad number.", filename,
+			 linenum);
+	 		switch (toupper(*endofnumber)) {
+			case '\0':
+				scale = 1;
+				break;
+			case 'K':
+				scale = 1<<10;
+				break;
+			case 'M':
+				scale = 1<<20;
+				break;
+			case 'G':
+				scale = 1<<30;
+				break;
+			default:
+				fatal("%.200s line %d: Invalid RekeyLimit "
+				    "suffix", filename, linenum);
+			}
+			val64 *= scale;
+			/* detect integer wrap and too-large limits */
+			if ((val64 / scale) != orig || val64 > UINT_MAX)
+				fatal("%.200s line %d: RekeyLimit too large",
+				    filename, linenum);
+			if (val64 != 0 && val64 < 16)
+				fatal("%.200s line %d: RekeyLimit too small",
+				    filename, linenum);
+		}
+		if (*activep && options->rekey_limit == -1)
+			options->rekey_limit = (u_int32_t)val64;
+		if (cp != NULL) { /* optional rekey interval present */
+			if (strcmp(cp, "none") == 0) {
+				(void)strdelim(&cp);	/* discard */
+				break;
+			}
+			intptr = &options->rekey_interval;
+			goto parse_time;
+		}
+		break;
+
 	case sGatewayPorts:
 		intptr = &options->gateway_ports;
 		multistate_ptr = multistate_gatewayports;
@@ -1718,6 +1779,8 @@ copy_set_server_options(ServerOptions *d
 	M_CP_INTOPT(max_authtries);
 	M_CP_INTOPT(ip_qos_interactive);
 	M_CP_INTOPT(ip_qos_bulk);
+	M_CP_INTOPT(rekey_limit);
+	M_CP_INTOPT(rekey_interval);
 
 	/* See comment in servconf.h */
 	COPY_MATCH_STRING_OPTS();
@@ -2005,6 +2068,8 @@ dump_config(ServerOptions *o)
 
 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
 	printf("%s\n", iptos2str(o->ip_qos_bulk));
+
+	printf("rekeylimit %lld %d\n", o->rekey_limit, o->rekey_interval);
 
 	channel_print_adm_permitted_opens();
 }
Index: servconf.h
===================================================================
RCS file: /var/cvs/openssh/servconf.h,v
retrieving revision 1.99
diff -u -p -r1.99 servconf.h
--- servconf.h	9 Jan 2013 04:56:45 -0000	1.99
+++ servconf.h	16 May 2013 06:46:59 -0000
@@ -176,6 +176,9 @@ typedef struct {
 	char   *authorized_keys_command;
 	char   *authorized_keys_command_user;
 
+	int64_t rekey_limit;
+	int	rekey_interval;
+
 	char   *version_addendum;	/* Appended to SSH banner */
 
 	u_int	num_auth_methods;
Index: serverloop.c
===================================================================
RCS file: /var/cvs/openssh/serverloop.c,v
retrieving revision 1.173
diff -u -p -r1.173 serverloop.c
--- serverloop.c	7 Dec 2012 02:07:47 -0000	1.173
+++ serverloop.c	16 May 2013 06:47:00 -0000
@@ -277,7 +277,7 @@ client_alive_check(void)
  */
 static void
 wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
-    u_int *nallocp, u_int max_time_milliseconds)
+    u_int *nallocp, u_int64_t max_time_milliseconds)
 {
 	struct timeval tv, *tvp;
 	int ret;
@@ -563,7 +563,7 @@ server_loop(pid_t pid, int fdin_arg, int
 	int wait_status;	/* Status returned by wait(). */
 	pid_t wait_pid;		/* pid returned by wait(). */
 	int waiting_termination = 0;	/* Have displayed waiting close message. */
-	u_int max_time_milliseconds;
+	u_int64_t max_time_milliseconds;
 	u_int previous_stdout_buffer_bytes;
 	u_int stdout_buffer_bytes;
 	int type;
@@ -826,6 +826,7 @@ server_loop2(Authctxt *authctxt)
 {
 	fd_set *readset = NULL, *writeset = NULL;
 	int rekeying = 0, max_fd, nalloc = 0;
+	u_int64_t rekey_timeout_ms = 0;
 
 	debug("Entering interactive session for SSH2.");
 
@@ -854,8 +855,13 @@ server_loop2(Authctxt *authctxt)
 
 		if (!rekeying && packet_not_very_much_data_to_write())
 			channel_output_poll();
+		if (options.rekey_interval > 0 && compat20 && !rekeying)
+			rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
+		else
+			rekey_timeout_ms = 0;
+
 		wait_until_can_do_something(&readset, &writeset, &max_fd,
-		    &nalloc, 0);
+		    &nalloc, rekey_timeout_ms);
 
 		if (received_sigterm) {
 			logit("Exiting on signal %d", (int)received_sigterm);
Index: ssh_config
===================================================================
RCS file: /var/cvs/openssh/ssh_config,v
retrieving revision 1.28
diff -u -p -r1.28 ssh_config
--- ssh_config	12 Jan 2010 08:40:27 -0000	1.28
+++ ssh_config	16 May 2013 06:47:00 -0000
@@ -45,3 +45,4 @@
 #   PermitLocalCommand no
 #   VisualHostKey no
 #   ProxyCommand ssh -q -W %h:%p gateway.example.com
+#   RekeyLimit 1G 1h
Index: ssh_config.5
===================================================================
RCS file: /var/cvs/openssh/ssh_config.5,v
retrieving revision 1.161
diff -u -p -r1.161 ssh_config.5
--- ssh_config.5	9 Jan 2013 05:12:19 -0000	1.161
+++ ssh_config.5	16 May 2013 06:47:00 -0000
@@ -931,8 +931,9 @@ The default is
 This option applies to protocol version 2 only.
 .It Cm RekeyLimit
 Specifies the maximum amount of data that may be transmitted before the
-session key is renegotiated.
-The argument is the number of bytes, with an optional suffix of
+session key is renegotiated, optionally followed a maximum amount of
+time that may pass before the session key is renegotiated.
+The first argument is specified in bytes and may have a suffix of
 .Sq K ,
 .Sq M ,
 or
@@ -943,6 +944,17 @@ The default is between
 and
 .Sq 4G ,
 depending on the cipher.
+The optional second value is specified in seconds and may use any of the
+units documented in the
+.Sx TIME FORMATS
+section of
+.Xr sshd_config 5 .
+The default value for
+.Cm RekeyLimit
+is
+.Dq default none ,
+which means that rekeying is performed after the cipher's default amount
+of data has been sent or received and no time based rekeying is done.
 This option applies to protocol version 2 only.
 .It Cm RemoteForward
 Specifies that a TCP port on the remote machine be forwarded over
Index: sshconnect2.c
===================================================================
RCS file: /var/cvs/openssh/sshconnect2.c,v
retrieving revision 1.184.2.1
diff -u -p -r1.184.2.1 sshconnect2.c
--- sshconnect2.c	5 Apr 2013 00:13:31 -0000	1.184.2.1
+++ sshconnect2.c	16 May 2013 06:47:00 -0000
@@ -197,8 +197,9 @@ ssh_kex2(char *host, struct sockaddr *ho
 	if (options.kex_algorithms != NULL)
 		myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
 
-	if (options.rekey_limit)
-		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
+	if (options.rekey_limit || options.rekey_interval)
+		packet_set_rekey_limits((u_int32_t)options.rekey_limit,
+		    (time_t)options.rekey_interval);
 
 	/* start key exchange */
 	kex = kex_setup(myproposal);
Index: sshd.c
===================================================================
RCS file: /var/cvs/openssh/sshd.c,v
retrieving revision 1.420
diff -u -p -r1.420 sshd.c
--- sshd.c	12 Feb 2013 00:04:48 -0000	1.420
+++ sshd.c	16 May 2013 06:47:00 -0000
@@ -2355,6 +2355,10 @@ do_ssh2_kex(void)
 	if (options.kex_algorithms != NULL)
 		myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
 
+	if (options.rekey_limit || options.rekey_interval)
+		packet_set_rekey_limits((u_int32_t)options.rekey_limit,
+		    (time_t)options.rekey_interval);
+
 	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
 
 	/* start key exchange */
Index: sshd_config
===================================================================
RCS file: /var/cvs/openssh/sshd_config,v
retrieving revision 1.91
diff -u -p -r1.91 sshd_config
--- sshd_config	12 Feb 2013 00:02:09 -0000	1.91
+++ sshd_config	16 May 2013 06:47:00 -0000
@@ -29,6 +29,9 @@
 #KeyRegenerationInterval 1h
 #ServerKeyBits 1024
 
+# Ciphers and keying
+#RekeyLimit default none
+
 # Logging
 # obsoletes QuietMode and FascistLogging
 #SyslogFacility AUTH
Index: sshd_config.5
===================================================================
RCS file: /var/cvs/openssh/sshd_config.5,v
retrieving revision 1.163
diff -u -p -r1.163 sshd_config.5
--- sshd_config.5	12 Feb 2013 00:02:09 -0000	1.163
+++ sshd_config.5	16 May 2013 06:47:00 -0000
@@ -799,6 +799,7 @@ Available keywords are
 .Cm PermitRootLogin ,
 .Cm PermitTunnel ,
 .Cm PubkeyAuthentication ,
+.Cm RekeyLimit ,
 .Cm RhostsRSAAuthentication ,
 .Cm RSAAuthentication ,
 .Cm X11DisplayOffset ,
@@ -993,6 +994,33 @@ Specifies whether public key authenticat
 The default is
 .Dq yes .
 Note that this option applies to protocol version 2 only.
+.It Cm RekeyLimit
+Specifies the maximum amount of data that may be transmitted before the
+session key is renegotiated, optionally followed a maximum amount of
+time that may pass before the session key is renegotiated.
+The first argument is specified in bytes and may have a suffix of
+.Sq K ,
+.Sq M ,
+or
+.Sq G
+to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
+The default is between
+.Sq 1G
+and
+.Sq 4G ,
+depending on the cipher.
+The optional second value is specified in seconds and may use any of the
+units documented in the
+.Sx TIME FORMATS
+section of
+.Xr sshd_config 5 .
+The default value for
+.Cm RekeyLimit
+is
+.Dq default none ,
+which means that rekeying is performed after the cipher's default amount
+of data has been sent or received and no time based rekeying is done.
+This option applies to protocol version 2 only.
 .It Cm RevokedKeys
 Specifies revoked public keys.
 Keys listed in this file will be refused for public key authentication.

-- 
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.


More information about the openssh-unix-dev mailing list