File: ssh-last.1

package info (click to toggle)
ssh-tools 1.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,328 kB
  • sloc: sh: 1,403; perl: 785; makefile: 5
file content (267 lines) | stat: -rw-r--r-- 12,574 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds C`
.    ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
.    if \nF \{\
.        de IX
.        tm Index:\\$1\t\\n%\t"\\$2"
..
.        if !\nF==2 \{\
.            nr % 0
.            nr F 2
.        \}
.    \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "SSH-LAST 1"
.TH SSH-LAST 1 2024-09-26 SSH-TOOLS "User Commands"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
ssh\-last \- list last SSH sessions
.SH SYNOPSIS
.IX Header "SYNOPSIS"
.Vb 2
\&               ssh\-last [OPTIONS]
\&    ssh_logs | ssh\-last [OPTIONS]
.Ve
.SS Options
.IX Subsection "Options"
.Vb 11
\&    \-a  show all sessions                           (show data which is hidden by the \*(Aqignored\*(Aq file)
\&    \-c  colored output                              (highlight active SSH sessions)
\&    \-d  debug
\&    \-f  force showing fingerprints                  (no mapping from \*(Aqknown\*(Aq file)
\&    \-h  show this help message
\&    \-i  force showing certificate ids               (no mapping from \*(Aqknown\*(Aq 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 \*(Aqknown\*(Aq 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
.Ve
.SS Examples
.IX Subsection "Examples"
.Vb 4
\&    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 \*(AqAccepted|Disconnected\*(Aq \-\-since yesterday               | ssh\-last
\&
\&    # Logs from three days ago
\&    LC_TIME=C journalctl _COMM=sshd \-g \*(AqAccepted|Disconnected\*(Aq \-\-since \-3d \-\-until \-2d         | ssh\-last
\&
\&    # Logs from the last hour
\&    LC_TIME=C journalctl _COMM=sshd \-g \*(AqAccepted|Disconnected\*(Aq \-\-since \-1h                     | ssh\-last
\&
\&    # Logs until a specific date
\&    LC_TIME=C journalctl _COMM=sshd \-g \*(AqAccepted|Disconnected\*(Aq \-\-until "2022\-03\-12 07:00:00"   | ssh\-last
\&
\&    # From logfiles (order must be from oldest to newest)
\&    zgrep \-hE \*(AqAccepted|Disconnected\*(Aq auth.log.2.gz  auth.log.1  auth.log                      | ssh\-last
\&    zgrep \-hE \*(AqAccepted|Disconnected\*(Aq $(ls /var/log/auth.log* \-\-sort=time \-\-reverse)           | ssh\-last
\&    zgrep \-hE \*(AqAccepted|Disconnected\*(Aq $(ls /var/log/messages* \-\-sort=time \-\-reverse)           | ssh\-last
\&    zgrep \-hE \*(AqAccepted|Disconnected\*(Aq $(ls /var/log/secure*   \-\-sort=time \-\-reverse)           | ssh\-last
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
ssh-last is like last but for SSH sessions
.SS "Output Flags"
.IX Subsection "Output Flags"
.Vb 9
\&    +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
\&    |                                                                          |
\&    | 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)            |
\&    |                                                                          |
\&    +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
.Ve
.SS Algorithm
.IX Subsection "Algorithm"
.Vb 1
\&    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...
.Ve
.SH FILES
.IX Header "FILES"
.SS Ignored
.IX Subsection "Ignored"
.Vb 3
\&     /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 \*(Aqknown\*(Aq file                 |
\&    |                                                                          |
\&    |# Cert IDs                                                                |
\&    |                                                                          |
\&    |user1@company.com                                                         |
\&    |user2@company.com with some info                                          |
\&    |user3@company.com with some info # and a comment                          |
\&    |                                                                          |
\&    |# Users                                                                   |
\&    |                                                                          |
\&    |git # gitlab                                                              |
\&    +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
.Ve
.SS Known
.IX Subsection "Known"
.Vb 3
\&     /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                                               |
\&    +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
.Ve
.SH "BUGS AND LIMITATIONS"
.IX Header "BUGS AND LIMITATIONS"
.SS JumpHosts
.IX Subsection "JumpHosts"
.Vb 3
\&    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.
.Ve
.SS "Unprivileged users"
.IX Subsection "Unprivileged users"
.Vb 1
\&    If possible, run ssh\-last as root or via sudo
\&
\&    1) Logfiles and systemd\*(Aqs journal usually can\*(Aqt 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\*(Aqs authorized_keys file
\&       but users usually are not allowed to look into each others files
.Ve
.SS "OS Upgrades"
.IX Subsection "OS Upgrades"
.Vb 5
\&    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
.Ve
.SS "Log inconsistency"
.IX Subsection "Log inconsistency"
.Vb 5
\&    I have seen cases where some sshd "Disconnect" log messages
\&    were missing in systemd\*(Aqs 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\*(Aqs journal since ssh\-last defaults to journald
.Ve
.SH NOTES
.IX Header "NOTES"
.SS "Helper Scripts"
.IX Subsection "Helper Scripts"
.Vb 2
\&    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 \e                         |
\&    | | grep \-E \*(AqAccepted|Disconnected\*(Aq              \e                         |
\&    | | ssh\-last "$@"                                                          |
\&    |                                                                          |
\&    +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
.Ve
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fBssh\-keyinfo\fR\|(1), \fBssh\-certinfo\fR\|(1)
.SH AUTHOR
.IX Header "AUTHOR"
Sven Wick <sven.wick@gmx.de>