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が遮断をしてくれると思います。
補足:
上記①〜③のパケットを実際に投入したわけではないのでこのルールが機能しているのかはまだ確認できていないのですが(汗)。