Detecting port scans has a peculiarity that drops it out of the usual toolkit. Fail2ban reads application logs — and when a closed port is scanned there is no application, so there is no log entry either. Scanning is visible only at the firewall level, and that is exactly where PSAD works: it reads the messages iptables writes about dropped packets.
A mandatory condition: logging must be on
This is the main reason PSAD "is installed and shows nothing". Without logging rules in the firewall it has nothing to read, and no error is produced along the way.
If you use UFW:
sudo ufw logging low
sudo ufw status verbose
To confirm that messages really do appear:
sudo journalctl -k | grep -c '\[UFW'
sudo grep -c 'UFW BLOCK' /var/log/ufw.log
Zeros from both commands mean PSAD will not work. And separately about Debian 12 and Ubuntu 24.04: without rsyslog the file /var/log/ufw.log does not exist and everything goes to the systemd journal — the log path in PSAD's settings has to account for that.
Installation
sudo apt install psad
sudo psad --sig-update
sudo psad -R
sudo psad --Status
The last command is the main one. It shows how many packets have been parsed, which addresses have been noticed and at what danger level. If the parsed-packet counter is zero, go back to the previous section: the problem is logging, not an absence of scans.
The settings are in /etc/psad/psad.conf. There are few parameters of practical significance: the address for mail, the path to the log, and the danger level thresholds.
Danger levels
PSAD rates every source from 1 to 5 depending on how many different ports were touched and how closely the behaviour resembles known scanning techniques.
- 1–2 — isolated contacts with closed ports. This is the permanent background of the internet; no reaction needed;
- 3 — systematic walking through ports. Usually the research scanners, of which there are several dozen on the network;
- 4–5 — deliberate probing of a large number of ports from one address, often trying to disguise the nature of the contacts.
The threshold for mail is set by EMAIL_ALERT_DANGER_LEVEL. A value of 3 usually means several emails a day, which fairly quickly leads to a rule in the mail client. It is more sensible to set 4 and see the rest on a summary page.
Automatic blocking: do not
PSAD can add firewall rules itself (ENABLE_AUTO_IDS). On a single working server that is not worth enabling, and the reason is specific: the source address in a packet can be forged. It is enough to send packets in your direction with a substituted address — and you will block the address somebody else chose. That may turn out to be your own customer, a payment gateway or a monitoring service.
If blocking is nevertheless required, enable it with a high danger threshold and always with a time limit (AUTO_BLOCK_TIMEOUT) so that a mistaken entry does not stay forever.
What to do with this in practice
Scanning by itself is harmless: it breaks nothing and happens continuously to everyone. The value of PSAD's data is not in the fact but in changes of character.
Useful observations:
- Directed interest. An ordinary scanner walks through thousands of addresses and a dozen popular ports. If somebody is methodically working through the ports of your server specifically, non-standard ones included, that is no longer background;
- Scanning of one particular port. Contacts with a database port or a control panel port mean somebody is looking for that service specifically — usually after news of yet another vulnerability in it;
- Reconnaissance before an attempt. A spike of scanning followed hours later by password guessing from the same range is a typical sequence, and its first half buys a little time.
The practical conclusion from any of those observations is the same: check that the list of outward-facing ports matches expectations, and that whatever runs on each of them is something you have updated this year.
Its place in the toolkit
PSAD replaces neither the firewall, nor Fail2ban, nor an intrusion detection system. It closes one narrow gap — attempts that leave traces nowhere else because they never reached an application. It costs little, works without configuration after the first run, and its summary answers a question nobody otherwise asks: is anybody interested in your server apart from the general background. What that summary looks like is on the demo page below.