blog

システム運用|fail2banとFirewallDのブラックリストでシステムを守る

公開SSHアクセスでサーバを運用している場合、おそらく悪意のあるログインの試みに遭遇したことがあるでしょう。この記事では、侵入者のシステム侵入を防ぐために2つのユーティリティを使う方法を説明します。...

Oct 23, 2025 · 10 min. read
シェア

公開SSHアクセスでサーバを運用している場合、悪意のあるログイン試行に遭遇したことがあるかもしれません。この記事では、2つのユーティリティを使って侵入者の侵入を防ぐ方法を説明します。

また、あまり旅行に行かず、基本的に1つか2つの国に滞在するのであれば、FirewallDを設定することで、許可することができます。

まず、このようなアプリケーションに馴染みのない方のために、いくつかの用語を紹介しましょう:

fail2ban: 認証に何度も失敗するホストをブロックするデーモンです。指定された回数失敗すると、設定された期間、特定の IP アドレスをブロックするファイアウォールルールを追加します。

FirewallD: ダイナミックファイアウォールを提供する D-Bus インタフェースを持つファイアウォールデーモンです。従来のiptablesを使うことに決めていない限り、サポートされているすべてのFedoraとCentOSにFirewallDがすでにインストールされています。

仮定

  • ホストシステムにはインターネット接続があり、インターネットに直接接続されているか、DMZを通して接続されているか、ルーターからポート転送されています。
  • ほとんどのことは他のシステムにも当てはまるかもしれませんが、この記事では現在のシステムが Fedora または RHEL/CentOS バージョン 8 であることを前提としています。CentOS では、Fedora EPEL リポジトリを sudo dnf install epel-release で有効にする必要があります。

インストールと設定

フェイルツーバン

すでに SSH アクセスを許可する Firewalld ゾーンが存在する可能性がありますが、 sshd サービス自体はデフォルトでは有効になっていません。手動で起動し、起動時に恒久的に有効にしないでください:

  1. $ sudo systemctl start sshd

または、システム起動時に有効にし、同時に起動します:

  1. $ sudo systemctl enable --now sshd

次のステップは、fail2banのインストール、設定、有効化です。いつものように、インストールはコマンドラインから行うことができます:

  1. $ sudo dnf install fail2ban
  1. # cat /etc/fail2ban/jail.local
  2. [DEFAULT]
  3. # "bantime" is the number of seconds that a host is banned.
  4. bantime = 1d
  5. # A host is banned if it has generated "maxretry" during the last "findtime"
  6. findtime = 1h
  7. # "maxretry" is the number of failures before a host get banned.
  8. maxretry = 5

平たく言うと、直近1時間に5回試行されると、そのIPは1日間ブロックされます。複数回ブロックされたIPのブロック時間を長くするオプションもありますが、それはまた別の記事で。

  1. # cat /etc/fail2ban/jail.d/sshd.local
  2. enabled = true

それはとても簡単です! 設定の多くは、Fedora用にビルドされたパッケージで既に処理されています。次にfail2banサービスを有効にして開始します:

  1. $ sudo systemctl enable --now fail2ban

すぐにエラーが出なければいいのですが、そうでない場合は、以下のコマンドでfail2banの状態を確認してください:

  1. $ sudo systemctl status fail2ban

正しく起動しなければ、起動するはずです:

  1. $ systemctl status fail2ban
  2. fail2ban.service - Fail2Ban Service
  3. Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled)
  4. Active: active (running) since Tue CDT; 5s ago
  5. Docs: man:fail2ban(1)
  6. Process: 11230 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)
  7. Main PID: 11235 (f2b/server)
  8. Tasks: 5 (limit: 4630)
  9. Memory: 12.7M
  10. CPU: 109ms
  11. CGroup: /system.slice/fail2ban.service
  12. └─11235 /usr/bin/python3 -s /usr/bin/fail2ban-server -xf start
  13. Jun :40 localhost.localdomain systemd[1]: Starting Fail2Ban Service
  14. Jun :40 localhost.localdomain systemd[1]: Started Fail2Ban Service.
  15. Jun :41 localhost.localdomain fail2ban-server: Server ready

fail2banが起動したばかりであれば、fail2banが興味深い情報を表示することはないでしょうが、fail2banのステータスをチェックし、"jail "が有効になっていることを確認するには、enterを入力してください:

  1. $ sudo fail2ban-client status
  2. |- Number of jail: 1
  3. `- Jail list: sshd

sshd "jail" の親の状態も表示されます。複数の jail が有効になっている場合、それらはここに表示されます。

  1. $ sudo fail2ban-client status sshd
  2. Status for the jail: sshd
  3. |- Filter
  4. | |- Currently failed: 8
  5. | |- Total failed: 9349
  6. | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
  7. `- Actions
  8. |- Currently banned: 101
  9. |- Total banned: 486
  10. `- Banned IP list: ...

fail2banログファイルの侵入試行を監視するには、ログを「テーリング」します:

  1. $ sudo tail -f /var/log/fail2ban.log

tailは素晴らしいコマンドラインツールで、デフォルトではファイルの最後の10行を表示します。fを追加すると、ファイルの末尾を表示するようになり、まだ書き込まれているファイルを見るのに便利です。

出力には実際のIPがあるので、サンプルはここでは提供しませんが、読むことはできます。INFO行は通常、ログインの試みです。特定のIPアドレスから十分な試行が行われた場合、IPアドレスが禁止されたことを示すNOTICE行が表示されます。禁止時間に達すると、禁止解除を示すNOTICE行が表示されます。

ファイアウォールDの設定

受動的か能動的か?

個々のIPアドレスをパッシブにブラックリスト化するか、発信国に基づいてサブネットを恒久的にアクティブにブラックリスト化するかです。

パッシブアプローチの場合、fail2banがしばらく実行されたら、悪者を確認するために sudo fail2ban-client status sshd 実行するのがよいでしょう。おそらく禁止されたIPアドレスがたくさんあるでしょう。出力には興味深い情報がたくさんあるかもしれませんが、この方法では、発信国だけが重要です。物事をシンプルにするために、国以外のすべての情報をフィルタリングしましょう。

この例では、いくつかの有名なドメイン名を使用します:

  1. $ whois google.com | grep -i country
  2. Registrant Country: US
  3. Admin Country: US
  4. Tech Country: US
  1. $ whois rpmfusion.org | grep -i country
  2. Registrant Country: FR
  1. $ whois aliexpress.com | grep -i country
  2. Registrant Country:

grep -iを使う理由は、grepを大文字小文字を区別しないようにするためで、ほとんどのエントリーは "Country "を使っていますが、いくつかのエントリーはすべて小文字の "country "を使っています!.

侵入を試みた国がわかったところで、問題は、"その国からこのコンピュータに接続する正当な理由がある人がいるかどうか "です。答えがノーであれば、その国全体をブロックしても構わないはずです。

機能的には、能動的なアプローチは受動的なアプローチと大差ありませんが、一部の国からの侵入の試みは非常に一般的です。システムがそのような国でホストされておらず、そのような国からのクライアントもいないのであれば、今すぐブラックリストに入れて待ってみてはいかがでしょうか。

ブラックリストスクリプトと設定

では、どのようにするのでしょうか?FirewallDのipsetを使って、可能な限りプロセスを自動化するために以下のスクリプトを開発しました:

  1. #!/bin/bash
  2. # Based on the below article
  3. # https://..////------st
  4. # Source the blacklisted countries from the configuration file
  5. . /etc/blacklist-by-country
  6. # Create a temporary working directory
  7. ipdeny_tmp_dir=$(mktemp -d -t blacklist-XXXXXXXXXX)
  8. pushd $ipdeny_tmp_dir
  9. # Download the latest network addresses by country file
  10. curl -LO http://..////-..gz
  11. tar xf all-zones.tar.gz
  12. # For updates, remove the ipset blacklist and recreate
  13. if firewall-cmd -q --zone=drop --query-source=ipset:blacklist; then
  14. firewall-cmd -q --permanent --delete-ipset=blacklist
  15. # Create the ipset blacklist which accepts both IP addresses and networks
  16. firewall-cmd -q --permanent --new-ipset=blacklist --type=hash:net \
  17. --option=family=inet --option=hashsize=4096 --option=maxelem= \
  18. --set-description="An ipset list of networks or ips to be dropped."
  19. # Add the address ranges by country per ipdeny.com to the blacklist
  20. for country in $countries; do
  21. firewall-cmd -q --permanent --ipset=blacklist \
  22. --add-entries-from-file=./$country.zone && \
  23. echo "Added $country to blacklist ipset."
  24. # Block individual IPs if the configuration file exists and is not empty
  25. if [ -s "/etc/blacklist-by-ip" ]; then
  26. echo "Adding IPs blacklists."
  27. firewall-cmd -q --permanent --ipset=blacklist \
  28. --add-entries-from-file=/etc/blacklist-by-ip && \
  29. echo "Added IPs to blacklist ipset."
  30. # Add the blacklist ipset to the drop zone if not already setup
  31. if firewall-cmd -q --zone=drop --query-source=ipset:blacklist; then
  32. echo "Blacklist already in firewalld drop zone."
  33. echo "Adding ipset blacklist to firewalld drop zone."
  34. firewall-cmd --permanent --zone=drop --add-source=ipset:blacklist
  35. firewall-cmd -q --reload
  36. rm -rf $ipdeny_tmp_dir

これは /usr/local/sbinにインストールし、実行可能にすることを忘れないでください!

  1. $ sudo chmod +x /usr/local/sbin/firewalld-blacklist

次に、設定ファイル /etc/blacklist-by-country作成します:

  1. # Which countries should be blocked?
  2. # Use the two letter designation separated by a space.
  3. countries=""

一方、もう一方のプロファイル /etc/blacklist-by-ip、追加フォーマットなしで1行にIPが1つだけです。

この例では、ipdenyのゾーンファイルから無作為に10カ国を選択しています:

  1. # ls | shuf -n 10 | sed "s/\.zone//g" | tr ' ' ' '
  2. nl ee ie pk is sv na om gp bn

あとは、設定ファイルに少なくとも1つの国を追加すれば、すぐに実行できます!

  1. $ sudo firewalld-blacklist
  2. % Total % Received % Xferd Average Speed Time Time Time Current
  3. Dload Upload Total Spent Left Speed
  4. 4 0 --:--:-- --:--:-- --:--:-- 1014
  5. 0 9k 0 --:--:-- --:--:-- --:--:-- 989k
  6. Added nl to blacklist ipset.
  7. Added ee to blacklist ipset.
  8. Added ie to blacklist ipset.
  9. Added pk to blacklist ipset.
  10. Added is to blacklist ipset.
  11. Added sv to blacklist ipset.
  12. Added na to blacklist ipset.
  13. Added om to blacklist ipset.
  14. Added gp to blacklist ipset.
  15. Added bn to blacklist ipset.
  16. Adding ipset blacklist to firewalld drop zone.
  17. success

FirewallD のブラックリストが成功したことを確認するには、ドロップゾーンと blacklist チェックしてください。

  1. $ sudo firewall-cmd --info-zone=drop
  2. drop (active)
  3. target: DROP
  4. icmp-block-inversion: no
  5. interfaces:
  6. sources: ipset:blacklist
  7. services:
  8. ports:
  9. protocols:
  10. masquerade: no
  11. forward-ports:
  12. source-ports:
  13. icmp-blocks:
  14. rich rules:
  15. $ sudo firewall-cmd --info-ipset=blacklist | less
  16. blacklist
  17. type: hash:net
  18. options: family=inet hashsize=4096 maxelem=
  19. entries:

2番目のコマンドは、ブロックされた国に基づいて追加され、非常に長くなる可能性があるすべてのサブネットを出力します。

で、どうすればいいの?

最初のうちは監視の頻度が高くなりますが、ブラックリストが増えるにつれて、侵入の試行回数は時間の経過とともに減少するはずです。そのときの目標は、積極的な監視よりもむしろ保守です。

記事を全部読んでよかったと思いませんか?あとはサービスファイルとタイマーを /etc/systemd/system/ダウンロードし、タイマーを有効にするだけです:

  1. $ sudo systemctl daemon-reload
  2. $ sudo systemctl enable --now firewalld-blacklist.timer

経由:

Read next

ソフトウェア開発|Git varbasesで履歴を変更する!

Gitの中心にある付加価値の一つは、履歴を編集できることです。履歴を神聖な記録として扱うバージョン管理システムとは異なり、Gitでは履歴を必要に応じて変更することができます。

Oct 23, 2025 · 18 min read