"We're under DDoS" covers several different attacks with different signatures and different answers. Worth separating them.
Layer 4: connection and packet floods
SYN flood - half-open connections exhausting the backlog. Check:
ss -s
netstat -ant | awk '{print $6}' | sort | uniq -c | sort -rn
A large SYN_RECV count relative to ESTABLISHED is the tell. Connection exhaustion - many complete connections held open, consuming file descriptors and worker slots. UDP flood - bandwidth saturation, usually visible as inbound traffic far exceeding anything your application would generate.
Layer 7: application floods
Harder, because every request looks legitimate in isolation. HTTP flood - high request rate against expensive endpoints. Search pages and anything hitting the database are favourite targets.
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Scanner probes - requests for /wp-admin, /.env, /phpmyadmin on a server running none of them. Not a flood exactly, but the same source usually escalates.
WordPress brute force - repeated POSTs to wp-login.php or xmlrpc.php.
What a host agent can and cannot do
Be clear about this, because vendors are not. A host-based agent cannot mitigate a volumetric DDoS. If your uplink is saturated, the packets have already consumed the bandwidth before anything on the server sees them. That mitigation has to happen upstream - at your provider, or behind a scrubbing service. What a host agent does well is the attacks where the source is identifiable and the volume is survivable: application-layer floods, credential stuffing, scanner probes, and brute force. There, blocking the source IP genuinely stops the attack. Distinguishing the two matters operationally. If you are seeing an HTTP flood from a few hundred sources, blocking works. If your interface counters are pinned and the box is unreachable, no agent will save you and you need to be on the phone to your provider.
Detection before mitigation
Either way, you need to know it is happening. Baseline your normal request rate, connection counts, and inbound bandwidth, then alert on deviation - not on fixed thresholds, which are wrong for every server except the one you tuned them on. SecAI baselines each server individually and detects both Layer 4 and Layer 7 patterns, auto-blocking identifiable sources while flagging volumetric events that need upstream action. See it alongside the rest of the detection stack.