init
This commit is contained in:
commit
23c7133fa9
33 files changed
+2896
No files matched your search
@@ -0,0 +1,48 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// OnlineSession is one currently-connected sshd process for a managed user.
|
||||
type OnlineSession struct {
|
||||
User string
|
||||
PID int
|
||||
Elapsed string // e.g. "01:23:45" as reported by ps etime
|
||||
}
|
||||
|
||||
// ListOnline reports users currently connected. Port-forwarding-only
|
||||
// sessions never allocate a pty, so they are invisible to `who`/`loginctl`;
|
||||
// what *is* always true is that an authenticated connection keeps a
|
||||
// "sshd: <user> [priv]"-style privilege-separated process alive for as long
|
||||
// as the session lasts, so we read that from `ps` instead.
|
||||
func ListOnline(managedUsers map[string]bool) ([]OnlineSession, error) {
|
||||
out, err := exec.Command("ps", "-eo", "user:32,pid,etime,args", "--no-headers").Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ps: %w", err)
|
||||
}
|
||||
var sessions []OnlineSession
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 4 {
|
||||
continue
|
||||
}
|
||||
user, pidStr, etime := fields[0], fields[1], fields[2]
|
||||
args := strings.Join(fields[3:], " ")
|
||||
if !strings.Contains(args, "sshd:") {
|
||||
continue
|
||||
}
|
||||
if !managedUsers[user] {
|
||||
continue
|
||||
}
|
||||
pid, err := strconv.Atoi(pidStr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
sessions = append(sessions, OnlineSession{User: user, PID: pid, Elapsed: etime})
|
||||
}
|
||||
return sessions, nil
|
||||
}
|
||||
Reference in new issue
Block a user