Fail2banは、サーバに対する悪意のある攻撃や不正アクセスの痕跡を探して、ログ情報から攻撃元のIPアドレスを自動遮断(BAN)するソフトウエアである。また、粘着質な度重なる攻撃に対して、より厳しい制裁(BAN)期間を設定することが可能である。
公式サイト : http://www.fail2ban.org/wiki/index.php/Main_Page
今回はこのFail2banを以下環境に導入して、サーバに対する不正アクセスのフィルタリングを実施。
◇ 導入環境:
OS : CentOS 7.6
ファイアウォール:Firewalld
◇ フィルタリング対象:
SSH
メールサーバ:postfix + dovecot
WEBサーバ:Apache2.4.x
・BASIC認証
・DDoS対策
・偽Google BOT対策
・特定ログ対処(403 / 404 等)
WORDPRESS
・WORDPRESSログイン認証
・WORDPRESSリモートコントロール機能
Fail2banインストール ( fail2ban.noarch 0:0.10.5-2.el7 )
※パッケージ取得にはEPELリポジトリを利用
# yum install --enablerepo=epel fail2ban fail2ban-systemd
Fail2ban設定ファイル構造
install_dir = /etc/fail2ban
├── action.d (アクション定義ファイル)
├── fail2ban.conf (全般設定)
├── fail2ban.d
├── filter.d(フィルター定義ファイル)
├── jail.conf(フィルターとアクションの定義ファイル)
├── jail.d(ユーザー定義ファイル)
│ ├── 00-firewalld.conf(firewalldの定義ファイル)
│ └── 00-systemd.conf(systemdの定義ファイル)
├── paths-common.conf (各種ログのパス定義)
└── paths-fedora.conf (FEDORAの各種ログのパス定義)※1
※1:インストールするディストリビューションによってconfファイル名が異なる
fail2banログファイル : /var/log/fail2ban.log
Fail2ban設定
注意事項:
Fail2banの各種設定ファイル「*.conf」は、アップグレードを容易にするため直接変更せずに、「*.local」ファイルを作成して変更を加えることが推奨されている。Fail2ban 起動時に設定ファイル「*.conf」をロードした後に、作成したユーザー定義「*.local」ファイルをオーバーライドする。
「*.local」ファイルでは変更する設定のみを指定。各設定ファイルは、[INCLUDES] 指定により、beforeで指定した設定ファイルを先に読み込み、afterで指定した設定ファイルを後に読み込む。そして、後で読み込んだ設定と重複する設定項目のみオーバーライドする。
◆CentOS版fail2banの場合、下記順番で設定ファイルをロードして重複する設定項目をオーバーライドする
・全般設定の定義ファイル
/etc/fail2ban/fail2ban.conf
/etc/fail2ban/fail2ban.localを作成して、重複項目について「fail2ban.conf」をオーバーライド
※下記の順番で設定ファイルを読み、重複する設定項目をオーバーライド
「fail2ban.conf」➡「fail2ban.local」
・アプリケーションの監視設定とアクションの定義ファイル
「paths-common.conf」➡「paths-fedora.conf」
▼
「paths-overrides.local」—- 「paths-common.conf」をオーバーライド
▼
「jail.conf」
▼
「jail.d/*.conf」
▼
「jail.local」 —- 「jail.conf」をオーバーライド
▼
「jail.d/*.local」
おおまかな設定の流れ
① fail2ban.confを参照して、「fail2ban.local」を作成
②「paths-common.conf」「paths-fedora.conf」を参照、環境に合わせ「paths-overrides.local」を作成
③「firewallcmd-common.local」「firewallcmd-ipset.local」をそれぞれ作成
④ 環境に合わせ必要なフィルターが存在するか確認して、追加および編集が必要なフィルターを「*.local」ファイルとして保存
⑤「jail.conf」を参照して、「jail.local」を作成
Fail2banコマンド一覧
・Fail2banデーモン起動 # systemctl start fail2ban ・Fail2banデーモン停止 # systemctl stop fail2ban ・Fail2banデーモン再起動 # systemctl restart fail2ban ・Fail2ban設定ファイル再読み込み # systemctl reload fail2ban ・Fail2banデーモンのステータス表示 # systemctl status fail2ban ・指定IPアドレスをBAN # fail2ban-client set <フィルタ-名> banip <IPアドレス> 例:SSH用に作成したフィルター規則でIPアドレス「10.8.25.2」をBAN # fail2ban-client set ssh banip 10.8.25.2 ・指定IPアドレスをBAN解除 # fail2ban-client set <フィルタ-名> unbanip <IPアドレス> 例:SSH用に作成したフィルター規則でBANされたIPアドレス「10.8.25.2」をBAN解除 # fail2ban-client set ssh unbanip 10.8.25.2 ・指定フィルターの動作確認 # fail2ban-regex <ログファイルパス> <フィルタ-パス> 例:SSH用に作成したフィルターが正しくパターンマッチングして文字列を検出できるか確認 # fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.local ・フィルター定義されている正規表現の確認 # fail2ban-client get <フィルタ-名> failregex 例:フィルターのパターンがどのような正規表現で書かれているか確認することができる # fail2ban-client get apache-ddos failregex The following regular expression are defined: `- [0]: ^(?:\[?(?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):)))\]?|(?P<dns>[\w\-.^_]*\w)) -.*"(GET|POST).*
Fail2ban起動設定およびステータス確認
fail2ban自動起動設定
# systemctl enable fail2ban Created symlink from /etc/systemd/system/multi-user.target.wants/fail2ban.service to /usr/lib/systemd/system/fail2ban.service.
fail2ban起動およびステータス確認
fail2ban起動 # systemctl start fail2ban # fail2ban起動確認 ※Active: active (running)であれば正常起動 # systemctl status fail2ban ● fail2ban.service - Fail2Ban Service Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled) Active: active (running)
Fail2ban設定
①全般設定
「fail2ban.local」を作成
※フィルター作成時は、ログレベルを「INFO」の方が出力が多くなるため色々便利
# vi /etc/fail2ban/fail2ban.local [DEFAULT] #ログレベル loglevel = NOTICE #BANユーザー用データベースの削除(40日) dbpurgeage = 3456000
②各種ログファイル出力先を指定
「paths-overrides.local」を作成
※各ログの保存場所は環境で異なる。[ paths-common.conf ] [ paths-fedora.conf ] の2つを参照して、実際のパスと異なる部分を下記ファイルに定義する
# vi /etc/fail2ban/paths-overrides.local [DEFAULT] #paths-common.conf apache_error_log = /var/log/httpd/*error_log apache_access_log = /var/log/httpd/*access_log
③ACTION設定
※CentOS7なので「firewalld」をそのまま使用
「action.d」に設定ファイルがあるので、差分が生じる場合は下記設定ファイルを作成
・ファイアウォール共通設定、「firewallcmd-common.local」を作成
アタッカーにエラーメッセージを返したくないので、IPパケットを全てDROP(破棄)
# vi /etc/fail2ban/jail.d/firewallcmd-common.local [Init] blocktype = DROP rich-blocktype = drop [Init?family=inet6] rejecttype = drop
・「firewallcmd-ipset.local」を作成
banactionで呼び出された際の制御について記述
# vi /etc/fail2ban/jail.d/firewallcmd-ipset.local [Definition] actionstart = ipset create <ipmset> hash:ip timeout <bantime><familyopt> firewall-cmd --direct --add-rule --permanent <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype> firewall-cmd --reload actionstop = firewall-cmd --direct --remove-rule --permanent <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype> firewall-cmd --reload <actionflush> ipset destroy <ipmset>
④フィルタ設定
※自分の環境に必要なフィルターを用意する。環境によってログファイルの出力方法も異なるため、最適なフィルターは自身で詰めるようにして、「/etc/fail2ban/jail.d/*.local 」として作成
◇以下フィルターは当方の環境下で設定変更なしで使用できたデフォルトフィルターである。
・フィルター名:sshd SSH(TCP/22番ポート)認証エラーを検知 # vi /etc/fail2ban/filter.d/sshd.conf ・フィルター名:dovecot POP3(TCP/110番ポート)認証エラーを検知 # vi /etc/fail2ban/filter.d/dovecot.conf
◇不足フィルターは作成する
・フィルター名:apache-auth
BASIC認証エラーを繰り返すユーザーをBAN
# vi /etc/fail2ban/filter.d/apache-auth.local [Definition] failregex = ^<HOST>:*.* authentication failure.* ignoreregex =
・フィルター名:apache-ddos
サーバに対して必要以上に負荷を繰り返すユーザーをBAN
# vi /etc/fail2ban/filter.d/apache-ddos.local [Definition] failregex = ^<HOST> -.*"(HEAD|GET|POST).* ignoreregex = \.(?i)(jpe?g|gif|png|bmp|pdf|js|css|woff|eot|ttf|ico|txt|xml|swf|xlsx?|docx?|pptx?)
・フィルター名:blacklist
403/404を多発させていたり、サーバに対し変なアクションをしているユーザーをBAN
# vi /etc/fail2ban/filter.d/blacklist.local [Definition] failregex = ^<HOST> -.*"(HEAD|GET|POST).*403 .*$ ^<HOST> -.*"(HEAD|GET|POST).*404 .*$ ^<HOST> -.*"(GET|POST).*die .*$ ^<HOST> -.*"(GET|POST).*fetch.*$ ^<HOST> -.*"(GET|POST).*phpdie.*$ ^<HOST> -.*"(GET|POST).*XDEBUG_SESSION_START=phpstorm.*$ ^<HOST> -.*phpunit.*$ ignoreregex = \.(?i)(jpe?g|gif|png|bmp|pdf|js|css|woff|eot|ttf|ico|txt|xml|swf|xlsx?|docx?|pptx?)
・フィルター名:apache-fakegooglebot
偽GooglebotをBAN
# vi /etc/fail2ban/filter.d/apache-fakegooglebot.local [INCLUDES] before = apache-common.conf [Definition] failregex = ^<HOST> .*POST .*Googlebot.*$ ignoreregex =
・フィルター名:wplogin
WORDPRESSで不正ログイン試行するユーザーをBAN
基本ignoreipで登録したIPアドレス以外全部不正アクセスとみなす
# vi /etc/fail2ban//filter.d/wplogin.local [Definition] failregex = ^<HOST> -.*"POST .*wp-login.php HTTP.*$ ^<HOST> -.*"GET .*wp-login.php .*404 .*$ ^<HOST> -.*"GET .*cp_login .*404 .*$ ignoreregex =
・フィルター名:wp-xmlrpc
XMLを使用して怪しいアクションをしているユーザーをBAN
# vi /etc/fail2ban/filter.d/wp-xmlrpc.local [Definition] failregex = ^<HOST> -.*"(GET|POST).*xmlrpc.php.*$ ignoreregex =
・フィルター名:postfix-sasl
Postfixで認証エラーを多発させているユーザーをBAN
# vi /etc/fail2ban/filter.d/postfix-sasl.local [INCLUDES] before = common.conf [Definition] _daemon = postfix(-\w+)?/(?:submission/|smtps/)?smtp[ds] failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$ ignoreregex = authentication failed: Connection lost to authentication server$ [Init] journalmatch = _SYSTEMD_UNIT=postfix.service
⑤Jail設定
不正アクセス元の調査のためドメイン登録情報検索コマンド導入
# yum -y install --enablerepo=epel jwhois
backend を切り替えて、ログファイルをモニタリングするため「pyinotify」導入
# yum -y install python-inotify
Jail.confとの設定を差分管理するため「jail.local」作成
[DEFAULT] ignoreip = 127.0.0.1/8 <除外IPアドレス(例:192.168.100..0/24)> destemail = <送信先メールアドレス> sender = <送信元IPアドレス(例:f2b@localhost)> mta = postfix banaction = firewallcmd-ipset banaction_allports = firewallcmd-allports action = %(action_mw)s ########## SSH ########## [sshd] enabled = true port = ssh logpath = %(sshd_log)s bantime = 2592000 findtime = 7200 maxentry = 3 backend = systemd ######### MAIL ########## [postfix-sasl] enabled = true port = smtp,submission logpath = %(postfix_log)s bantime = 7200 findtime = 600 maxretry = 6 backend = systemd [dovecot] enabled = true port = pop3,submission logpath = %(dovecot_log)s bantime = 7200 findtime = 600 maxretry = 6 backend = systemd ######### HTTPD ########## [apache-auth] enabled = true port = http,https logpath = %(apache_error_log)s bantime = 7200 findtime = 10 maxretry = 5 backend = pyinotify [apache-ddos] enabled = true port = http,https logpath = %(apache_access_log)s bantime = 3600 findtime = 3 maxretry = 10 backend = pyinotify [apache-fakegooglebot] enabled = true port = http,https logpath = %(apache_access_log)s bantime = 43200 findtime = 7200 maxretry = 2 backend = pyinotify [blacklist] enabled = true port = http,https logpath = %(apache_access_log)s bantime = 10800 findtime = 120 maxretry = 3 backend = pyinotify ####### WORDPRESS ######## [wplogin] enabled = true port = http,https logpath = %(apache_access_log)s bantime =2592000 findtime = 10800 maxretry = 3 backend = pyinotify [wp-xmlrpc] enabled = true port = http,https logpath = %(apache_access_log)s bantime = 2592000 findtime = 43200 maxretry = 2 backend = pyinotify ########### 再犯防止 ######## [recidive] enabled = true filter = recidive logpath = /var/log/fail2ban/fail2ban.log action = firewallcmd-allports[name=recidive,protocol=all] postfix-whois-lines[name=recidive, dest=webmaster@net-powered.com] bantime = 2592000 findtime = 259200 maxretry = 3
設定反映
# systemctl restart fail2ban
起動時のエラー確認
# less +F -S /var/log/fail2ban.log