0
0

Rack::Attackを用いたDoS攻撃防止策の設定方法

Last updated at Posted at 2024-05-04

はじめに

この記事では、RailsアプリケーションにおけるDoS攻撃防止策として、Rack::Attackの設定方法についてステップバイステップで解説します。Rack::Attackは、不正なアクセスや不要なトラフィックを制限するためのミドルウェアであり、アプリケーションを保護する上で非常に有効です。

ステップ1: Gem の追加

まず、RailsプロジェクトのGemfileに以下の行を追加し、rack-attack gemをプロジェクトにインクルードします。

gem 'rack-attack'

追加後、ターミナルで以下のコマンドを実行して、gemをインストールします。

bundle

ステップ2: 初期化ファイルの設定

rack-attackの設定を管理するために、config/initializers/rack_attack.rbファイルを作成します。ファイルには、特定のリクエストを制限するための設定を記述します。以下はその一例です。

config/initializers/rack_attack.rb
class Rack::Attack
  # ユーザーごとの予約リクエストを制限
  throttle('request by user', limit: 150, period: 1.hour) do |req|
    if req.path.start_with?('/reservations') && req.post? # postのみに適用
      warden_info = req.env['warden'].user(:customer)
      warden_info&.id.to_s
    end
  end
  
  throttle('logins/email', limit: 5, period: 20.seconds) do |req|
    if req.path == '/login' && req.post?
      req.params['email'].presence
    end
  end

  # イベントを購読してログに記録
  ActiveSupport::Notifications.subscribe('rack.attack') do |name, start, finish, request_id, req|
    Rails.logger.info "Rack::Attack: #{req.env['rack.attack.match_type']} from #{req.ip} blocked."
  end
end

ステップ3: Middleware として追加

次に、Rack::AttackをRailsアプリケーションのミドルウェアスタックに追加する必要があります。config/application.rbファイルを開き、以下の行を追加します。

config/application.rb
config.middleware.use Rack::Attack

ステップ4: キャッシュストアの設定

Rack::Attackはリクエストの頻度を追跡するためにキャッシュストアを利用します。Railsでは標準でいくつかのキャッシュストアが用意されていますが、本例ではRedisを使用します。Redisの設定は以下の通りです。
※Redisはインメモリデータストアであり、データベース、キャッシュ、メッセージブローカーとして広く使われています。Railsアプリケーションでキャッシュシステムとして利用されることが多いですが、他にもMemcachedなどがよく使われます。

config/environments/production.rb
Rack::Attack.cache.store = ActiveSupport::Cache::RedisCacheStore.new(url: ENV['REDIS_URL'])

開発環境で使用する場合は以下の通りです。

config/environments/development.rb
config.cache_store = :redis_cache_store, { url: 'redis://localhost:6379/1' }

この設定を行う前に、Redisサーバーが起動していることを確認してください。

ステップ5: ログの設定

Rack::Attackの動作を監視するために、ログ設定を追加することが推奨されます。以下の設定をconfig/initializers/rack_attack.rbに追加することで、攻撃を検出した際にログを出力できます。

ActiveSupport::Notifications.subscribe('rack.attack') do |name, start, finish, request_id, req|
  Rails.logger.info "Rack::Attack: #{req.env['rack.attack.match_type']} #{req.path}"
end

以上の設定により、Rack::Attackを利用してRailsアプリケーションのセキュリティを向上させることができます。次のステップでは、これらの設定をテストし、適切に動作するかを確認する方法について説明します。

補足: エラーハンドリング

Rack-Attackが設定どおりにブロックしない場合は、以下のことを試してください。

1. Rails consoleでRedisの存在とキャッシュの設定を確認

以下のようにコンソールから現在設定されているキャッシュストアを確認できます

rails console

コンソールで以下のコマンドを実行してください:

puts Rails.configuration.cache_store

また、以下のコマンドを実行します

(base) Kengo% redis-cli
zsh: command not found: redis-cli
(base) Kengo% 

以下のようになる場合、現在のRailsアプリケーションで設定されているキャッシュストアはnull_storeです。これは実際には何もキャッシュしない設定で、キャッシュストアとして機能しないため、Rack::Attackのような機能でリクエストを追跡して制限を行う場合には適していません。

[1] pry(main)> puts Rails.configuration.cache_store
null_store
=> nil

Rack::Attackを有効に使用するためには、有効なキャッシュストア(例えばRedisやMemcached)を設定する必要があります。Redisをキャッシュストアとして設定する基本的な手順は以下の通りです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0