DDoS and CC Attacks: How They Work and How to Defend

Learn the difference between network-layer DDoS and application-layer CC, make the most of single-host rate limiting, and understand where that defense ends and CDN plus scrubbing must take over.

When your server suddenly slows to a crawl, saturates its bandwidth, or pegs the CPU with no matching real traffic, you're likely under a DDoS or CC attack. Both aim to knock your service offline, but they hit different layers and call for different defenses.

Two Kinds of Attack

Network-layer DDoS

A DDoS (Distributed Denial of Service) attack usually strikes the network or transport layer, drowning your server or its uplink in sheer volume. Common forms include SYN Flood, UDP Flood, and reflection/amplification attacks that abuse DNS or NTP. The tell-tale signs are saturated bandwidth and exploding connection counts—your server often gets buried at the link level before it ever runs a line of business logic.

Application-layer CC

A CC (Challenge Collapsar) attack works at the application layer. The traffic isn't necessarily large, but every request is expensive. Attackers hammer costly endpoints—login, search, checkout—with floods of seemingly legitimate HTTP requests that burn database and CPU cycles. It's stealthier, because any single request looks almost indistinguishable from a real user's.

What a Single Host Can Do

On one box, your toolkit is rate limiting, connection capping, spotting anomalies, and temporary bans, and nginx is your handiest first gate.

Use limitreq to cap request rate and limitconn to cap concurrent connections per IP:

# Define limiting zones (inside the http block)
limit_req_zone  $binary_remote_addr zone=req_per_ip:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;

server {
    location /login {
        limit_req  zone=req_per_ip burst=20 nodelay;
        limit_conn conn_per_ip 10;
    }
}

burst absorbs short spikes, and nodelay serves bursty requests immediately instead of queuing them.

To spot anomalies, start with the access log and rank the noisiest source IPs:

# Top 20 source IPs by request count
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

For an IP you've confirmed is malicious, apply a temporary ban—always with an expiry so you don't lock out real users:

# Quick block; pairs even better with fail2ban
sudo ufw deny from 203.0.113.10

In production, prefer fail2ban to ban on log-pattern rules and unban automatically, rather than hand-curating a blacklist.

Where Single-host Defense Ends

Be clear-eyed here: none of this stops a genuinely large DDoS. When the attack bandwidth is tens of times your uplink capacity, the packets clog the link before they ever reach nginx, and no config on the box can help. Single-host rate limiting really shines against small-to-medium CC floods and abusive scraping—not volumetric attacks.

Absorbing real volume takes upstream infrastructure:

  • CDN: pushes static content and traffic out to edge nodes, soaking up and filtering most requests.
  • Anti-DDoS IP / traffic scrubbing: reroutes traffic through a scrubbing center that strips the attack traffic before forwarding the clean remainder to your origin.
  • Hiding your origin: the most critical step, and the one most often missed. Once your real origin IP leaks, attackers can bypass the CDN and hit you directly. Lock the origin down so only your CDN or scrubbing provider's egress IPs can reach it (via firewall or security group), and audit email headers, DNS history, and error pages for any leaked origin IP.

Summary

DDoS is a contest of bandwidth; CC is a contest of per-request cost. On a single host, nginx's limitreq/limitconn, log analysis, and fail2ban meaningfully blunt small-to-medium application-layer attacks—table-stakes skills worth having. But against a volumetric DDoS, one box has no answer: you need a CDN, upstream scrubbing, and above all a hidden origin. Defense is layered—your host holds the application layer while upstream absorbs the network layer, and neither works without the other.