概要
- 無作法なbotなどによる過剰なリクエストを防止する
- 方法は、rack-attack gemをインストールしてthrottleを設定すればOK
- もし、development環境で効果を確認するには
rails dev:cache
をする
環境
- rails: 5.1.4
- rack-attack: 5.0.1
手順
gemインストール
Gemfileに下記を追加する
# for security
gem 'rack-attack'
なお、もしproductionだけにしたい場合は、下記の通り。
group :production do
gem 'rack-attack'
end
bundle install実施
bundle install
これでインストール完了
設定
起動時に読み込む
- developmentとproduction両方で読み込む場合
module YourApp
class Application < Rails::Application
省略
# security
config.middleware.use Rack::Attack
end
end
- productionだけ読み込む場合
Rails.application.configure do
config.middleware.use Rack::Attack
end
rack-attackの設定ファイル
config/initializers/rack_attack.rb
を作成し、編集します。今回の目的に合致した例がrack-attack gem公式のExample Configurationにありますので、部分抜粋することで実装します。
class Rack::Attack
throttle('req/ip', :limit => 300, :period => 5.minutes) do |req|
req.ip # unless req.path.start_with?('/assets')
end
end
上記の設定は、同一IPから5分間
あたりに300回
のリクエストがあった場合、そのIPからのアクセスを制限するという設定です。
各自の要望に合わせて、適宜、数値を変更してください。
確認
productionにdeployすれば動作確認できるのですが、それだと不安なのでdevelopment環境で動作を確認できるようにします。
こちらの記事を参考に下記のコマンドで設定します。
rails dev:cache
上記コマンドを入力することで、tmp/caching-dev.txt
が作成されます。このファイルが存在するとconfig.action_controller.perform_caching = true
になりキャッシュが有効になり、リクエスト元のipが記録されrack-attackが機能するようになります。
# Enable/disable caching. By default caching is disabled.
if Rails.root.join('tmp/caching-dev.txt').exist? # ここでcaching-dev.txtの有無を判定する
config.action_controller.perform_caching = true # これがキャッシュを有効にする
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
なお、終了するときは、再度rails dev:cache
を実行してください。
動作テスト
development環境でrailsアプリを起動します。任意のページを表示させ、再読込(command+rとか)を300回(上記rack-attack.rbファイル参照)します。そうすると下記の表示に変わります。
これで、動作している事が確認できました。