Instrumentation for metrics

Damien Miller
2020-01-21T07:44:52Z

On Tue, 21 Jan 2020, Philipp Marek wrote:

> > This makes me think that the syslog approach is probably the way to go
>
> Yeah, right.
> Another idea is to mirror the current preauth load via setproctitle()...
> That makes that data accessible even without a syscall (at least the
> writing of the data - quering needs syscalls, right), so that can be
> kept up-to-date and allows a high monitoring frequency as well.
>
> Multiple instances of SSHd (on different ports) are easily distinguished
> as well.

That's a really, really good idea. Patch below.

> Data that I would like to see logged is the utime information of child
> processes - how much user/sys time the processes took, memory usage,
> and some more.
>
> I imagine a single-line output with SSHd pid, session ID, user,
> child PID, and the accounting data - that would be nice to have.
>
> The parallel ongoing discussion about ControlMaster reminds me that
> one SSH connection might drop multiple such log lines...

Well, there's two plausible places where this could be logged:

1) At shell/command termination. This would be a little divorced from its
   context however, because we don't log any commands for privacy reasons.
2) At connection termination; this would roll up all stats for multiplexed
   sessions as you observe.

-d

diff --git a/sshd.c b/sshd.c
index 6129b0a..debbdcb 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1005,7 +1005,7 @@ server_accept_loop(int *sock_in, int *sock_out, int
*newsock, int *config_s)
 {
 	fd_set *fdset;
 	int i, j, ret, maxfd;
-	int startups = 0, listening = 0, lameduck = 0;
+	int ostartups = -1, startups = 0, listening = 0, lameduck = 0;
 	int startup_p[2] = { -1 , -1 };
 	char c = 0;
 	struct sockaddr_storage from;
@@ -1029,6 +1029,11 @@ server_accept_loop(int *sock_in, int *sock_out, int
*newsock, int *config_s)
 	 * the daemon is killed with a signal.
 	 */
 	for (;;) {
+		if (ostartups != startups) {
+			setproctitle("[listener] %d/%d startups",
+			    startups, options.max_startups);
+			ostartups = startups;
+		}
 		if (received_sighup) {
 			if (!lameduck) {
 				debug("Received SIGHUP; waiting for children");