WARNING: This is still a work-in-progress.
Read a yaml
config, and loop through some pre-defined commands from the config with Netflix's go-expect
.
In short, log SSH Client output; batteries included.
- Pre-scripted YAML command configs, per-host
- Customizable CLI prompt detection
- Optionally-timestampped command logs (both UTC and local timezones)
- ping logs (requires elevated privileges)
- Server sniffer logs (requries elevated privileges)
To build the ssh_logger
client, you need to have:
- Go
ssh
andsshpass
; OpenSSH is required.libpcap-dev
(Unix-like OS) / npcap (Windows) installed in your operating-system
It's all wrapped into one portable binary that you can install on any number of clients; this is a key advantage of developing in Go (for instance, compared with Python). Developing this in Python would result in a much slower runtime, the inability to reliabily sniff (because of slow execution), and you would need to download all build dependencies on every new ssh_logger
client.
-
Example of SSH into 127.0.0.1 as
mpenning
, loop through commands inconfigs/localhost.yaml
with timestamps, and no pings:ssh_log --yaml configs/localhost.yaml --verbose
-
Example of using
configs/localhost.yaml
, which will SSH asmpenning
, loop through commands with timestamps, pings, and sniffer pcaps oneth0
:sudo ssh_log --yaml configs/localhost.yaml --verbose --pingCount 10 --sniff eth0
ssh_logger
uses a brief YAML client configuration per ssh server.
Contents of an example YAML configuration file.
ssh_logger:
timezone_location: "America/Chicago"
ssh_loop_sleep_seconds: 5
ssh_user: "mpenning"
ssh_host: "localhost"
ssh_authentication: "password"
ssh_prompt_regex: mpenning.localhost\S+?\$
ssh_privilege_command: "# no privilege command"
prefix_command: "date"
commands:
- "ls -la | grep vim"
- "exit"
timezone_location
: is the timezone that verbose log timestamps are rendered as (in addition to UTC).ssh_loop_sleep_seconds
: are the number of seconds thatssh_logger
will sleep before looping through all commands again. Zero disables looping.ssh_user
: is the username thatssh_logger
will use when logging into the SSH serverssh_host
: is the SSH server DNS or IPssh_authentication
is one of several keywords:none
: No SSH server authentication is used; it's rare to use this, but a few hosts do (such as SSH torviews@route-views.routeviews.org
)password
: SSH Password authentication is used; for now, we assume that the Cisco IOS VTY password and Cisco IOS enable password are the same.ssh_logger
asks for the password at the CLI before starting.password:/path/to/ssh/privatekey
: SSH Password authentication with an SSH private key.ssh_logger
asks for the password at the CLI before starting.key:/path/to/ssh/privatekey
: Password-less authentication with an SSH private key.
ssh_prompt_regex
: Use an un-quoted regex string to detect a prompt; more than one character can be used.ssh_privilege_command
: Use an escaped-regex string for what is used to detect a prompt; more than one character can be used.prefix_command
:ssh_logger
can run commands together in pairs. This prefix command is often used to capture a timestamp from the server (such as the unixdate
command)commands
:ssh_logger
will run this list commands on the server; if there is aprefix_command
, it is run before every command listed here.
$ ./ssh_logger -h
Usage of ./ssh_logger:
--debug Flag to show interactive debugs of the remote host SSH session, default is False
--failOnPingLoss Flag to fail and exit on ping loss, default is False
--logFilename commands.log Name of the Netflix go-expect command logfile. Default is commands.log (default "commands.log")
--pingCount int Specify the number of pings
--pingInterval int Specify the ping interval, in milliseconds (default 200)
--pingSize int Specify the ping size, in bytes (default 64)
--sniff string Name of interface to sniff (default "__UNDEFINED__")
--sshKeepalive int Specify ssh keepalive timeout, in seconds (default 60)
--sshKexAlgorithms string List of accepted KexAlgorithms (default "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1")
--verbose Flag to enable verbose log timestamps, default is False
--yaml string Path to the YAML configuration file (default "__UNDEFINED__")
Use GNU make
make
or
go build -o ssh_logger main.go
- Question: Why did you build a custom Go binary to log ssh sessions when you can simply log the output of an ssh session with the
script
command:script -c 'ssh foo@bar' log.txt
? - Answer: Real SSH session drops often devolve into a list of time-consuming tasks, and
ssh_logger
helps with some of them.
Assume ssh sessions are dropping on your production database server; that's an important problem to solve, especially if the network is dropping traffic (which means your database sessions themselves are slowing down from network packet drops).
ssh_logger
helps provide proactive evidence for the problem, and:
- It's easy to script common use-cases
- It avoids the need to install Don Libes' Expect on the client PC
- It avoids the need to a sniffer application on the client PC
- It builds timestampped command logs, in UTC and your local timezone
- It keeps ping logs from the SSH client
- It keeps sniffer logs from the SSH client
- It's wrapped into a (portable) binary executable; build once, use many
- Apache 2.0 License
- Copyright David Michael Pennington, 2023