- 開発
READ MORE
こんにちは、hachi8833です。今回はrack-attack gemを取り上げます。
Railsが動作する土台となるRack middleware(後述)のレベルでアプリへのアクセスを制限できます。
アクセス制限をRailsアプリ側のコードで実装せずに済むので、開発がシンプルになります。逆にアクセス制限をRailsアプリと密に連携しようとすると大変かもしれません。
rack-attackの設定はRubyのコードになっているので、込み入った要件にも対応可能です。Rack::Attack
というクラスを使います。
クラウドやホスティング環境でも類似のアクセス制限は多くの場合可能ですし、より下のレイヤで制限をかける方がパフォーマンス上有利ですが、設定は別途記録が必要になります。rack-attackの設定ならリポジトリに登録できるのでアクセス制限の履歴をRailsアプリのGitログなどで容易に追えるようになります。
以下の制限がチェックされます。
上記はattack.rbで以下のような流れで処理されます。
def call(env)
req = Rack::Attack::Request.new(env)
if safelisted?(req)
@app.call(env)
elsif blocklisted?(req)
self.class.blocklisted_response.call(env)
elsif throttled?(req)
self.class.throttled_response.call(env)
else
tracked?(req)
@app.call(env)
end
end
アクセス制限では、IPアドレスやURL、UserAgent(≒ブラウザの種類)、HTTPレスポンスなど、さまざまな要素を指定できます。ログ出力(ActiveSupport::Notifications
を使用)にも対応しています。
2012年のv1.0リリース以来長く使われていて実績があるのが助かります(現在はv5.0.1)。GitHubの☆も3,000個を超えていますね。
明示されていませんが、Rails 3以上であれば利用できるようです。
READMEにひととおり書いてありますが、一応こちらにも書いておきます。
bundle install
を実行します。gem 'rack-attack'
# config/application.rbに書く場合(Rails 3以上)
config.middleware.use Rack::Attack
# config.ru (Rackupファイル)に書く場合
use Rack::Attack
Rack::Attack
を定義して設定を記述します。# config/initializers/rack-attack.rb
class Rack::Attack
# カスタム設定をここに記述
end
初めての場合はWikiに掲載されている一般的な設定例を使い、そこから少しずつ調整するとよいでしょう。以下に抜粋しました。
# 例: 同一IPアドレスからのリクエストを60回/分に制限
throttle('req/ip', :limit => 300, :period => 5.minutes) do |req|
req.ip # unless req.path.start_with?('/assets')
end
# 例: 同一IPアドレスからの/loginsへのPOSTリクエストを20秒あたり5回までに制限
throttle('logins/ip', :limit => 5, :period => 20.seconds) do |req|
if req.path == '/login' && req.post?
req.ip
end
end
より高度な設定方法についてはAdvanced Configurationをご覧ください。ブラックリストを環境変数で与える方法や、BASIC認証への攻撃を遮断する方法などが記載されています。「大半のコードはテストされてないのでご注意ください」とあります。
以下のような使い方が主になると思います。
同一IPアドレスからの短時間/大量アクセスの制限は、特にインターネットで一般公開されるRailsアプリで役立ちそうです。非常に大規模な大量アクセスについては、rack-attackだけに任せず、他の方法によるアクセス制限も併用する必要があるかもしれません。
# examples/rack_attack.rbより
# 同一IPからの1秒あたりのアクセスを30回までに制限
Rack::Attack.throttle("req/ip", :limit => 30, :period => 1) { |req| req.ip }
請け負ったRailsアプリのセキュリティに問題が見つかった場合に、セキュリティ問題をつぶす前に取り急ぎrack-attackでアクセスを絞り込むといった使い方も考えられます。
技術評論社の「Rackとは何か」が一番参考になると思います。Rack middlewareに関するその他の一次情報リンクは以下のとおりです。