サーバーへの DoS 攻撃を軽減する

サーバーを立ち上げていると、攻撃を受けることが多々ある。SSH/POP/IMAP のサーバーに対して辞書攻撃が行われたり、SMTP サーバーに対して第三者リレーを試みたり、SMTP AUTH を突破しようとする試みも多い。攻撃は単純なものが多く、設定がしっかりしており、十分に複雑なパスワードが設定されていればサーバーを悪用される可能性は低い。しかし、攻撃を受けている時はサーバーへの接続要求が非常に多くなるため、サーバーに負荷がかかる。サーバーのスペックに余裕があれば気づかないこともあるが、CPU やメモリーのリソースが限られた VPS では、SSH でログインすることもままならないこともあり、(攻撃者は意図していないけれど)DoS 攻撃を受けているのと同じ状態になる。

月々2,000円ぐらいで始める公開サーバーiptables の設定(2)で iptables/ip6tables を使った。iptables/ip6tables で送信元 IP アドレスを元に制限できれば一番よいが、難しい場合もある。たとえば、スマートフォンでメールを読みたいという要求に応えるのであれば、IP アドレスで制限ができない。別の対処策が必要だ。

DoS 攻撃になるほど負荷をかける攻撃者は、基本的に間断なく攻撃を行う。間断なく攻撃を行われてしまうと、サーバーが過負荷になりサービスを提供できなくなる。そこで、間断なく接続できないように、iptables を使って接続回数を制限する。なお、例に示している iptables のルールは、iptables の設定(2)で使用した /etc/sysconfig/iptables に記述する形式になっている。

limit モジュール

limit モジュールは、単位時間あたり制限された回数だけマッチする。単位時間内の接続回数を制限するために利用できる。オプションは以下の通りだ。

  • –limit rate : 単位時間あたりの平均マッチ回数の最大値。rate には、/second、/minute、/hour、/dayを使用できる
  • –limit-burst number : パケットがマッチする回数の最大初期値

たとえば、SSH がデフォルトの22番ポートで待ち受けを行っており、「-m limit –limit 1/m –limit-burst 1」と指定すると、

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m limit --limit 1/m --limit-burst 1 -j ACCEPT
...
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

SSH サーバーへの接続は最大1コネクション、次の接続は1分後のパケットのみマッチするようになる。
オプションはわかりにくいので、上記の設定を例に、(厳密さはかけるが)クライアントを操作している人間の立場でざっくりと説明してみる。–limit-burst で指定しているのは、SSH のポートに接続可能なクライアントの数になる。1クライアントは接続できるが、その後は1分経たないと次のクライアントは接続できない。「1分経たないと」という指定は、–limit で設定している 1/m になる。「–limit 1/m –limit-burst 3」とすると、1分以内に3クライアント接続すると、4番目のクライアントは1分後にしか接続できないということだ。
なお、limit モジュールで定義しているのは「許可」の設定なので、チェインのデフォルトが「DROP」もしくは、最後に「すべてを拒否」するルールがないと有効にならない。

hashlimit

hashlimit は、limit モジュールと同様に単位時間あたり制限された回数だけマッチするが、IP アドレスやポート番号ごとに管理できる点が異なる。たとえば、拠点のネットワークからは10コネクションまで、外部からは1秒間に1コネクションまでといったような制限を行える。重要なオプションは以下の通り。

  • –hashlimit rate : 単位時間あたりの平均マッチ回数の最大値
  • –hashlimit-burst num : パケットがマッチする回数の最大初期値
  • –hashlimit-mode {srcip|srcport|dstip|dstport} : パケットのマッチを送信元 IP/PORT、宛先 IP/PORT のどれで行うかを指定する。カンマ区切りで複数指定可能
  • –hashlimit-name foo : ハッシュテーブル名(proc/net/ipt_hashlimit/foo)
  • –hashlimit-htable-gcinterval msec : ハッシュテーブル中のレコードの有効期間
  • –hashlimit-srcmask prefix : hashlimit-mode に srcip が指定されている場合、送信元 IP アドレス/ネットワークを指定

たとえば、SSH がデフォルトの22番ポートで待ち受けを行っており、「-m hashlimit –hashlimit-name sshd_limit –hashlimit 1/m –hashlimit-burst 1 –hashlimit-mode srcip –hashlimit-htable-expire 120000」と指定すると、

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m hashlimit --hashlimit-name sshd_limit --hashlimit 1/m --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT
...
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

同一 IP アドレスからの SSH サーバーへの接続は最大1コネクション、次の接続は1分後のパケットのみマッチするようになる。同一 IP アドレスからの接続を管理するように指定しているのは、「–hashlimit-mode srcip」というオプションの指定だ。

iptables の設定を組み合わせる

iptables は、指定した順にルールを適用していく。ルールをうまく組み合わせれば、信頼できるネットワークからのアクセスは無制限にアクセスを許可し、信頼できないネットワークからのアクセスは接続数を制限することができる。SSH サーバーがデフォルトのポートで待ち受けしている前提で、例を2つ挙げる。

攻撃元の IP アドレスがランダムな場合は、limit モジュールを使えばよいだろう。以下の例では、192.168.1/24 のネットワークからの接続は無制限に許可するが、その他のネットワークからのアクセスは、1分間に最大1コネクションしか許可しない。

-A RH-Firewall-1-INPUT -s 192.168.1/24 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m limit --limit 1/m --limit-burst 1 -j ACCEPT
...
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

攻撃元の IP アドレスが固定されている、もしくは、異なる IP アドレスから多くのアクセスを許可する必要がある場合は、hashlimit を使う。たとえば、POP/IMAP サーバーでスマートフォンからの接続を許可する場合は、hashlimit を使う方がよいだろう。以下の例では、192.168.1/24 のネットワークからの接続は無制限に許可するが、その他のネットワークからの同一 IP アドレスからのアクセスは、1秒間に最大1コネクションしか許可しない。

-A RH-Firewall-1-INPUT -s 192.168.1/24 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m hashlimit --hashlimit-name sshd_limit --hashlimit 1/s --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT
...
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.