Defending Your Rails Application Against DDoS Attacks with Rack::Attack

Distributed Denial of Service (DDoS) attacks can wreak havoc on web applications, causing server overload and unavailability. As a Ruby on Rails developer, you can bolster your application’s defenses against such attacks using the Rack::Attack gem. In this blog, we’ll explore what DDoS attacks are, why Rack::Attack is a vital tool, and how to implement it effectively in your Rails application to mitigate the risks.

Understanding DDoS Attacks

DDoS attacks involve a barrage of requests, often from a vast network of compromised devices or bots, with the aim of overwhelming a server. These attacks can lead to significant downtime and financial losses, making DDoS protection an essential aspect of application security.

The Role of Rack::Attack

Rack::Attack is a middleware for Rails applications that enables you to control and customize access to your application based on predefined rules and limits. With Rack::Attack, you can protect your application against various types of DDoS attacks.

Installing Rack::Attack

Step 1: Add Rack::Attack to Your Gemfile

To begin, open your Gemfile and add Rack::Attack as a gem:

# Gemfile
gem 'rack-attack'

Then, run:

bundle install

Step 2: Configuring Rack::Attack

Rack::Attack’s configuration typically goes in an initializer. Create a new file in the config/initializers directory, such as config/initializers/rack_attack.rb.

In this file, you can define your attack protection rules using Rack::Attack’s DSL (Domain-Specific Language). Here are some common configurations:

Rate Limiting

Rate limiting allows you to restrict the number of requests made from an IP address within a specified time period. For example, limiting requests to 300 per 5 minutes:

# config/initializers/rack_attack.rb
Rack::Attack.throttle('requests/ip', limit: 300, period: 5.minutes) do |req|


You can whitelist certain IP addresses to ensure they are not affected by your rate limiting rules:

Name your custom safelist and make your ruby-block argument return a truthy value if you want the request to be allowed, and falsy otherwise.

Rack::Attack.safelist('allow from trusted IP') do |req|
  # List the trusted IP addresses or ranges
  ['', ''].include?(req.ip)

Custom Block

You can implement custom blocking logic for specific conditions. For example, to block requests with a specific user agent:

Name your custom blocklist and make your ruby-block argument return a truthy value if you want the request to be blocked, and falsy otherwise.

Rack::Attack.blocklist('block bad user agents') do |req|
  # Check for a specific user agent
  req.user_agent == 'BadUserAgent'

Testing and Fine-Tuning

After implementing Rack::Attack, it’s crucial to thoroughly test your configuration and adjust it based on your application’s specific needs. Simulate different attack scenarios to ensure that the gem performs as expected and that legitimate users aren’t adversely affected.

Monitoring and Logging

You can configure Rack::Attack to log or notify you when it triggers an action. For example, you can log blocked requests:

# Log blocked requests
Rack::Attack.blocklist('block bad user agents') do |req|
  # Check for a specific user agent
  req.user_agent == 'BadUserAgent'

config.middleware.use Rack::Attack

Additional Considerations

Ensure that your web server is configured to properly handle and pass requests through Rack::Attack. Keep in mind that DDoS protection is an ongoing process. Regularly monitor and adjust your Rack::Attack configuration based on evolving attack techniques and your application’s traffic patterns.


Rack::Attack is a robust tool for fortifying your Ruby on Rails application against DDoS attacks. By implementing rate limits, whitelists, blacklists, and custom blocking logic, you can significantly reduce the risk of server overload and downtime. With Rack::Attack, you can enhance your application’s security and ensure a smoother and more reliable experience for your users, even in the face of DDoS threats.

Related Post