---
name: "ssh-last"
section: "1"
platform: "linux"
package: "ssh-tools"
version: "1.9-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/ssh-last"
---

# ssh-last(1)

list last SSH sessions

## NAME

ssh-last - list last SSH sessions

## SYNOPSIS

```
               ssh-last [OPTIONS]
    ssh_logs | ssh-last [OPTIONS]
```

### Options

```
    -a  show all sessions                           (show data which is hidden by the 'ignored' file)
    -c  colored output                              (highlight active SSH sessions)
    -d  debug
    -f  force showing fingerprints                  (no mapping from 'known' file)
    -h  show this help message
    -i  force showing certificate ids               (no mapping from 'known' file, not together with -f)
    -l  try to use logfiles instead of journalctl   (may be even faster on some systems)
    -n  show host/ip in cleartext                   (no mapping from 'known' file)
    -w  show only active SSH sessions
    -?  show complete manual with more detailed information
        (usually needs perl-doc installed to work properly)
    --version    show version information
```

### Examples

```
    ssh-last
    ssh-last -c | more
    ssh-last -c | less -R   # keeps colored output in less
    ssh-last -cw
    # Logs from yesterday
    LC_TIME=C journalctl _COMM=sshd -g 'Accepted|Disconnected' --since yesterday               | ssh-last
    # Logs from three days ago
    LC_TIME=C journalctl _COMM=sshd -g 'Accepted|Disconnected' --since -3d --until -2d         | ssh-last
    # Logs from the last hour
    LC_TIME=C journalctl _COMM=sshd -g 'Accepted|Disconnected' --since -1h                     | ssh-last
    # Logs until a specific date
    LC_TIME=C journalctl _COMM=sshd -g 'Accepted|Disconnected' --until "2022-03-12 07:00:00"   | ssh-last
    # From logfiles (order must be from oldest to newest)
    zgrep -hE 'Accepted|Disconnected' auth.log.2.gz  auth.log.1  auth.log                      | ssh-last
    zgrep -hE 'Accepted|Disconnected' $(ls /var/log/auth.log* --sort=time --reverse)           | ssh-last
    zgrep -hE 'Accepted|Disconnected' $(ls /var/log/messages* --sort=time --reverse)           | ssh-last
    zgrep -hE 'Accepted|Disconnected' $(ls /var/log/secure*   --sort=time --reverse)           | ssh-last
```

## DESCRIPTION

ssh-last is like last but for SSH sessions

### Output Flags

```
    +--------------------------------------------------------------------------+
    |                                                                          |
    | AUTH_ID                                                                  |
    |                                                                          |
    | (C) sshd authorized login via (c)ertificate                              |
    | (K) sshd authorized login via public (k)ey                               |
    | (?) sshd authorized login via some other type (password, pam)            |
    |                                                                          |
    +--------------------------------------------------------------------------+
```

### Algorithm

```
    Milling through sshd logs in chronological order:
    1) Finding login (Accepted) and logout (Disconnected) lines.
    2) Storing info from the lines like username, auth_type, fingerprint, ...
    3) Using the used network port to check for active sessions
       and piecing together old sessions by remembering logged network ports
    4) Using mainly /etc/os-release to adapt for different systems
       which differ in logfile names, logging patterns, etc...
```

## FILES

### Ignored

```
     /etc/ssh-tools/ssh-last/ignored
    ~/.config/ssh-tools/ssh-last/ignored
    ./ignored
    These data will be hidden in output unless forced with -a option
    +--------------------------------------------------------------------------+
    |# Fingerprints                                                            |
    |                                                                          |
    |SHA256:ElgyEn5xPe4VlK5jJkqauRdAKNRHdh2tGHfo0m9/IwW Jenkins                |
    |SHA256:5xPe4JkqaElKNRHGHfxPe4RdAKdh2tlK5AKNRHn5xK5 foo          # comment |
    |SHA256:nmKL5s7/fs45312nvjhFSRTREa44r2hfgJHJG54353R   bar@gmx.de           |
    |                                                                          |
    |# Hosts                                                                   |
    |                                                                          |
    |127.0.0.1       localhost   # local ssh logins                            |
    |192.168.1.50    nas         # more comments                               |
    |webserver                   # alias from the 'known' file                 |
    |                                                                          |
    |# Cert IDs                                                                |
    |                                                                          |
    |user1@company.com                                                         |
    |user2@company.com with some info                                          |
    |user3@company.com with some info # and a comment                          |
    |                                                                          |
    |# Users                                                                   |
    |                                                                          |
    |git # gitlab                                                              |
    +--------------------------------------------------------------------------+
```

### Known

```
     /etc/ssh-tools/ssh-last/known
    ~/.config/ssh-tools/ssh-last/known
    ./known
    For these keys the mapped value will be shown instead of its key,
    unless forced with -f (fingerprints) and -n (hosts)
    or -i (certificate ids) option
    +--------------------------------------------------------------------------+
    |# Fingerprints                                                            |
    |                                                                          |
    |SHA256:WwI/9m0ofHGt2hdHRNKAdRuaqkJj5KlV4ePx5nEyglE Sven Wick              |
    |SHA256:xyk5ZZZWZKnmKL5mYdk8Poy5eds7/CD/JEwqykMnlQQ root@n40l    # comment |
    |SHA256:G7h9i5+NDU72Ae40gCkxyvDz/8BH+KETw7sXHCYr5w0   sven.wick@gmx.de     |
    |                                                                          |
    |# Hosts                                                                   |
    |                                                                          |
    |127.0.0.1       localhost   # local ssh logins                            |
    |192.168.1.50    nas         # more comments                               |
    |192.168.50.100  webserver                                                 |
    |                                                                          |
    |# Cert IDs                                                                |
    |                                                                          |
    |user1@company.com   vaporup                                               |
    +--------------------------------------------------------------------------+
```

## BUGS AND LIMITATIONS

### JumpHosts

```
    Using a JumpHost with ProxyCommand oder ProxyJump,
    may often result in an unclean disconnect with nothing logged,
    so LOGOUT and DURATION can not be displayed.
```

### Unprivileged users

```
    If possible, run ssh-last as root or via sudo
    1) Logfiles and systemd's journal usually can't be read by a normal user
    2) ssh-last -w works only reliably as root,
       since ss and netstat do not show process info when invoked as normal user
    3) ssh-last tries to map the fingerprint from a user's authorized_keys file
       but users usually are not allowed to look into each others files
```

### OS Upgrades

```
    If you do an in-place upgrade like dist-upgrade on Debian/Ubuntu,
    depending on the version difference,
    it can happen that sshd logs differently from that point on
    and you may have a mix of logs in new and old format
    which results in ssh-last showing only the latest ones correctly
```

### Log inconsistency

```
    I have seen cases where some sshd "Disconnect" log messages
    were missing in systemd's journal but existed in /var/log/auth.log.
    So, if ssh-last is not showing a logout and duration
    but the log lines exist in the logfile, check if the log message
    really reached systemd's journal since ssh-last defaults to journald
```

## NOTES

### Helper Scripts

```
    For convenience you can create little wrapper scripts like the following
    which avoids parsing too many logs by limiting the data only to the last week
    my-ssh-last
    +--------------------------------------------------------------------------+
    | #!/usr/bin/env bash                                                      |
    |                                                                          |
    | LC_TIME=C journalctl _COMM=sshd --since -1week \                         |
    | | grep -E 'Accepted|Disconnected'              \                         |
    | | ssh-last "$@"                                                          |
    |                                                                          |
    +--------------------------------------------------------------------------+
```

## SEE ALSO

[**ssh-keyinfo**(1)](/ssh-keyinfo/1.md), [**ssh-certinfo**(1)](/ssh-certinfo/1.md)

## AUTHOR

Sven Wick \<sven.wick@gmx.de\>
