Firewalldにダイレクトルールを設定する。

CentOS7.4のFirewalldにダイレクトルールを設定してみます。以下の方法で設定できると思います。

まず、ダイレクトルールを設定するユーザー定義チェインを作成します。組み込みチェインに直接設定を追加することもできますが管理しやすくするためユーザー定義チェインを利用するほうが良いでしょう。ユーザー定義チェインは「INPUT_custom」という名前で作るとします。

ユーザー定義チェインの作成
# firewall-cmd --direct --add-chain ipv4 filter INPUT_custom

次に、ダイレクトルールをユーザー定義チェインに追加します。例として「SYNflood攻撃と思われる接続を破棄する」ルールの設定です。「-p tcp ! --syn -m state --state NEW -j DROP」の部分がこれに該当します。

ダイレクトルールの作成
# firewall-cmd --direct --add-rule ipv4 filter INPUT_custom 1 -p tcp ! --syn -m state --state NEW -j DROP

最後に、ダイレクトルールを設定したユーザー定義チェインの適用をします。適用先はINPUTチェインです。

ユーザー定義チェインの適用
# firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -j INPUT_custom

以上でFirewalldにダイレクトルールが設定できるはずです。「はずです」と書いているのは、これをまだ試していないからです。このようにやろうと思ったのですが以下の理由により別の方法にしました。

  • Firewalldが導入されているからかなのか、組み込まれているチェインがもともと多く、新たに追加する必要がない気がした。
  • fail2banが「INPUT_direct」のチェインに動的にダイレクトルールを優先度「0」で書き込んでいた。

参考:fail2banを導入したときの記事はこれです。

FirewalldがインストールされているCentOS7.4で「iptables -L」を実行してチェインの内容を確認すると、INPUT、FORWARD、OUTPUT以外にも以下のようなものがありました。

Chain INPUT
Chain FORWARD
Chain OUTPUT
Chain FORWARD_IN_ZONES
Chain FORWARD_IN_ZONES_SOURCE
Chain FORWARD_OUT_ZONES
Chain FORWARD_OUT_ZONES_SOURCE
Chain FORWARD_direct
Chain FWDI_public
Chain FWDI_public_allow
Chain FWDI_public_deny
Chain FWDI_public_log
Chain FWDO_public
Chain FWDO_public_allow
Chain FWDO_public_deny
Chain FWDO_public_log
Chain INPUT_ZONES
Chain INPUT_ZONES_SOURCE
Chain INPUT_direct
Chain IN_public
Chain IN_public_allow
Chain IN_public_deny
Chain IN_public_log
Chain OUTPUT_direct

何がどういう用途なのかはわからないのですが、fail2banを起動させたあとにFirewalldのダイレクトルールの確認、および、iptablesの確認をすると以下でした。

Firewalldのダイレクトルールを確認してみる。


# firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 0 -p tcp -m multiport --dports 50000 -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable

iptablesの確認をしてみる。


# iptables -L
 :
Chain INPUT_direct (1 references)
target     prot opt source               destination         
REJECT     tcp  --  anywhere             anywhere             multiport dports 50000 match-set fail2ban-sshd src reject-with icmp-port-unreachable
 :

[広告]

fail2banのダイレクトルールの設定と同じになるようにダイレクトルールは「INPUT_direct」チェインに設定することにします。fail2banのダイレクトルールの優先度は「0」だったので、ここで設定するダイレクトルールの優先度は「1」とします(fail2banのダイレクトルールの優先度のほうを高くしておく)。設定するダイレクトルールは以下です。

①データを持たないパケットの接続を破棄する。
②SYNflood攻撃と思われる接続を破棄する。
③ステルススキャンと思われる接続を破棄する。

※さくらのVPSのサポートページ(閉鎖されました)を参考にさせてもらいました。

①データを持たないパケットの接続を破棄する。
# firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 1 -p tcp --tcp-flags ALL NONE -j DROP

②SYNflood攻撃と思われる接続を破棄する。
# firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 1 -p tcp ! --syn -m state --state NEW -j DROP

③ステルススキャンと思われる接続を破棄する。
# firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 1 -p tcp --tcp-flags ALL ALL -j DROP

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

ダイレクトルールが設定されているか「/etc/firewalld/direct.xml」の中身を確認してみます。

direct.xmlの確認
# cd /etc/firewalld
# cat direct.xml

以下が設定内容です。


<?xml version="1.0" encoding="utf-8"?>
<direct>
  <rule priority="1" table="filter" ipv="ipv4" chain="INPUT_direct">-p tcp --tcp-flags ALL NONE -j DROP</rule>
  <rule priority="1" table="filter" ipv="ipv4" chain="INPUT_direct">-p tcp '!' --syn -m state --state NEW -j DROP</rule>
  <rule priority="1" table="filter" ipv="ipv4" chain="INPUT_direct">-p tcp --tcp-flags ALL ALL -j DROP</rule>
</direct>

また、iptablesの内容も確認してみます。


# iptables -L
 :
Chain INPUT_direct (1 references)
target     prot opt source               destination         
REJECT     tcp  --  anywhere             anywhere             multiport dports 50000 match-set fail2ban-sshd src reject-with icmp-port-unreachable
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP       tcp  --  anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG
 :

ダイレクトルールの設定が追加されています。これで、①〜③のような接続があった場合はFirewalldが遮断をしてくれると思います。

補足:
上記①〜③のパケットを実際に投入したわけではないのでこのルールが機能しているのかはまだ確認できていないのですが(汗)。

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: