A Debian-first guide to identifying external reconnaissance, reviewing exposed services, reducing unnecessary exposure, and hardening publicly reachable systems.
Port scanning is a reconnaissance technique used to discover which network ports and services are exposed on a system. Attackers, bots, researchers, and automated internet scanners all do this. In many cases, a port scan is the first step before brute force attempts, exploit attempts, or web probing.
A scan does not always mean compromise, but it does mean your system is being examined for opportunities.
sudo grep "UFW BLOCK" /var/log/ufw.log | tail -n 50
This helps show recent blocked traffic. If one source IP is touching many different destination ports, that may indicate scanning behavior.
sudo grep "UFW BLOCK" /var/log/ufw.log | awk '{
for(i=1;i<=NF;i++){
if($i ~ /^SRC=/){
split($i,a,"=");
print a[2];
}
}
}' | sort | uniq -c | sort -nr | head
This shows which source IPs appear most often in blocked traffic.
sudo ss -tulnp
Before reacting to scans, verify what is truly exposed. If unnecessary services are listening, they increase your attack surface.
sudo journalctl --since "1 hour ago"
If scanning is followed by connection attempts, authentication failures, or service errors, you may see useful context here.
sudo ufw status numbered
This confirms what your firewall is allowing and helps you compare that against the listening services shown by ss.
sudo ufw deny from <IP_ADDRESS>
This is useful when a specific source is aggressively scanning or repeatedly returning.
sudo ufw deny 8080
sudo ufw deny 3306
sudo ufw deny 5432
Only deny ports that should not be publicly reachable in your environment.
sudo ufw allow from <trusted_ip> to any port 22
sudo ufw deny 22
For management services like SSH, limiting access is often better than leaving them open to the internet.
sudo ss -tulnp
sudo systemctl list-units --type=service --state=running
If a scan revealed a service you forgot was exposed, confirm whether it should be running at all.
sudo systemctl stop <service_name>
sudo systemctl disable <service_name>
Removing exposure is often the safest recovery step when a service is not required.
sudo grep "Accepted password" /var/log/auth.log
sudo grep "Accepted publickey" /var/log/auth.log
Port scanning alone is not compromise, but it often comes before other activity. Make sure it did not progress into successful access.
Recovery in this context usually means reviewing exposure, disabling what is unnecessary, and confirming that the scan did not lead to a deeper foothold.
You cannot stop the internet from scanning exposed systems, but you can reduce what attackers learn and limit what they can reach.
sudo ss -tulnp
sudo ufw status numbered
Compare what is listening with what is allowed. If a service is not needed, close it at the firewall and disable it if possible.
127.0.0.1
Databases, dashboards, and internal tools often should not listen on public interfaces at all. Review each service configuration and bind to localhost where appropriate.
sudo ufw allow from <trusted_ip> to any port 22
sudo ufw deny 22
Management ports should rarely be open to the whole internet unless there is a strong operational reason.
sudo apt list --installed
sudo systemctl list-unit-files --type=service
Old web panels, test services, and forgotten applications often create unnecessary exposure.
sudo grep "UFW BLOCK" /var/log/ufw.log | tail -n 100
Repeated scanning against the same ports can help you understand what the internet sees on your system and what should be hardened next.
Manual Debian-based hardening should come first. That keeps visibility and control in your hands.
Over time, this section may include carefully selected hosting or infrastructure options that make firewall management, service isolation, or remote administration easier. Any future recommendations should support the workflow, not replace it.
For now, the primary recommendation is still to reduce exposure manually, review listening services regularly, and keep firewall rules tight.
All commands shown are based on Debian-based systems unless otherwise noted. Log locations and service names may vary slightly depending on your configuration.