How to Monitor and Count Active SSH Sessions to Troubleshoot “no more sessions” Error


2 views

When managing SSH servers, you might encounter the error message sshd[8888]: error: no more sessions in your auth.log, even when you've configured MaxStartups 300 in sshd_config. This typically indicates that your server is hitting its session limit, despite not having hundreds of concurrent connections.

While many administrators use netstat -an | grep :22 | wc -l to count connections, this approach has limitations:

  • It counts TCP connections, not actual SSH sessions
  • Doesn't account for multiplexed connections
  • Might miss sessions where the connection is closed but the session persists

Here are more accurate ways to monitor SSH sessions:

Method 1: Using ss Command

The modern alternative to netstat provides more detailed information:

ss -o state established '( dport = :ssh or sport = :ssh )'

Method 2: Checking Process List

SSH sessions create processes that you can count:

ps aux | grep sshd | grep -v grep | wc -l

Method 3: Using lsof

For more detailed session information:

lsof -i :22 | grep ESTABLISHED

For enterprise environments, consider these approaches:

Using Systemd's Journal

journalctl -u sshd --since "1 hour ago" | grep "session opened"

Implementing Auditd

Configure auditd to track SSH sessions:

# Add to /etc/audit/audit.rules
-w /usr/sbin/sshd -p x -k sshd_sessions

Here's a bash script to monitor SSH sessions:

#!/bin/bash

MAX_SESSIONS=300
CURRENT_SESSIONS=$(ps aux | grep sshd | grep -v grep | wc -l)

if [ "$CURRENT_SESSIONS" -ge "$MAX_SESSIONS" ]; then
    echo "Warning: $CURRENT_SESSIONS SSH sessions detected" | mail -s "SSH Session Alert" admin@example.com
fi

To prevent session exhaustion:

  • Set appropriate MaxSessions in sshd_config
  • Configure ClientAliveInterval and ClientAliveCountMax
  • Consider implementing connection time limits

To identify stale sessions:

last | grep still

Or for more details:

who -u

When seeing "sshd[8888]: error: no more sessions" in your auth.log despite having MaxStartups 300 configured, you're likely dealing with either:

  1. Zombie SSH sessions not being properly terminated
  2. SSH multiplexing creating multiple control connections
  3. Clients rapidly connecting/disconnecting during SFTP transfers

While netstat -an | grep :22 | wc -l gives connection counts, these methods provide more accurate session tracking:

# Method 1: Using ss (socket statistics)
ss -o state established '( sport = :ssh or sport = :22 )'

# Method 2: Checking SSH process tree
ps -ef | grep 'sshd:.*@' | grep -v grep | wc -l

# Method 3: Using systemd's cgroup tracking (Linux only)
systemctl status sshd.service | grep -i "memory" | awk '{print $9}'

For detailed session inspection, check SSH's process tree:

# List all active SSH sessions with client IPs
sudo grep -aoP 'SSH-2.0-[^\x00]+' /proc/*/environ | \
  awk -F/ '{print $3}' | \
  xargs -I{} sudo cat /proc/{}/cmdline | \
  tr '\0' ' ' | \
  grep -a "sshd:"

For persistent monitoring, configure audit rules:

# /etc/audit/rules.d/sshd.rules
-w /usr/sbin/sshd -p x -k sshd_sessions
-w /etc/ssh/sshd_config -p rwa -k sshd_config

# Then monitor with:
sudo ausearch -k sshd_sessions | aureport -au -i

Track session duration to identify stuck connections:

#!/bin/bash
while true; do
  netstat -tnp | grep ':22' | awk '{print $5}' | \
    cut -d: -f1 | sort | uniq -c | \
    awk '$1 > 3 {print "Potential SSH abuse from "$2": "$1" connections"}'
  sleep 30
done

For kernel-level monitoring (requires SystemTap):

# ssh_session_monitor.stp
probe begin { printf("SSH Session Monitor Started\n") }
probe process("/usr/sbin/sshd").function("do_authenticated") {
  printf("New SSH session from %s\n", user_string($display))
}
probe process("/usr/sbin/sshd").function("session_close") {
  printf("Closed SSH session from %s\n", user_string($display))
}

Add these to sshd_config to prevent session buildup:

ClientAliveInterval 300
ClientAliveCountMax 2
MaxSessions 10
LoginGraceTime 2m