Firewalldとfail2banを連携させる。

CentOS7.4の環境でFirewalldとfail2banを連携させてみようと思います。Firewalldで公開しているsshサービスに対してfail2banが実行されるようにします。なおsshの公開ポートは「22」から「50000」に変更しています。rootユーザーで作業します。
前回の記事の続きです。

1. fail2banのインストール

fail2banはepelリポジトリにあるため、まずepelリポジトリのインストールを行います。それからfail2banのインストールを行います。

epelリポジトリのインストール
# yum install epel-release

fail2banのインストール
# yum install fail2ban fail2ban-systemd

2. fail2banの設定ファイルの確認

fail2banをインストールすると「/etc/fail2ban/jail.d」配下に「00-firewalld.conf」、「00-systemd.conf」というファイルができます。それぞれのファイルには以下のような記載があります。

00-firewalld.confの記載内容
====================
[DEFAULT]
banaction = firewallcmd-ipset
====================

00-systemd.confの記載内容
====================
[DEFAULT]
backend=systemd
====================

上記は「fail2banがbanしたときにfirewalldと連携する」および「fail2banがsystemdとも連携する」という設定の記載です。今回はsshのポートを変えているので、その情報もfail2banの設定ファイルに追記する必要があります(後述)。

3. fail2banの設定ファイルの修正

「/etc/fail2ban/jail.d」配下に「00-sshd.conf」というファイルを新規に作成して、以下の内容を書き込みます。

# cd /etc/fail2ban/jail.d
# vi 00-sshd.conf

書き込む内容
====================
[sshd]
enabled = true
port = 50000
blocktype = DROP
====================

「enabled = true」とすることでfail2banでsshの監視を有効にします。「port = 50000」というのはfail2banがsshのデフォルトポートを「22」ではなく「50000」として認識するようにする設定です。最後の「blocktype = DROP」というのはbanの規定回数に達したときにパケットをREJECT(拒否)ではなくDROP(破棄) するという設定です。DROPに変えている理由は、REJECTだと送信元のIPにエラーメッセージを返してしまうためbanしたことを教えてしまうことになり、セキュリティ上良くないからです。

ほかにも「00-sshd.conf」にfindtime、maxRetry、bantimeを設定できます(findtime、maxRetry、bantimeは /etc/fail2ban/jail.conf にデフォルト値が定義されていますが上書きできます)。ちなみにfindtime、maxRetry、bantimeの意味は、findtime秒内にmaxRetry回のsshログインの失敗をしたら、bantime秒ブロックさせる、ということです。

4. fail2banの起動

設定ファイルが作成できたのでfail2banを起動させます。

fail2banの起動
# systemctl start fail2ban

fail2banの自動起動の設定
# systemctl enable fail2ban

fail2banが起動するとsshのログインの監視が始まります。

5. 実際のbanとbanの解除

試しにsshのログインを(規定回数以上)間違えてbanされたかどうか確認してみました。banが発動するとfail2banのログ「/var/log/fail2ban.log」に「NOTICE [sshd] Ban 192.168.1.1」(192.168.1.1はIPアドレス)のログが出ました。banした内容を確認してみます。

banした内容の確認
# fail2ban-client status sshd

結果は以下のように表示されます。


Status for the jail: sshd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	0
|  `- Journal matches:	_SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned:	1
   |- Total banned:	1
   `- Banned IP list:	192.168.1.1

手動でbanされたIPアドレスを解除してみます。

banされたIPアドレスの解除
# fail2ban-client set sshd unbanip 192.168.1.1
※「192.168.1.1」はbanされたIPアドレス

もう一度「fail2ban-client status sshd」でbanの状態を確認します。IPアドレスが解除されているのがわかります。


# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	0
|  `- Journal matches:	_SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned:	0
   |- Total banned:	1
   `- Banned IP list:	

sshのポートを変更したときのFirewalldとの連携方法

sshのポートを変更してFirewalldで通信できる設定について書いてみます。環境はCentOS7.4です。rootユーザーで作業します。

1. Firewalldの停止

作業を始める前にFirewalldの起動確認を行い、起動している場合は停止します。

Firewalldの起動の確認
# systemctl is-active firewalld

「active」となっている場合は起動していますので以下のコマンドで停止させます。

Firewalldの停止
# systemctl stop firewalld

2. sshのポート変更

sshのデフォルトでは22番ポートを使用しますがインターネット上では攻撃されやすいためsshのポートを「22」から変更します。今回は「50000」ポートに変更するものとします。

「/etc/ssh」配下の sshd_config を編集します(編集する前にバックアップを取っておきます)。sshd_config に「Port 22」と記載されている箇所があるのでテキストエディタ(viなどで)そこを修正します。

バックアップ
# cd /etc/ssh
# cp -p sshd_config sshd_config.bkup

コンフィグファイルの修正
# vi sshd_config

修正前
Port 22
 ↓
修正後
Port 50000

修正が終わったら設定を反映させるためにリロードをします。

設定のリロード
# systemctl reload sshd

3. デバイスのゾーンの設定

デバイスのゾーンの設定にはnmcliを使いますが、その前にネットワークマネージャの起動を行います(nmcliはネットワークマネージャが起動していないと使えません)。

ネットワークマネージャの起動確認
# systemctl is-active NetworkManager

「active」となっている場合は起動しています。停止している場合はネットワークマネージャを起動します。

ネットワークマネージャの起動
# systemctl start NetworkManager

nmcliでデバイスのゾーンがデフォルトになっていることを確認します。まずデバイスのコネクションIDを確認します。

コネクションIDの確認
# nmcli connection

「nmcli connection」を実行すると、NAME、UUID、TYPE、DEVICEの情報が表示されます。コネクションIDはNAMEに表示されたものが該当します。UUIDは一意に識別するための値、TYPEはイーサネットや無線LANなどの種類、DEVICEはデバイス名となります。コネクションIDをもとに接続プロファイルの確認を行います。

接続プロファイルの確認
# nmcli connection show "コネクションID"

「connection.zone:」という項目が何も設定されていない(ハイフンとなっている)場合はデバイスのゾーンはデフォルトゾーンとなっています。もしデバイスにゾーンが設定されている場合はデフォルトに戻します(設定を明示的にクリアします)。

デバイスのゾーンの変更
# nmcli connection modify "コネクションID" connection.zone ""
# nmcli connection up "コネクションID"

4. Firewalldのポート変更

sshのポートを「22」から「50000」に変更しているためFirewalldの認識するポートも変更します。「/usr/lib/firewalld/services」配下にある ssh.xml を「/etc/firewalld/services」配下にコピーします(「/usr/lib/firewalld/services」配下のファイルを直接編集することは推奨されていません、「/etc/firewalld/services」配下のファイルが先に読み込まれるためコピーをしてこちらを編集します)。

ssh.xml のコピー
# cd /etc/firewalld/services
# cp -p /usr/lib/firewalld/services/ssh.xml ./

ssh.xml に「port="22"」と記載されている箇所があるのでテキストエディタ(viなどで)そこを修正します。

XMLファイルの修正
# vi ssh.xml

修正前
<port protocol="tcp" port="22"/>
 ↓
修正後
<port protocol="tcp" port="50000"/>

5. Firewalldの起動

sshとFirewalldのポートをあわせたのでFirewalldの起動を行います(sshとFirewalldのポートがずれているとFirewalldにsshの通信がブロックされてしまいます)。

Firewalldの起動
# systemctl start firewalld

Firewalldの起動の確認
# systemctl is-active firewalld

「active」と表示されればFirewalldは起動されています。またFirewalldがOS再起動時も自動起動されるように設定しておきます。

firewalldの自動起動の設定
# systemctl enable firewalld

6. デフォルトゾーンの設定

Firewalldのデフォルトゾーンを確認します。Firewalldにあらかじめ定義されているゾーンには、public、work、home、internal、external、dmzなどがあります。

Firewalldのデフォルトゾーンの確認
# firewall-cmd --get-default-zone

今回は公共の領域でのサーバー公開を想定しているため表示結果は「public」です。publicでない場合は以下のコマンドで変更します。

Firewalldのデフォルトゾーンの変更
# firewall-cmd --set-default-zone=public

「3.デバイスのゾーンの設定」でデバイスのゾーンがデフォルトになるように設定しましたが、ここでFirewalldのデフォルトゾーンをpublicにしたことにより、デバイスのゾーンは「public」として振る舞うようになります。

ゾーンの設定ファイルを確認してみます。設定ファイルは「/etc/firewalld/zones」配下にあります。publicの場合は「public.xml」となります。

ゾーンの設定ファイルの確認
# cat /etc/firewalld/zones/public.xml

デフォルト設定だと以下の2行が記載されています。
==========
<service name="dhcpv6-client"/>
<service name="ssh"/>
==========

これはpublicゾーンの場合、dhcpv6-clientとsshが公開されているサービスということです。コマンドでも公開されているサービスが確認できます。

公開されているサービスの確認
# firewall-cmd --list-service

7. 公開サービスの変更

sshが通れば今回のケースは問題ないのですが、dhcpv6-clientの通信はブロックし、HTTP通信を通す設定を書いておきます。

dhcpv6-clientの通信をブロック
# firewall-cmd --permanent --remove-service=dhcpv6-client

HTTP通信を許可
# firewall-cmd --permanent --add-service=http

HTTPS通信を許可
# firewall-cmd --permanent --add-service=https

永続設定の再読込み
# firewall-cmd --reload

再度、public.xmlを確認してみます。

ゾーンの設定ファイルの確認
# cat /etc/firewalld/zones/public.xml

「service name」の設定が以下のようになっていると思います。
==========
<service name="ssh"/>
<service name="http"/>
<service name="https"/>
==========

次回は、fail2banとの連携について書いてみようと思います。

※ここに記載したfirewalldやLinuxコマンドのsystemctl、nmcliについて詳しく知りたい方は以下の書籍が参考になります。CentOS7になってプロセス管理やネットワーク管理がCentOS6から変わっており、この書籍はプロセス管理のsystemd、ネットワークマネージャー、Firewalldに絞って書かれています。僕も読んで辞書みたいに使いながらこの記事の内容をやりました。