DOS 攻撃対策の Filter といえば、HTTP サーバか、Java だと、Servlet FIlter で、
実装を行っているのが、多い気がします。
Dropwizard を使って書いているアプリケーションでは、どうしたらよいかを調べてみました。1
Dropwizard は HTTP サーバに Jersey を使っているので、その Filter の定義方法になります。
参考サイト
-
Apache DoS攻撃にそなえる | Developers.IO
HTTP サーバ側での対策 サーバが死んでいたり、
縮退運転? などを考えると、どちらの層でも、実施したほうがいいように思います。 -
Denial of Service Filter
Jetty の Denial of Service Filter のページ
MyWebApplication.java
Jersey は Jetty のライブラリが使えるので、org.eclipse.jetty.servlets.DoSFilter
が使えます。 2
以下、Application クラスに、DosFilter 定義を追加しました。
正しく理解できてないかもですが、Jerseyは Jettyに依存している認識です。
package mypackage;
import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.jetty.MutableServletContextHandler;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.DoSFilter;
import mypackage.MyConfiguration
import javax.servlet.DispatcherType;
import java.util.EnumSet;
/**
* MyWebApplication
*
* @author Kem
*/
public class MyWebApplication extends Application<MyConfiguration> {
public static void main(String[] args) throws Exception {
new Festivals4PartyPeopleApp().run(args);
}
@Override
public String getName() {
return "MyWebApplication";
}
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
// Do Nothing....
}
@Override
public void run(MyConfiguration t, Environment e) throws Exception {
MutableServletContextHandler context = e.getApplicationContext();
// DOS Attack 対策 Filterの定義
FilterHolder doSFilterHolder = new FilterHolder(new DoSFilter());
doSFilterHolder.setName("DoSFilter");
doSFilterHolder.setInitParameter("maxRequestsPerSec", "3");
doSFilterHolder.setInitParameter("delayMs", "-1");
context.addFilter(doSFilterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
// 429 ページの設定
ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
errorHandler.addErrorPage(429, "/429");
context.setErrorHandler(errorHandler);
}
}
- 説明
- MutableServletContextHandler に対して、DoSFilter を addFilter します。
maxRequestsPerSec
で Dos アタックとみなす1秒間のリクエスト数を定義します。3 [3] 感覚的には厳しめの3
を設定。context.addFilter(doSFilterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
で、REQUEST
をdispatcher
に設定しています。 4 [4] servlet 2.4 から、デフォルト REQUEST- delayMs を -1 にすると、HTTP エラーコード 429 TOO MANY REQUESTS が飛びます。
- 429 の エラー時の URLを設定しています。
確認
以下、curlコマンドで、429ページに遷移することが確認できました。
while true; do (sleep 2; curl http://127.0.0.1:18080)& done | grep '429 Too Many Requests'
以上です。
コメント