기타

How to prevent DDoS on Throttling Layers

파커초 2024. 2. 27. 22:12

What is DDoS

In Distribute denial of service the attacker tries to make a particular service unavailable by directing continuous and huge traffic from multiple end system

Due to this enormous traffic, a legitimate user is unable to access the resources

How to identify a DDoS attack

  • Suspicious amounts of traffic originating from a single IP address or IP range
  • A flood of traffic from users who share a single behavioral profile, such as device type, geolocation, or web browser version
  • An unexplained surge in requests to a single page or endpoint

Layer7 attacks

Is hard to prevent since it can be hard to differentiate malicious traffic from legitimate traffic

SYN flood attack (Layer4)

Normal TCP Handshake

  1. First, the client sends a SYN packet to the server in order to initiate the connection.
  2. The server then responds to that initial packet with a SYN/ACK packet, in order to acknowledge the communication.
  3. Finally, the client returns an ACK packet to acknowledge the receipt of the packet from the server. After completing this sequence of packet sending and receiving, the TCP connection is open and able to send and receive data.
  4. attack send high volume syn packets to the target server
  5. server then responds to each one of the connection request
  6. server waits for ack packet (ack packet never come)

Mitigating a DDoS attack?

The key concern in mitigating a DDoS attack is differentiating between attack traffic and normal traffic.

Blackhole routing

  • funnel traffic into the blackhole
  • but without specific restriction criteria, both legitimate and malicious network traffic is routed to a null route or black hole

Rate limiting

  • Limiting the number of requests a server will accept over a certain time window is also a way of mitigating denial-of-service attacks.
  • it is useful in slowing web from stealing content
    • brute force attack
  • but it alone will likey be insufficient to handle a complex DDoS attack effectively

Web application wall (WAF)

  • WAF is a tool that can assist in mitigating a layer7 DDoS
  • protecting the targeted server from certain types of malicious traffic

What we use now

  • maybe aws waf
  • rate limiting

In memory block strategy

  • redis or mongo provides in-memory block strategy to avoid many request to storage
router.get('/', (req, res, next) => {
  rateLimiter.consume((Math.floor(Math.random() * 5).toString()))
    .then(() => {
      res.status(200).json({}).end();
    })
    .catch(() => {
      res.status(429).send('Too Many Requests').end();
    });
});
  • This code create 5 random keys

bombardier -c 1000 -l -d 30s -r 2000 -t 1s http://127.0.0.1:3000

  • 1000 concurrent requests
  • test duration is 30 seconds
  • not more than 2000 req/sec

Without In-memory Block Strategy

5points for second to consume

const rateLimiter = new RateLimiterRedis(
  {
    redis: redisClient,
    points: 5,
    duration: 1,
  },
);

results

Statistics        Avg      Stdev        Max
  Reqs/sec      1999.05     562.96   11243.01
  Latency        7.29ms     8.71ms   146.95ms
  Latency Distribution
     50%     5.25ms
     75%     7.20ms
     90%    11.61ms
     95%    18.73ms
     99%    52.78ms
  HTTP codes:
    1xx - 0, 2xx - 750, 3xx - 0, 4xx - 59261, 5xx - 0

With In-memory Block Strategy

When 5 points consumed, a key is blocked in current process memory to avoid further requests to Redis in the current duration window.

const rateLimiter = new RateLimiterRedis(
  {
    redis: redisClient,
    points: 5,
    duration: 1,
    inMemoryBlockOnConsumed: 5,
  },
);

Result

Statistics        Avg      Stdev        Max
  Reqs/sec      2011.39     390.04    3960.42
  Latency        1.11ms     0.88ms    23.91ms
  Latency Distribution
     50%     0.97ms
     75%     1.22ms
     90%     1.48ms
     95%     1.91ms
     99%     5.90ms
  HTTP codes:
    1xx - 0, 2xx - 750, 3xx - 0, 4xx - 59268, 5xx - 0

Parameter

inMemoryBlockOnConsumed

For Redis, Memcached, MongoDB, MySQL, PostgreSQL, etc.

In-memory blocking works in current process memory and for consume method only.

Way of blocks

  • msBeforeNext milliseconds from the last consume result if InMemoryBlockDuration is not set

inMemoryBlockDuration

  • block key for inMemoryBlockDuration seconds
    • if inMemoryBlockOnConsumed or more points are consumed
  • should set it the same as blockDuration for distributed application to have consistent result on all processes

Reference