個人開発でも最低限やっておくべきインフラレベルでのセキュリティ対策

最近の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


# iptablesの導入
一般的な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
```

# SYNflood攻撃と思われる接続を破棄

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接続に制限を設ける
ssh接続のポートは22から別の番号へ必ず変更してください。公開鍵秘密鍵の作成も忘れずに。

> 公開鍵・秘密鍵の生成
https://qiita.com/nisyuu/items/333bf5bd0b8c4e71a26b#%E5%85%AC%E9%96%8B%E9%8D%B5%E7%A7%98%E5%AF%86%E9%8D%B5%E3%81%AE%E7%94%9F%E6%88%90

> SSH設定ファイルの変更
https://qiita.com/nisyuu/items/333bf5bd0b8c4e71a26b#ssh%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%A4%89%E6%9B%B4

最初の接続を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
```

# icmp攻撃対策
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
```

# DDos攻撃対策
アプリケーションに割り振られたポート番号などをここで指定してください。ポートを複数設定したい場合、`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を飛ばしてみると通信が遮断されると思います。

# 参考
https://qiita.com/nisyuu/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

誤字脱字、記事内容に間違いやご意見があれば遠慮なくお知らせください。