SSHD logs are in /var/log/auth.log on Debian/Ubuntu, /var/log/secure on RHEL/CentOS, and in journalctl -u sshd. The right level to set for debugging is LogLevel VERBOSE in /etc/ssh/sshd_config. The team that knows where to look has the answer in under a minute. The team that does not is grepping the wrong log file.
Table of contents
- The right log file
- Using journalctl
- Setting the log level
- Common log messages
- Finding brute-force attempts
- FAQ
The right log file
The right log file on Debian/Ubuntu is /var/log/auth.log. The right way to see recent SSH events:
sudo tail -f /var/log/auth.log
The right log file on RHEL/CentOS/Fedora is /var/log/secure. The right way:
sudo tail -f /var/log/secure
The right answer is to grep for sshd to filter to SSH events:
grep sshd /var/log/auth.log | tail -20
Using journalctl
The right way to see sshd logs on a systemd-managed system:
sudo journalctl -u sshd
The right way to follow in real time:
sudo journalctl -u sshd -f
The right way to see only the last hour:
sudo journalctl -u sshd --since "1 hour ago"
Setting the log level
The right way to get more detail in the logs is to set LogLevel in /etc/ssh/sshd_config:
LogLevel VERBOSE
The default is INFO. VERBOSE adds more detail about authentication attempts. DEBUG and DEBUG1-3 are for development. The right answer is to set VERBOSE for production debugging, then revert to INFO after the issue is resolved.
Common log messages
Failed password for invalid user X from Y port Z ssh2 — wrong password. Accepted publickey for X from Y port Z ssh2 — successful key auth. Connection closed by authenticating user X [preauth] — auth failed before completion. Disconnected from authenticating user X Y port Z [preauth] — connection dropped during auth.
Finding brute-force attempts
The right way to find failed login attempts on Debian/Ubuntu:
grep 'Failed password' /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head
The right way on RHEL/CentOS:
grep 'Failed password' /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head
The output is the top 10 source IPs of failed logins. The right answer is to feed these to fail2ban.
FAQ
What is the difference between auth.log and secure?
auth.log is on Debian/Ubuntu, secure is on RHEL. Both contain authentication events including SSH.
Why is my log file empty?
The right answer is to check that rsyslog or journald is running. The wrong answer is to assume nothing happened.
How do I rotate the logs?
The right answer is logrotate, which is installed by default. The right answer is to configure the rotation policy in /etc/logrotate.d/.
What is the LogLevel DEBUG1?
The most verbose level. The right answer is to use it for development, not production.
Can I see the public key that was used?
Yes, with LogLevel VERBOSE. The wrong answer is INFO, which only logs the key fingerprint.
How do I see authentication attempts from a specific IP?
grep 'from Y' /var/log/auth.log. The right answer is to replace Y with the IP.
What is the ‘preauth’ tag?
It means the connection was dropped before authentication completed. The right answer is to investigate why (timeout, wrong client, fail2ban ban).
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: