Server logs and login auditing
Logs answer three questions: what broke, who logged in to the server and what they did there. You only get an answer if logging is enabled, the logs are kept long enough and they are not stored only on the server that may have been compromised. Here is where to find logs on Linux, which commands show logins, how to set up rotation and what to do in advance so that there is something to investigate after an incident.
On a Linux system with systemd, two services write logs. journald, part of systemd, collects messages from all services, the kernel and logins into a binary journal. rsyslog, if installed, sorts the same messages into text files under /var/log. The web server, the database and Docker keep their own logs. You need to know where everything is before an incident, not during one.
Where the logs are
- journald. Read it with
journalctl. The journal is kept on disk if the/var/log/journaldirectory exists; otherwise it is kept only in memory and lost on reboot (journald.conf, theStorage=autosetting). Check this on a new server withls /var/log/journal. If the directory is missing, create it and restart the service:systemctl restart systemd-journald. - System files. On Ubuntu, logins and sudo are written to
/var/log/auth.logand general messages to/var/log/syslog. On AlmaLinux and Rocky Linux these are/var/log/secureand/var/log/messages. Debian 12 and later do not install rsyslog by default, so everything is only in journald. - The web server. nginx writes to
/var/log/nginx/access.loganderror.log; Apache writes to/var/log/apache2/on Debian and Ubuntu or/var/log/httpd/on AlmaLinux. The access log records every request: address, time, path, response code, size and browser. The set of fields is defined by the log_format directive. If the site sits behind a CDN, configure the server to pass on the visitor's real address, or the log will contain only CDN addresses (more in the article CDN: when a website needs one). - Applications and Docker. Databases write to their own directories under
/var/log, and containers write to Docker's files, which you read withdocker logs.
A few journalctl commands cover most cases: journalctl -u nginx --since "1 hour ago" shows one service's messages for the last hour; journalctl -p err -b shows errors since the last boot; journalctl -f follows new messages; journalctl --disk-usage shows how much space the journal takes.
Who logged in to the server
Every SSH login leaves a record with the user name, the address and the authentication method, key or password. To see successful logins:
- in journald:
journalctl -u ssh --since today | grep Accepted(on AlmaLinux the service is calledsshd); - in a file:
grep Accepted /var/log/auth.logor/var/log/secure; - as a summary:
lastshows logins and reboots,lastbshows failed attempts.
Debian 13 no longer ships last, lastb and lastlog: their old file formats cannot store dates after 2038. The wtmpdb and lastlog2 packages replace them (Debian 13 release notes). The Accepted entries in the journal remain in every version.
What to look for. Logins from unfamiliar addresses and at unusual times. Password logins when you have configured key-only access: that means the setting did not take effect. Commands run with sudo: auth.log and journald record who ran what. New keys in ~/.ssh/authorized_keys and new users in /etc/passwd: intruders add them to get back in later. If you need a detailed audit of file changes and commands, Linux has the auditd audit subsystem, but its rules need separate configuration and disk space.
fail2ban: what it offers beyond SSH
fail2ban reads logs and temporarily blocks addresses that fail to log in again and again. Installing it and protecting SSH is covered in the article First 10 steps after buying a VPS: security. By default an address is blocked for 10 minutes after 5 failures within 10 minutes (jail.conf). What is worth adding:
- Long bans for repeat offenders. The
recidivejail reads fail2ban's own log and blocks for a week any address that was banned several times within a day. Thebantime.increment = truesetting doubles the ban with each new one. - Web server jails. The ready-made
nginx-http-auth,nginx-limit-reqandnginx-botsearchjails react to wrong passwords on protected pages, exceeded request rate limits and scanning for non-existent URLs. - Your own addresses as exceptions. The
ignoreipsetting with your office's static address keeps you from locking yourself out.
fail2ban does not protect against distributed attacks from thousands of addresses and does not replace key-based login. Its main value for auditing is a shorter log: what remains are meaningful events rather than tens of thousands of identical password-guessing attempts. fail2ban-client status sshd lists the blocked addresses.
Rotation and disk space
Logs grow all the time, and inexpensive VPS plans have small disks. According to the accsly.io catalog as of November 2026, the median disk on VPS plans with 1 GB of memory is 20 GB, and 9% of VPS plans have a disk of 20 GB or less. The access log of a busy site or a container writing an error in a loop fills such a disk within days, after which the database and the site itself stop working.
- journald by default takes no more than 10% of the file system and no more than 4 GB. Set your own limit with
SystemMaxUse=in/etc/systemd/journald.confand a retention period withMaxRetentionSec=, which is off by default. To free space once:journalctl --vacuum-size=500Mor--vacuum-time=30d. - Text files are rotated by logrotate according to the rules in
/etc/logrotate.d/. On Ubuntu 24.04, system logs are rotated weekly and 4 old files are kept, which is about a month. The nginx logs from the AlmaLinux 9 package are rotated daily with 10 old files kept. Therotate,dailyorweekly,compressandmaxsizeoptions change the retention, compression and size-based rotation. Thecopytruncatemode suits programs that cannot reopen their log file, but according to the documentation it may lose lines. To test a rule without changing anything:logrotate -d /etc/logrotate.d/nginx. - Docker by default writes container logs with no size limit (json-file driver). Set
max-sizeandmax-filein/etc/docker/daemon.jsonand recreate the containers: the settings apply only to new ones. More in the article Docker on a VPS: getting started.
To find what filled the disk, df -h shows the full partition and du -xh /var/log | sort -h | tail the largest directories. Do not delete a log file that a service keeps open: the space will not be freed until the service restarts. Empty it with truncate -s 0 instead. It is better to get a warning before the disk fills up; that is covered in the article Server monitoring: uptime, load, alerts.
Keeping logs for incident review
If a server is compromised, the first thing an intruder with root access does is edit or delete the logs. That is why a copy that leaves the server immediately is worth more than any retention settings on the server itself.
- Ship logs to another server. rsyslog can forward messages over the network, and journald has the systemd-journal-upload service for this. The receiving end can be a separate inexpensive VPS with a larger disk or a log collection system such as Loki, Graylog or OpenSearch; suitable plans are collected in VPS for Elasticsearch.
- Decide how long to keep them. Most incident reviews need 30–90 days of logs, because a break-in is often discovered well after the day it happened. A week or two on the server itself is enough; the rest belongs on the collection server or in an archive.
- Synchronise the clock. Without accurate time you cannot match events across servers. Run
timedatectl: the "System clock synchronized" line should say yes. - Do not log more than you need. Passwords, tokens and full card numbers must never end up in a log. Under the GDPR, IP addresses and user logins are personal data, so the retention period should be stated in your records of processing and your privacy policy; more in the article GDPR and choosing a host.
- In an incident, preserve first, then fix. Copy the logs and take a disk snapshot at the host before reinstalling the system. How snapshots and backups work is explained in the article VPS backups: strategies and tools.
If you need logs not only for investigations but also for alerts, such as a spike in 500 errors or a root login, they are collected together with metrics on a separate monitoring server. Plans for this are collected in VPS for monitoring.