CentOS7にFail2ban導入①


Ffail2banail2banは、サーバに対する悪意のある攻撃や不正アクセスの痕跡を探して、ログ情報から攻撃元の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