2019/02/24
最近のWebフレームワークには、セキュリティ面で優れたものもあり、セキュリティの知識を持っていなくてもある程度の対策ができてしまいます。
例えば、DjangoなんかはORマッパーを使っておけばSQLインジェクションも防げますし、CSRF対策もさくっとできます。
しかし、アプリケーションレベルでの対策をいくらやっても、サーバー自体のセキュリティがあまければ元も子もありません。個人開発で運用しているようなサービスであっても攻撃されたためにサーバーの停止、もしくはレンタルサーバーを解約することになったなんて話もあります。
DDoS攻撃を喰らったらConoHaを解約する羽目になった話
http://www2.gyafuuuun.com/2015/04/ddos%E6%94%BB%E6%92%83%E3%82%92%E5%96%B0%E3%82%89%E3%81%A3%E3%81%9F%E3%82%89conoha%E3%82%92%E8%A7%A3%E7%B4%84%E3%81%99%E3%82%8B%E7%BE%BD%E7%9B%AE%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E8%A9%B1/DDoS攻撃に注意!ブロガーに起きた悲劇と個人が標的の驚愕の過去事例!
https://netkiji.com/blog-operation/ddos-attack/
DDosなどの攻撃には、iptablesというパケットフィルタを導入することで対策することができます。
実際の導入や設定をここで紹介します。
私が試した環境はUbuntuですが、他のLinuxディストリビューションでも同じ設定内容でできます。iptablesの起動方法などはディストリビューションごとに違いがあったりするようなので、そこは各自調べてください。
対象読者はiptablesをちょっと知っている人向けですが、iptables自体の情報はたくさん出てくるので安心してください。
iptables入門者向け参考
https://eng-entrance.com/linux-firewall
一般的なLinuxには標準搭載されているそうですが 、入っていなければインストールしてください。
sudo apt install iptables iptables-persistent
以下のコマンドを打ってみると、現在の設定を見ることができます。インストール直後は何も設定されていません。
sudo iptables -L
次に、フィルタリングのルールを設定するためのファイルを作成します。
sudo /sbin/iptables-save > /etc/iptables/rules.v4
それでは、/etc/iptables/rules.v4
にルールを追加していきます。
追加する箇所は、*filter~COMMITの間で、:OUTPUT ACCEPT
の下に追記していってください。
最初はすべてACCEPTになっているのでINPUT
とFORWARD
のみをDROPにします。
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
ローカルループバックの接続を許可をし、かつ127.0.0.1~127.0.0.254のアドレスはローカルループバックとして許可します。
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
DDos攻撃の一種です。
SYNフラッド攻撃について
https://www.secomtrust.net/secword/synfloodat.html
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP
ポートスキャンの強化版です。接続先にログを取られることなくポートをスキャンできます。
ステルススキャンについて
https://wa3.i-3-i.info/word15556.html
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
ssh接続のポートは22から別の番号へ必ず変更してください。公開鍵秘密鍵の作成も忘れずに。
最初の接続を1分間に1回、同一ホストからの接続数を1つ、管理テーブル中の有効期限を120秒になるよう設定すると、以下のようになります。
ちなみに、hashlimit
はクライアントごとに対して制限をかけられるような機能です。例えば、誰かがサービスに対して攻撃をしてパケットを一時遮断した場合でも、hashlimitを使うことで別のクライアントを遮断せず接続を許可することができます。
hashlimitについて
https://qiita.com/homihomu/items/778770a1c1b3b2371fe0
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A INPUT -p tcp -m state --syn --state NEW --dport 40230 -m hashlimit --hashlimit-name t_sshd --hashlimit 1/m --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT
ping通信などがicmpを使った通信に当たります。
2行目は、通信が遮断されたことを明示的にクライアントへ通知する命令です。
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_icmp --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
アプリケーションに割り振られたポート番号などをここで指定してください。ポートを複数設定したい場合、multiport
を使うことでまとめて指定できます。
-A INPUT -p tcp -m multiport --dport 80,443 -m state --state NEW -m hashlimit --hashlimit-name web_limit --hashlimit 60/m --hashlimit-burst 500 --hashlimit-mode srcip --hashlimit-htable-expire 360000 -j ACCEPT
最後に以下のコマンドで設定内容を適応します。
sudo /usr/sbin/iptables-apply /etc/iptables/rules.v4
設定が反映されていることを確認します。
sudo iptables -L
試しに、フィルタリングしたサーバーにpingを飛ばしてみましょう。
最初の1回は通信できますが、すぐに2回目のpingを飛ばしてみると通信が遮断されると思います。
告知みたいになってしまいますが、私が開発した個人サービスもiptablesでセキュリティ対策をしています。
DAIFUKU
https://daihuku.xyz
Djangoで家計簿サービスを開発してリリースするまで 【個人開発】
https://qiita.com/uichi/items/333bf5bd0b8c4e71a26b
https://qiita.com/sagami1991/items/23f72ab4e6552221188a
https://marunouchi-tech.i-studio.co.jp/2023/
https://orangain.hatenablog.com/entry/20080822/1219310039
https://www.atmarkit.co.jp/ait/articles/0112/18/news002.html
https://www.shadan-kun.com/blog/measure/1426/#04_b
誤字脱字、記事内容に間違いやご意見があれば遠慮なくお知らせください。