Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
29
Help us understand the problem. What is going on with this article?
@junara

rails rack-attack gemで同一IPからの過剰なアクセスを制限する

More than 3 years have passed since last update.

概要

  • 無作法な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両方で読み込む場合
config/application.rb
module YourApp
  class Application < Rails::Application
    省略
    # security
    config.middleware.use Rack::Attack
  end
end
  • productionだけ読み込む場合
config/environments/production.rb
Rails.application.configure do
  config.middleware.use Rack::Attack
end

rack-attackの設定ファイル

config/initializers/rack-attack.rbを作成し、編集します。今回の目的に合致した例がrack-attack gem公式Example Configurationにありますので、部分抜粋することで実装します。

config/initializers/rack-attack.rb
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が機能するようになります。

config/environments/development.rb
  # 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ファイル参照)します。そうすると下記の表示に変わります。
これで、動作している事が確認できました。

https://gyazo.com/35ecc64272302b827b6547f33cc1fd24

29
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
junara
10年間医療の研究していたが、Webサービス作りたくて、エンジニアへ。 Rails, Javascritptのエンジニアとして働きながら、生命科学学会検索サービスを作りました。 https://www.dokode.work
bldt
"Your growth, Improve the world" をビジョンに掲げ、自社事業やシステム開発サービスを提供しています

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
29
Help us understand the problem. What is going on with this article?