ipset と iptables + fail2ban を使用して、多数または少数の IP 範囲をブラックリストまたはホワイトリストに登録する方法

ipset と iptables + fail2ban を使用して、多数または少数の IP 範囲をブラックリストまたはホワイトリストに登録する方法

編集:

解決策を見つけたいという衝動が、時にはゆっくりと、しかし着実に解決策へと導くのに十分であるというのは驚くべきことです。また、質問を明確にするために何度も読み返すと、この「質問」が「単純な」質問の範囲、またはこのコミュニティで回答を得るという考え方を超えていることに気づきます。

iptables の運用概念をどんどん理解していくにつれて、今後数時間以内にこの質問の構造をまとめ直す予定です。理解の過程で、より具体的な質問もいくつか生まれました。これらの質問は、すぐにこのコミュニティに提供し、この質問にリンクします。


一言で言えば: 私の問題は、次のような適切なルールのセットを見つけることです。

  • 自分のルール
  • 失敗2バン
  • 追加のDNSブラックリストは連携して機能しますが、「私のルール」は、私の国をSSHのホワイトリストに登録し、他のすべての国をSSHでブロックすることも意味します。しかし許可する全てブラックリストに登録されているものを除く、DNS クエリの国/範囲/IP。

数字で見る:

  • sshの場合: 50の範囲をホワイトリストに登録またはブラックリスト約620,000範囲(ipdeny.comなどから作成)
  • DNSのブラックリストエントリ: 約140 (u32 ルールのセットスクリプト
  • 追加サービスに関する25+/-ルール(下記参照)

歌詞バージョン: 私は自分のニーズに合ったソリューションの実装に苦労しています。シナリオは次のとおりです。私は (今のところ DNS を想定) サーバーを持っています。bind ssh のほかに、sendmail、https、munin も考慮する必要があります。

これは一般的に簡単に達成できました。さらに、世界中から (d)dos 攻撃を受けたため、fail2ban をインストールしました。私の主な目的は、サーバーを可能な限りロックダウンすることでした。

私のアイデアは、私がアクセスできる ISP (DSL やモバイルなど) の可能な動的 DNS 割り当てに一致する、私の国の一部の IP 範囲のみをホワイトリストに登録することでした。 そうすれば、自分自身を締め出すことがなくなります。

私は自分の ISP のすべてのネット範囲を調べ、次のスクリプト/ルール セットを作成しました。

#ports:
#  22: SSH (#4,#5) (ssh)
#  25: SMTP (#20) (outgoing, sendmail for f2b report)
#  53: DNS (!!#16!! see end of #16 as differs for ns1&2) (outgoing, bind)
# 443: HTTPS (#10) (outgoing, dns-blacklist update)
#4949: munin (#26) (outgoing, sending client stats to server)

# Modify this file accordingly for your specific requirement.
# http://www.thegeekstuff.com: http://www.thegeekstuff.com/scripts/iptables-rules
# 1. Delete all existing rules
#iptables -F

# 2. Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# 4. Allow ALL incoming SSH
#iptables -A INPUT -i eth1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
#iptables -A OUTPUT -o eth1 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# 5. Allow incoming SSH only from a sepcific network (kabelBW/Unitymedia, Telekom, Accelerated)
# note: Using '-I' instead of '-A' to insert to top of INPUT chain to put rule in front of fail2ban!
iptables -A INPUT -i eth0 -p tcp -s 5.10.48.0/20    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 5.10.160.0/19   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 5.56.176.0/20   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 5.56.192.0/18   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 5.146.0.0/15    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 5.158.128.0/18  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 24.134.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 31.16.0.0/14    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 37.4.0.0/15     --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 37.24.0.0/16    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 37.49.0.0/17    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 37.114.96.0/19  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 37.201.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 37.209.0.0/17   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 46.5.0.0/16     --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 46.223.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 46.237.192.0/18 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 46.252.128.0/20 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 62.143.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 77.20.0.0/14    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 78.42.0.0/15    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 78.94.0.0/16    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 80.69.96.0/20   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 81.210.128.0/17 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 82.211.0.0/18   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 82.212.0.0/18   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 83.169.128.0/18 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 84.200.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 84.201.0.0/18   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 85.216.0.0/17   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 88.134.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 88.152.0.0/15   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 91.64.0.0/14    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 91.89.0.0/16    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 92.50.64.0/18   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 94.79.128.0/18  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 95.88.0.0/14    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 95.208.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 95.222.0.0/15   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 109.90.0.0/15   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 109.192.0.0/15  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 130.180.0.0/17  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 134.3.0.0/16    --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 146.52.0.0/16   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 149.172.0.0/16  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 176.198.0.0/15  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 178.24.0.0/14   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 178.200.0.0/14  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 188.192.0.0/14  --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s 217.8.48.0/20   --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

service fail2ban restart


# 10. Allow outgoing HTTPS
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

# 12. Ping from inside to outside
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# 13. Ping from outside to inside
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

# 14. Allow loopback access
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# 16. Allow outbound DNS
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

#Allow inbound DNS

iptables -A INPUT -p udp -s 0/0 --sport 1024:65535 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp --sport 53 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp -s 0/0 --sport 53 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp --sport 53 -d 0/0 --dport 53 -m state --state ESTABLISHED -j ACCEPT


# 20. Allow Sendmail or Postfix
iptables -A OUTPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT

# 26. Allow Munin Stats
iptables -A INPUT -p tcp --dport 4949 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 4949 -j ACCEPT

service munin-node restart
sh /root/update_domain_blacklist.sh

ルール セット #10 の前に fail2ban を再起動するのは、iptable から消去された後 (スクリプトの先頭で -F によってフラッシュされた後) にチェーンが正しく (再) 設定されていることを確認するためです。例外ルールを適用した後に再起動しないとサーバーに到達できないというエラーが表示される munin にも同じことが当てはまります。

/etc/rc.local 経由でルールを適用するつもりです。これは、fail2ban と munin のチェーンがすでに作成されていることを意味します。

私が実現したいファイアウォール チェック フローは次のとおりです: 要求は DNS ですか? -> (a); ssh ですか? -> (b); 他のサービスの 1 つですか? -> (c); 他に何かありますか? -> (d):

  • (a): ブラックリストに載っていない場合はDNSブラックリストスクリプトを提供する
  • (b): ブラックリストに載っていない場合、または私のネット範囲設定に従ってホワイトリストに載っている場合は、サービスを提供します。
  • (c):私が定義したルールに従ってサーブする
  • (d): DROP/TARPIT/その他ベストプラクティス
  • (b)の場合、さらにfail2banをパスする

問題点上記のルールに従って:

  • ホワイトリストのチェックの前に fail2ban が起動します -良い私のSSH部分については、悪い私のDNS部分:私の推測

次に、ipsetを使用して、50の範囲を除く「全世界」をブロック/ブラックリストに登録しようとしました。理論的には可能ですが、620kの範囲の解析には10分以上かかります。操作をキャンセルし、ホワイトリストの範囲に戻りました。次のアイデア: 50の範囲にipsetを使用し、ssh のリスト:

!/bin/bash
#Script to process ip ranges to ban using IPSet and IPTables

# 10. Allow outgoing HTTPS
iptables -I OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -I INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

# 12. Ping from inside to outside
iptables -I OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -I INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# 14. Allow loopback access
iptables -I INPUT -i lo -j ACCEPT
iptables -I OUTPUT -o lo -j ACCEPT

# 16. Allow outbound DNS
iptables -I OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -I INPUT -p udp -i eth0 --sport 53 -j ACCEPT

#Allow inbound DNS
iptables -I INPUT -p udp -s 0/0 --sport 1024:65535 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -I OUTPUT -p udp --sport 53 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
iptables -I INPUT -p udp -s 0/0 --sport 53 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -I OUTPUT -p udp --sport 53 -d 0/0 --dport 53 -m state --state ESTABLISHED -j ACCEPT

# 20. Allow Sendmail or Postfix #to mail.awib.it (82.211.19.134)
iptables -I OUTPUT -p tcp --dport 25 -j ACCEPT
iptables -I INPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT

# 26. Allow Munin Stats
iptables -I INPUT -p tcp --dport 4949 -j ACCEPT
iptables -I OUTPUT -p tcp --sport 4949 -j ACCEPT

#iptables -I OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
ipset create countryblock hash:net
while read line; do ipset add countryblock $line; done < blocklist.txt
iptables -A INPUT -m set ! --match-set countryblock src -j DROP

一方、「blocklist.txt」には、ホワイトリストに登録される 50 の範囲、またはその逆のブラックリストに登録される範囲が含まれています。しかし、そのセットの逆は、すべての DNS トラフィックがブロックされることを意味します...これは私をイライラさせます! :-D

しかし、何らかの理由で、サーバーにまったくアクセスできなかったか、その逆が機能しませんでした (ssh プロンプトを確認するためだけに、いくつかの web2ssh アプレットを試しました)。

また、対応する fail2ban createaction ルール定義もその構成で見つかりました。ただし、オーバーヘッドを削減するために、munin と f2b のデフォルト ルールをそのままにして、自分のルールと、場合によっては dns-blacklist スクリプトに必要な変更を適用したいと思っています。

この質問/リクエストは簡単ではないかもしれないし、単に fail2ban を使用しないのはなぜかと疑問に思うかもしれません。疑わしい動作があるかどうか知りたいので、ブロックされたホストのレポートを取得できるのは便利です。ただし、すべての外部ホストにこれを適用するつもりはありません (10 台を超えるサーバーで fail2ban を実行しているため、10 倍になります)。

もう 1 つのアプローチは、すべてのトラフィックを処理する専用のファイアウォール サーバー/ルーターです。ただし、これはかなり複雑なルール設定になるため、愚かな設定ミスやルールの誤りなどが原因で、すべてのサーバーを誤ってロックアウトすることは避けたいです。また、これでは、現在 10 台のサーバーすべてに分割されている無料トラフィックを超えてしまいます。

ルールを正しく整理するのを手伝ってくれるような、洞察力のあるオタクの友人が近くにいることを願っています。

この質問を不必要に膨らませる前に、私は現在待機しており、要求された情報を提供しています。

追伸:評判がないため、私は「ipset」タグを作成できないので、誰かが追加してくれるかもしれません。ありがとうございます!

答え1

すごく複雑そうですね…。

別のポートに移動するだけsshdで、セキュリティとパフォーマンスに大きな価値を見いだせると思います。munin

デフォルトと一致しないポートでこれらのサービスを実行すると、ブルート フォース/DOS トラフィックのほとんどが抑制されます。その後、Fail2ban は異常値を検出できるようになります。

customポートに移動すると、基本的に次のものが作成されます。

iptables -A "Anyone that doesn't know the correct ssh port" -j DROP

ポートへの接続試行をログに記録することはできます22が、ディスク領域をより有効に活用する方法が見つかると思います。

答え2

ipset create banned_hosts hash:net family inet hashsize 524288 maxelem 800000 counters comment
ipset create whitelist hash:net family inet hashsize 524288 maxelem 800000 counters comment

iptables -I INPUT 1 -m set --match-set banned_nets src -j DROP
iptables -I INPUT 2 -m set --match-set whitelist src -j ACCEPT

ipset add banned_hosts 171.248.31.131
ipset add banned_hosts 191.185.207.16
ipset add banned_hosts 45.247.22.251
ipset add banned_hosts 82.98.162.90
ipset add banned_hosts 125.227.181.216
ipset add banned_hosts 122.117.163.44

すべてを保存する ipset

ipset save >all.txt

すべてロード設定

ipset load <all.txt

関連情報