ちょっと話題の記事

Amazon EC2でDoS/DDoS攻撃をブロックする – iptables –

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

サーバーへの攻撃とは

ファイアウォールで公開しているポートに対して攻撃を受けたかどうか、みなさんはどのように判断していますでしょうか?実際のところ、たまにログを目視チェックしていれば良い方だと思います。実際のところ、攻撃されたことにも気付かず。。。そこで、今回は、連続して攻撃を受け"そうに"なった場合に、アクセス自体をブロックする方法をご紹介します。

DoS/DDoS攻撃とは

DoS(Denial of Service:サービス妨害)攻撃は、正常なサービスの運営を妨害する攻撃です。F5キーを押し続けて大量のリクエストをし続けてサーバーをパンクさせるとか、考えられる全てのパスワードをチャレンジする総当り攻撃などとても怖いです。また、単一のクライアントからの攻撃だけでなく、トロイの木馬で感染させられた大量の端末を用いて総攻撃を掛けるDDoS(Distributed Denial of Service:分散サービス妨害)攻撃は、十分と思われる対策が施された大手Webサイトもパンクするような攻撃力を持っています。

iptablesとは

iptablesは、パケットフィルタリングやNATを行うコマンドです。フィルタリングを行うテーブルと、どのタイミングで処理するかチェインによって構成されています。今回は、外部からのアクセスに対してフィルタしますので、filterテーブルのINPUTチェインにて記述をします。

パケットフィルタリングの例

Wikipediaの丸パクリですが、分かりやすいのでご紹介します。

$ sudo iptables -t filter -I INPUT -p tcp -s 123.123.123.123 --dport 80 -j DROP
  • -t filter でfilterテーブルを操作
  • -I INPUT でINPUTチェインに追加(-Iでチェイン内ルールの先頭に、-Aで末尾に)
  • -p tcp でTCPプロトコル限定
  • -s 123.123.123.123 で送信元IPアドレスを指定
  • --dport 80 で 80番ポート(80/tcp = http)を指定
  • 上記ルールにマッチしたパケットを-j DROPで破棄

まとめるとfilterテーブルのINPUTチェインの先頭に以下のルールを追加:IP 123.123.123.123から80/tcp(http)に入ろうとしているパケットは送信元(123.123.123.123)に通知することなく破棄(DROP)ということになります。

SSHへの総当り攻撃をブロックする

まず始めに、Amazon EC2は、SSH接続する際にパスワードによる認証を行っていませんので、総当り攻撃を食らっても突破されるには現状難しいと思います。SSHの部分をFTP等でパスワード認証で公開しているサービスに置き換えて頂いても構いません。総当り攻撃の判断ですが、「一定時間内に連続して接続をトライして失敗した接続元」と定義します。例えば、5分で10回の接続失敗等です。

それでは、「1分間に5回しか接続トライをできないようにする」シナリオで進めてみます。

$ sudo iptables -A INPUT -p tcp --syn --dport 22 -m recent --name ssh_attack --set
$ sudo iptables -A INPUT -p tcp --syn --dport 22 -m recent --name ssh_attack --rcheck --seconds 60 --hitcount 5 -j LOG --log-prefix 'SSH attack: '
$ sudo iptables -A INPUT -p tcp --syn --dport 22 -m recent --name ssh_attack --rcheck --seconds 60 --hitcount 5 -j REJECT

設定を保存してiptablesを再起動します。

$ sudo service iptables save
$ sudo service iptables restart

これで1分間以内に連続接続5回失敗すると6回目から接続自体を拒否します。ここで注意が必要です。REJECTではなくDROPを指定してしまうと、SSHクライアント側が再接続を繰り返すのでログが大量に残ります。REJECTして拒否を確定しましょう。接続拒否のログを見てみます。

$ sudo tail /var/log/messages
Mar 21 17:13:59 ip-10-146-58-XXX kernel: [324156.136295] SSH attack: IN=eth0 OUT= MAC=12:31:50:00:39:a7:fe:ff:ff:ff:ff:ff:08:00 SRC=210.20.91.XXX DST=10.146.58.XXX LEN=48 TOS=0x00 PREC=0x00 TTL=52 ID=4878 DF PROTO=TCP SPT=52141 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 
Mar 21 17:14:16 ip-10-146-58-XXX kernel: [324172.659590] SSH attack: IN=eth0 OUT= MAC=12:31:50:00:39:a7:fe:ff:ff:ff:ff:ff:08:00 SRC=210.20.91.XXX DST=10.146.58.XXX LEN=48 TOS=0x00 PREC=0x00 TTL=52 ID=16997 DF PROTO=TCP SPT=52141 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 
Mar 21 17:15:31 ip-10-146-58-XXX kernel: [324248.328989] ip_tables: (C) 2000-2006 Netfilter Core Team
Mar 21 17:16:11 ip-10-146-58-XXX kernel: [324287.695710] SSH attack: IN=eth0 OUT= MAC=12:31:50:00:39:a7:fe:ff:ff:ff:ff:ff:08:00 SRC=210.20.91.XXX DST=10.146.58.XXX LEN=64 TOS=0x00 PREC=0x00 TTL=53 ID=25633 DF PROTO=TCP SPT=52159 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 
Mar 21 17:16:20 ip-10-146-58-XXX kernel: [324296.344494] SSH attack: IN=eth0 OUT= MAC=12:31:50:00:39:a7:fe:ff:ff:ff:ff:ff:08:00 SRC=210.20.91.XXX DST=10.146.58.XXX LEN=64 TOS=0x00 PREC=0x00 TTL=52 ID=62724 DF PROTO=TCP SPT=52160 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0

messagesはsyslogの様々なメッセージが入ってきますので、iptablesのログを分けたいと思います。Amazon Linuxのログはrsyslogです。

$ sudo vi /etc/rsyslog.conf

iptables用の出力設定を追記します。以下のようにしてみてください。

# Save iptables messages to iptables.log                                                                                
kern.debug                         /var/log/iptables.log

rsyslogサービスを再起動します。ちゃんとログが分かれました!

$ sudo service rsyslog restart

Webサーバーへの総当り攻撃をブロックする

パスワードを入力する画面に対して総当り攻撃を行い突破する方法は最もポピュラーな攻撃です。これらの攻撃に対処するためにOWASP(The Open Web Application Security Project)では、いくつかの方法を紹介しています。様々な仕掛けでサーバーを守る必要がありますね。AWSが行っているセキュリティ施策がお手本だと思います。

  • CAPTCHASを使ってプログラムによる自動ログイン/自動登録をさせないようにする。
  • パスワード認証時にレスポンスに時間を掛ける。
  • 同じIPからの繰り返し認証失敗時に接続拒否をする。
  • 何回か連続してパスワード認証に失敗するとアカウントをロックする。
  • ログインしたらそのセッションでは同じIPアドレスからのみ受け付ける。
  • ランダムなシークレット質問に回答する。
  • ユーザー毎にユニークなログインURLを用意する

WebサーバーへのHashdos攻撃をブロックする

今年に入って、Webサーバへの新たなDoS攻撃手法が出てきました。Hashdos攻撃というものです。HttpRequestにあるパケットを大量に送り続けることによりWebサーバーが数分程度高負荷になってしまう攻撃です。かなり簡単にDoS攻撃できてしまいます。PHPやTomcatでも最新バージョンのパッチでは対策が施されているようですが、運用中のアプリ環境を変えるのは気が引けます。そこで、WAFでどうにかしちゃいましょう。ModSecurityがインストール済みということで進めます。

$ sudo vi /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf

最後の行あたりのSecRuleEngine Onの次に追記します。

#for Hashdos

SecRequestBodyAccess On
SecResponseBodyAccess Off
SecRequestBodyLimit 5242880
SecRequestBodyNoFilesLimit 51200
SecRequestBodyNoFilesLimit 51200
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogType Serial
SecAuditLog         /var/log/httpd/modsec_audit.log
SecAuditLogParts "ABIFHKZ"
SecDebugLog         /var/log/httpd/modsec_debug.log
SecDebugLogLevel    3
SecDataDir      /var/modsecurity/data/
SecTmpDir       /var/modsecurity/tmp/
SecUploadDir    /var/modsecurity/upload/

httpdが読み込むModSecurityに関する設定ファイルを編集します。

$ sudo vi /etc/httpd/conf.d/mod_security.conf

CoreRuleSetをインクルードします。

Include modsecurity.d/modsecurity_crs_10_config.conf

最後にhttpdサービスを再起動します。

$ sudo service httpd restart

まとめ

iptablesによってパケットレベルの制御を行い、総当り攻撃を防ぐ事が出来ました。WAFによってHashdos攻撃を防ぐ事ができました。日曜プログラマな私も気がつけばパケットの流れやHTTPの中身を制御する番人になっていました。やればできる。いつやる?いまだよ。以上、CM進ハイスクールでしたw。今日から君もパケットの番人だ!

参照資料

iptables:Wikipedia

iptables の ipt_recent で ssh の brute force attack 対策

hashdos攻撃をmod_securityで防御する(CentOS+yum編)

Blocking Brute Force Attacks:OWASP